Android 7.0 Nougat中的Doze模式下,Android Alarm Manager的setExactAndAllowWhileIdle()无法正常工作

25
我正在尝试使用Alarm Manager的setExactAndAllowWhileIdle每30分钟在我的应用程序中设置一个闹钟,但它不起作用!
我通过在接收到闹钟信号时发出推送通知来测试功能。
问题是:当设备长时间空闲后进入待机模式时,我不再收到闹钟。 但是,一旦我打开屏幕,我就会收到通知。 我的应用程序需要精确的闹钟,需要准确地按时每30分钟传递! 它不能承受因设备处于待机模式而接收到延迟的闹钟或丢失的闹钟!
我在代码中使用了以下内容:
1.打开应用程序时设置闹钟。 2.使用WakefulBroadcastReceiver接收闹钟信号。 在其onReceive()方法中,我设置下一个闹钟。 我还启动了一个startWakefulService,仅发出推送通知,然后停止自身。 3.在onReceive()的结尾调用completeWakefulIntent。 4.我尝试测试RTC_WAKEUP和ELAPSED_REALTIME_WAKEUP。
注:
  • 在清单文件中注册了wakefulbroadcastReceiver类。
  • 我添加了android.permission.WAKE_LOCK权限。
  • 我试图将我的应用程序加入白名单,但结果仍然相同。
  • 我尝试使用setAlarmClock(),它可以在doze模式下一直工作,但每50个闹钟会有一个被丢弃或延迟。因此,它也不是完美的解决方案。而且我不想让用户一直看到那里的闹钟图标。
  • 不仅setExactAndAllowWhileIdle()在doze模式下无法工作,而且当它在工作时精度也很差。通常我会收到许多1-3分钟后或1-3分钟早于预期的闹钟信号。
  • 我正在使用华为Mate 8和Android 7.0 Nougat进行测试。

P.S: 在回答之前,请确保您已了解Android 6.0 M及Doze模式所施加的限制。

Link1: https://developer.android.com/training/monitoring-device-state/doze-standby.html

总之,它的意思是:
  • 如果您需要在Doze模式下触发警报,请使用setAndAllowWhileIdle()或setExactAndAllowWhileIdle()。
  • 使用setAlarmClock()设置的警报会继续正常触发 - 系统会在这些警报触发前不久退出Doze模式。
现在,为什么我不能使用setExactAndAllowWhileIdle()每30分钟获得准确的警报信号?!并且,为什么setAlarmClock()不是100%可靠的?!

它可能会有所帮助。 - Nisarg
2
我遇到了同样的问题,并且看到了类似的观察结果。我希望有谷歌的工作人员能够站出来解决这个问题。 - d777
1
@Mena 你找到解决方案了吗?我也遇到了同样的问题。 - CauCuKien
@caucukien 仍然没有解决方案... - Mena
@Mena,你找到任何解决方案了吗? - Zohab Ali
显示剩余2条评论
4个回答

6

你可能会得到准确的警报,但在Doze模式下

系统会忽略唤醒锁。

因此,如果你真的需要每30分钟触发一次,请使用AlarmManager.setAlarmClock,这可能会抵消所有Doze模式的节能效果...

顺便说一句:你可以使用adb shell dumpsys alarm查看警报。


可能性:使用Firebase JobDispatcher Firebase JobDispatcher是一个用于在Android应用程序中调度后台作业的库。它提供了一个JobScheduler兼容的API,适用于所有安装有Google Play服务的最新版本的Android(API级别14+)。

是的,我一直在使用adb shell来设置设备进入待机模式并监控闹钟,但是经过大量测试,平均准确率为49/50,有1个闹钟会被丢失或延迟......我可以忍受闹钟图标一直可见,但是丢失一个闹钟是灾难性的。我不知道其他人是否也遇到了这样的问题,还是只有我的设备出现了异常。 - Mena
你是否考虑过使用Firebase JobScheduler? 它使用 Google Play 并被认为是准时的。 - serv-inc
不,我没有。但是它不是建立在JobScheduler之上的吗?而AlarmManager又是其中的一部分? - Mena
它实现了相同的接口。某处曾经说过,它允许用户精确地安排闹钟,因为Google可以阻止邪恶的东西。请参见 https://github.com/firebase/firebase-jobdispatcher-android/issues/187. - serv-inc

0

0

你尝试过将你的应用添加到电池优化白名单中吗?正如一些新闻所指出的那样(link),华为有一些特殊的电池管理。


0
如果您想在计时器触发时显示通知,则可以使用后端服务器向Android用户发送数据通知。
您需要在后端服务器中保存Android客户端的FCM令牌,服务器将负责向这些客户端推送通知。
我知道仅仅为了显示通知而进行这样的操作有点复杂,但这就是Android系统的工作方式!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接