我需要每 10 分钟计划一次计划任务。
在 Lollipop 和更高版本中 setRepeating()
是不准确的,我使用 setExact()
并且(在触发警报时)我在 10 分钟内设置了新的精确警报。
private void setAlarm(long triggerTime, PendingIntent pendingIntent) {
int ALARM_TYPE = AlarmManager.ELAPSED_REALTIME_WAKEUP;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(ALARM_TYPE, triggerTime, pendingIntent);
} else {
alarmManager.set(ALARM_TYPE, triggerTime, pendingIntent);
}
}
triggerTime
计算 SystemClock.elapsedRealtime() + 600_000;
当警报响起时,我首先计划新的,然后才运行我的预定任务。
setAlarm();
mySheduledTask;
我的清单中确实有 WAKE_LOCK
权限。
当我在 Android 4 上测试它时 - 它运行完美(偏差可能是 12-15 毫秒)。
但是当我在小米红米 Note 3 Pro (5.1.1) 上运行应用程序时 - 偏差最多可达 15 秒!
例如,我在我的日志文件中看到:第一次运行是在 1467119934477(RTC 时间),第二次运行是在 1467120541683。差异是 607_206 毫秒,而不是计划的 600_000 !
我错过了什么? 什么是模拟系统警报行为的方法(这是可以描述我的策略的最接近的用例)?
附言。 我将 IntentService 用于 PendingIntent = PendingIntent.getService(context, 0, myIntent, 0);
原文由 Goltsev Eugene 发布,翻译遵循 CC BY-SA 4.0 许可协议
操作系统会根据您指定的时间来选择警报的工作方式。因此,当手机进入“半睡眠”模式时,它不必在您希望的时间使用资源。基本上,它等待操作系统为它打开的“窗口”,然后您要运行的警报才会运行,这就是您遇到时间间隔的原因。
这是在 Marshmallow OS 上引入的,并将在 Nougat OS 上继续,作为谷歌试图改进设备电池的一部分。
事情是这样的,你有两个选择:
JobScheduler
更推荐,可以节省电池电量)。setExactAndAllowWhileIdle
这可能会导致你的电池问题(小心使用,太多的警报会对你的电池不利)。此方法不重复,因此您必须声明要在 pendingIntent 打开的服务上运行的下一个作业。如果您选择选项 2,那么这里是开始: