如何创建持久的AlarmManager

编辑:根据CommonsWare的答案澄清问题

我们通过AlarmManager安排一个警报,每60秒触发一次。 当我们的应用程序被杀死时,我们的警报似乎不再执行。 即使应用程序被手动或系统杀死,有没有办法使这些警报持续存在?

这对我们来说是个问题,因为我们有一个显示时间的小部件应用程序。 这意味着我们需要每分钟更新一次。 为了解决AppWidgetProvider的onUpdate方法的30分钟更新限制,我们使用AlarmManager。 它通常运行良好,但有些用户报告时间不同步。 在与其中几个人交谈之后,我怀疑我们的应用程序是通过任务杀手应用程序手动杀死的,或者Android本身正在杀死我们的应用程序。

对根问题的任何其他替代解决方案(保持小部件中的时间同步)也是受欢迎的。

以下是我们执行的用于安排警报的代码:

Intent intent = new Intent(UPDATE_TIME); PendingIntent pIntent = PendingIntent.getBroadcast(ctx, 0 /* no requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT ); // get alarm params Date d = new Date(); long timeTilMinuteChange = 60*1000-d.getSeconds()*1000; long startTime = System.currentTimeMillis() + + timeTilMinuteChange; AlarmManager am = (AlarmManager) ctx.getSystemService(Context. am.cancel(pIntent); am.set(AlarmManager.RTC, System.currentTimeMillis(), pIntent); am.setRepeating(AlarmManager.RTC, startTime, 60000, pIntent); 

每当我们的应用程序被杀死时,AlarmManager也会被杀死。

AlarmManager没有被杀死。 但是,您的警报会被取消。 如果用户强制停止或任务杀死您,则您的警报将不计划。 在Android 3.1+上,如果用户强行停止,则在用户手动启动您的某项活动之前,您的代码不会再次运行。

在与其中几个人交谈之后,我怀疑我们的应用程序是通过任务杀手应用程序手动杀死的,或者Android本身正在杀死我们的应用程序。

理想情况下,您的应用程序不应该以Android有任何理由摆脱您的方式编写。 对于你所描述的内容,你应该使用指向清单注册的BroadcastReceivergetBroadcast() PendingIntent ,或者你应该使用指向IntentServicegetService() PendingIntent 。 在任何一种情况下,您的代码都会短暂运行,然后您的流程就有资格在没有问题的情况下由Android进行回收。

恕我直言,任务杀手,无论是手动还是自动,似乎更有可能被取消警报。

关于文档中的报警管理器 – 解释有点令人困惑,老实说,我还是没有完全理解。 我有一些小部件的代码,解决了我的问题。

 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); } }