Alarm Manager Won't Work When the App Is Killed in the Background and Device Is Locked

Alarm Manager won't work when the app is killed in the background and device is locked

I just found the solution, set flag named FLAG_INCLUDE_STOPPED_PACKAGES to intent of the alarm, things will go right.
Here are the illustration in Android Developers

Alarm manager not working when device is locked for a while

For the unfortunate people who are looking for answers in this case, My code is perfectly fine and working. I just found out that "Greenify app" was killing/hibernating my app when device was going into sleep mode. Please check your task manager or other battery saving application while testing Alarm Manager functions.

Android Alarm Manager Not working when app is Killed

On some devices you will need to manually add your app to the list of apps allowed to run in the background. Otherwise, even with a "sticky" Service, Android will not restart the Service once the process has been killed. Manufacturers do this to save battery life.

In the settings, there should be a way to add your app to the list of "protected apps" or "apps allowed to run in the background". Look in the power management settings or the Apps settings.

Android alarms cancelled when application is killed

Quit functionality stops the service, releases the wake lock, and lets Android kill the process

If you are implying that you have a continuous WakeLock, unless this is only running on devices that are perpetually plugged in, your users will slap you with a trout.

Also, Android can kill the process whenever it wants. Do not mistake startForeground() as some sort of guarantee that Android will never kill your process.

But when it is killed from Task Manager is looks almost like alarm is getting cancelled.

I have no idea what "Task Manager" is, since there is none in Android. If you mean the list of running apps in Settings, and clicking Force Stop, then yes, that cancels any outstanding alarms and prevents your app from ever running again until something manually starts one of your components (e.g., user launches your app from the launcher).

Am I doing something wrong in regards to how to properly set the alarms?

Probably not. Force-stop definitely wipes out your alarms.

Alarm Manager or Work Manager for Recurring Background Work

For recurring background work, AlarmManger isn't suitable. As the name implies, it's intended to notify the system of an event at a precise time. Just like a physical alarm that wakes a person up even if the person sleeps, AlarmManager will wake up the device from doze mode which will result in more power usage. it is suitable for suitations like setting remainders such as for calender events which the users probably set by themselves.

On the other hand, WorkManager is intended to carry out background processing or work that would persist. Workmanager is much more efficient for recurring task especially as it allows you set constraints to determine when it should start or stop the background work.

check the link form the offical documentation on WorkManger:
workmanager architecture
tabular comparison between the two

AlarmManager not working in Android 8.1.0

You can use workmanager as mentioned in link.It supports all api version and easy to use because it uses backward compatibility to API level 14

https://developer.android.com/topic/libraries/architecture/workmanager

https://medium.com/androiddevelopers/introducing-workmanager-2083bcfc4712

How to restart service after the app is killed from recent tasks

Override onTaskRemoved() in your service and use alarm manager to start the service again. Below is code from our app that does the same and works fine:

@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);

Log.d(TAG, "TASK REMOVED");

PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
}

As you may want to send location periodically even in the case if the service gets killed on low memory (or for any reason), I suggest you to handle the uncaughtException to restart it after N seconds. This is how we have done in our app that works perfectly:

private Thread.UncaughtExceptionHandler defaultUEH;
private Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {

@Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.d(TAG, "Uncaught exception start!");
ex.printStackTrace();

//Same as done in onTaskRemoved()
PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
System.exit(2);
}
};

Note: I THINK and I remember I verified it on Kitkat that START_STICKY does not work on Kitkat and higher API levels. Please verify this for yourself.

MORE:

As you do loc sending periodically, you may have to consider the deep sleep mode. To get things work in deep sleep, use WakefulBroadcastReceiver combined with AlarmManager. Take a look at my other post How to use http in deep sleep mode.

UPDATE:

This solution does not work (in fact need not to work) if user "FORCE STOP" the application from Settings. This is good in fact as restarting the service is not a good way if user himself wants to stop application. So, it is fine.



Related Topics



Leave a reply



Submit