I'm working on location tracking application using FusedLocationProvider. I have a background service which tracks location of phone in every 5 minutes.
All works well with it, but once the phone goes idle then after 3 to 4 hours of time, the background service stops to take location. When user unlocks the phone the tracking start again.
Can someone please guide me what could be causing the issue?
One possibility could be Android M Doze Mode. When the device is unplugged and stationary for a period of time, the system attempts to conserve battery by restricting apps access to CPU-intensive services. Doze mode starts after about 1h of inactivity, periodic tasks etc. are then scheduled to maintenance windows. When the user unlocks the device, doze mode is turned off again.
You find more information about Doze Mode in the developer docs:
http://developer.android.com/training/monitoring-device-state/doze-standby.html
Maybe your service is being stopped because the phone needs to free up memory so it kills your service. Make sure your service is set as a foreground service.
A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the "Ongoing" heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
http://developer.android.com/guide/components/services.html
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
Android will put your service to sleep after being idle for a while. You can use WakeLock to prevent that from happening.
public int onStartCommand (Intent intent, int flags, int startId)
{
PowerManager mgr = (PowerManager)getSystemService(Context.POWER_SERVICE);
mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
mWakeLock.acquire();
...
return START_STICKY;
}
public void onDestroy(){
...
mWakeLock.release();
}
Related
I have tried running a service in background. Have used Start_Sticky.
Basically this answer. It works in many devices fine but in some devices like Xiaomi Lenovo the service dies when app is removed from "recent app" screen. I have also tried deactivating power saver for particular apps and full system but that doesn't work either.
How do I make it work in those devices? I know its possible because some apps (like whatsapp) and games are able to send notification even when the app is not in "recent app" screen.
You can create the alarm with 1min in the onTaskRemoved() method in your service class. It will automatically invoke after the 1min and restarts the service.
In service class
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(), YourService.class);
restartService.setPackage(Yourpackagename);
PendingIntent restartServiceIntent = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealTime()+1000, restartServiceIntent);
}
I'm using a sticky android service by using code snippet in service class
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
But it restarts only when app get force closed by android o/s, Although when user force stop app from application manager, service also get terminated.
However, my requirement is that I want to keep running service forever till app is installed in device.
Could any one help me on this?
Going through long research and blogs recommendation, if user click force close application from application manger, then there is no way to restart again automatically.
Though, there can be work around to start stopped service by following broadcasts like - Usb detection, bluetooth status change, device restart etc. In these cases device send broadcast and if your app is capable to receive these notification, you can restart your service from context received in broadcast.
you can use Forground Service to make your service alive.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Notification notification=new Notification(R.drawable.icon,"The Service Is Running",System.currentTimeMillis());
Intent j=new Intent(this, Activity.class);
PendingIntent pi=PendingIntent.getActivity(this, 0,
j, 0);
notification.setLatestEventInfo(this, "Notification Message", "RunningService", pi);
notification.flags|=Notification.FLAG_NO_CLEAR;
startForeground(1, notification);
return START_STICKY;
}
Its not possible .But you can use foreground service . in low memory case android os can kill foreground service
I've set a repeating alarm that I only want going off when the device is awake. When it's asleep, I want it to stop (and come back on when the device wakes up). However, it's currently going off no matter what. Here's how I register my alarm:
Intent updateIntent = new Intent(UPDATE_INTENT);
AlarmManager alarmService = (AlarmManager) context.getSystemService(
Context.ALARM_SERVICE);
PendingIntent updatePendingIntent = PendingIntent.getBroadcast(context, 0,
updateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmService.setInexactRepeating(AlarmManager.RTC, Calendar.getInstance().getTimeInMillis(), UPDATE_INTERVAL, updatePendingIntent);
The alarm manager docs say that RTC will not wake up the device. The docs specify exactly the behavior that I want:
Alarm time in System.currentTimeMillis() (wall clock time in UTC). This alarm does not wake the device up; if it goes off while the device is asleep, it will not be delivered until the next time the device wakes up.
When I press the lock button on the device, I clearly see the going to sleep message from PowerManager in logcat:
I/PowerManagerService(488): Going to sleep by user request...
And then my alarm goes off anyway. What's going on here?
Ironically, every other question I've found on SO deals with alarms NOT going off while the device is asleep. I wish I had their problem!!
However, it's currently going off no matter what.
Presumably something else is holding a partial WakeLock, and the device is not actually asleep, even though the screen may be off. Use adb shell dumpsys power to try to track it down (look for the "Wake Locks" section).
I eventually decided to register broadcast receivers to listen for SCREEN_ON, and SCREEN_OFF, and toggle the alarm appropriately. I realize this might not be super elegant, but at least it always works even if another app is holding a wake lock.
Listening for screen on and off: android: broadcast receiver for screen on and screen off
Turning off an alarm: How to stop an alarm in android
I want to create application that can play a streaming music . When I press home my app can running in background but when I open another application that use more memory my app will stop and killed by android system . Anyone have another idea to run my music player app in background?
thank you
You have to implement a foreground service:
https://developer.android.com/guide/components/services.html#Foreground
A foreground service is a service that's considered to be something
the user is actively aware of and thus not a candidate for the system
to kill when low on memory. A foreground service must provide a
notification for the status bar, which is placed under the "Ongoing"
heading, which means that the notification cannot be dismissed unless
the service is either stopped or removed from the foreground.
Example:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
Look the activity lifecycle :)
http://developer.android.com/guide/topics/fundamentals/activities.html
I think you must do a service.
I have an app that uses text to speech to inform the user every 10 mins that 10 mins have passed. It currently works fine but if you sleep the phone (press the power button) it no longer plays the sound.
How can i play these sounds even when the phone is asleep?
In general, your code is not running if divice goes to sleep. In order to make your code running you need to acquire WakeLock from PowerManager. But in your case you don't need to have the WakeLock acquired all the time. You need to wake you application every 10 minutes. Otherwise your app will just eat battery doing nothing.
In order to wake your application periodically you need to use a special Android's AlarmManager.
Here is an example:
Intent myIntent = new Intent(getApplicationContext(), YourActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, interval, pendingIntent);
You also may send broadcast which you will process in your Service (if you don't want to use Activity).
EDIT: Playback will not start unless you explicitly create a SCREEN_DIM_WAKE_LOCK. Note that PARTIAL_WAKE_LOCK will not work with playback (don't now why, probably it's a bug).
PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "Music");
wakeLock.acquire();
...start playback...
wakeLock.release();
EDIT: Added project that shows an example of running a playback every 60 seconds (even when screen is off and usb cable is disconnected). It can be found here: http://code.google.com/p/playevery60/