注意:从API 19(KITKAT)开始报警传递不准确... 有新的API支持需要严格交付的应用程序 担保;请参阅... setExact(int,long,PendingIntent)。
因此,如果我需要精确重复警报 - 需要使用setExact
- 设置一次警报。所以我有:
public static void setAlarm(Context context) {
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarm.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + ALARM_INTERVAL, pendingIntent);
}
public static void cancelAlarm(Context context) {
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyService.class);
PendingIntent sender = PendingIntent.getService(context, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarm.cancel(sender);
}
通话顺序为:
用户通过活动启用闹钟,因此活动会调用setAlarm(getApplicationContext())
。
导致某些服务在后台运行的警报 - 这是警报的目的:在后台以准确的时间间隔运行此服务。
在服务的onDestroy()
内,我呼叫setAlarm(getApplicationContext())
,这样我就可以在准确的时间内重复闹钟。所以最后我重复的不是每个间隔,而是服务的间隔+执行时间,直到onDestroy
被调用。
用户可以通过调用cancelAlarm(getApplicationContext())
从某些活动取消闹钟。通过这种方式,警报的重复效果被取消:服务将不会被执行,具体而言,不会执行调用设置新警报的onDestroy()
方法,因此链将结束。
更新:运行时adb shell dumpsys alarm
的结果是:
RTC_WAKEUP #0: Alarm{... type 0 when ... code.dev}
tag=*walarm*:code.dev/.MyService
operation=PendingIntent{...: PendingIntentRecord{... code.dev startService}}
...:code.dev +17ms running, 3 wakeups:
*walarm*:code.dev/.MyService
取消后:
...:code.dev +359ms running, 14 wakeups:
*walarm*:code.dev/.MyService
问题:服务会定期唤醒,这意味着警报未被取消。