5

我很难让我的收音机闹钟按预期工作,我在这里阅读了很多关于该主题的帖子,但不幸的是,没有一个对我有帮助。

AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);        
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent penInt = PendingIntent.getBroadcast(this, intentId, intent, 0);

这种区分我在 stackoverflow 上找到的 API 级别的方法并将其放在我的calcNextAlarm()函数中(加上一些用于调试的日志消息)以正确设置警报,无论设备上使用什么 API:

// problems in doze mode api 23+
if (Build.VERSION.SDK_INT >= 23) {
    if (testMode) Log.d("Ben", "setAlarmClock() - API 23+");
    am.setAlarmClock(new AlarmManager.AlarmClockInfo(alarmTimeInMillis, penInt), penInt);
}

else if (Build.VERSION.SDK_INT >= 19) {
// Wakes up the device in Idle Mode
    if (testMode) Log.d("Ben", "setExact() - API >= 19 && API < 23");
    am.setExact(AlarmManager.RTC_WAKEUP, alarmTimeInMillis, penInt);
}
// Old APIs
else {
    if (testMode) Log.d("Ben", "set() - API < 19");
    am.set(AlarmManager.RTC_WAKEUP, alarmTimeInMillis, penInt);
}

根据 Log.d 消息,我可以看到,在我的 Android 7.1 设备上,第一种方法setAlarmClock()正在执行以在接收器中设置警报。

经过 3 周的不成功测试和编码后,我变得非常绝望——我今天的闹钟再次迟到了 4 分钟——这永远不会发生,根据打瞌睡模式培训页面:

使用 setAlarmClock() 设置的警报继续正常触发——系统在这些警报触发前不久退出打盹。

在我的 7.1 手机上,当我将闹钟设置为“现在 +5 或 6”分钟时,闹钟甚至会晚 20 秒到 1:40 分钟。谁能告诉我如何真正及时完美地关闭警报?

4

2 回答 2

6

尝试使用:

setExactAndAllowWhileIdle()

这将确保警报按时触发。我已经在我自己的应用程序中对其进行了测试,它是可靠的。

如果您的目标 API 小于 23,请将其保留在 if 子句中,该子句检查设备中安装的当前 api。仅在 API 级别 23 以上使用,其余继续使用 setExact

可以回答您的评论:

1)我已经在打盹模式下准确地测试了它而没有插入电池

2)是的,不幸的是,空闲类型的警报每 9 分钟有一个警报限制。您在这里有两种选择:

首先使用 setExactAndAllowWhileIdle 触发第一个警报。

a) 对于贪睡,您必须使用 setAlarmClock 方法

b) 对于贪睡,您可以安排一个 JobScheduler 作业,并将最小延迟时间设置为您的贪睡时间。这将确保至少在贪睡间隔的间隙安排作业。但这会导致作业在间隔后随机安排,因此您还需要将覆盖期限设置为 0,以便在最小延迟后立即安排作业。还将网络要求保持为无,将需要的空闲模式保持为默认值或 false。根据我的经验,这也与警报精确方法一样可靠,我个人使用这种方法。

于 2017-12-28T14:22:51.597 回答
1

文件指出:

  • 如果您需要设置在打瞌睡时触发的警报,请使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。

  • 使用 setAlarmClock() 设置的警报继续正常触发——系统在这些警报触发前不久退出打盹。

在“使您的应用程序适应打瞌睡”部分中,它还说:

注意:对于每个应用,setAndAllowWhileIdle() 和 setExactAndAllowWhileIdle() 都不能每 9 分钟触发一次以上的警报。

setExactAndAllowWhileIdle的文档说:

与其他警报不同,系统可以自由地重新安排此类警报,使其与任何其他警报(即使来自同一个应用程序的警报)一起发生故障。这显然会在设备空闲时发生(因为此警报可能会在空闲时响起,此时来自应用程序的任何其他警报将一直保持到稍后),但即使在非空闲时也可能发生。请注意,操作系统将允许自己比常规精确警报更灵活地安排这些警报,因为应用程序已选择此行为。当设备空闲时,为了优化电池寿命,它可能需要更多的调度自由。

所以 setExactAndAllowWhileIdle 不能保证准确执行,而 setAlarmClock 更准确(根据文档)。

于 2020-02-16T05:47:36.423 回答