How to create a persistent AlarmManager
Whenever our application is killed, the AlarmManager is also killed.
AlarmManager
is not killed. Your alarm, however, is canceled. If the user force-stops or task-kills you, your alarms are unscheduled. On Android 3.1+, if the user force-stops you, nothing of your code will run again until the user manually launches one of your activities.
After talking to several of them, my suspicion is that our application is being killed manually via a task killer app or Android is itself is killing our app.
Ideally, your app should not be written in such a way that Android would have any cause to get rid of you. For something like what you describe, you should either using a getBroadcast()
PendingIntent
pointing to a manifest-registered BroadcastReceiver
, or you should be using a getService()
PendingIntent
pointing to an IntentService
. In either case, your code will run briefly, and then your process will be eligible for reclamation by Android without issue should the need arise.
Task killers, whether manual or automatic, seem a far more likely culprit of alarms being canceled, IMHO.
About the alarm manager in the Docs - the explanation is somewhat confusing and I honestly still don't get it fully. I have this bit of code for the widget part that solved the problem in my case.
package com.test.mytestwidget;
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
public class MyWidgetProvider extends AppWidgetProvider {
private PendingIntent service = null;
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
final Calendar TIME = Calendar.getInstance();
TIME.set(Calendar.MINUTE, 0);
TIME.set(Calendar.SECOND, 0);
TIME.set(Calendar.MILLISECOND, 0);
final Intent i = new Intent(context, UpdateWidgetService.class);
if (service == null)
{
service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
}
m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 30000, service);
}
@Override
public void onDisabled(Context context)
{
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
m.cancel(service);
super.onDisabled(context);
}
}