Android Alarm Manager setExactAndAllowWhileIdle()在Doze模式下无法在Android 7.0 Nougat中运行

我试图使用Alarm Manager的setExactAndAllowWhileIdle每隔30分钟在我的应用程序中发出警报,但它无法正常工作!

每当我收到警报信号时,我都会通过发出推送通知来测试function。

问题是:当设备闲置一段时间后进入打盹模式时,我不再收到警报。 但是,只要我打开屏幕,我就会收到通知。 我的应用程序需要准确的警报,需要每30分钟准确按时交付! 由于设备处于打盹模式,它无法接收延迟警报或丢失警报!

我在我的代码中使用了以下内容:

  1. 我在打开应用程序时设置闹钟。
  2. 我使用WakefulBroadcastReceiver接收警报信号。 在其onReceive()方法中,我设置了下一个警报。 我也是,启动一个只发出推送通知的startWakefulService,然后自行停止。
  3. 我在onReceive()的末尾调用completeWakefulIntent。
  4. 我尝试了两种方法:RTC_WAKEUP和ELAPSED_REALTIME_WAKEUP

笔记:

  • wakefulbroadcastReceiver类在Manifest中注册。
  • 我添加了以下权限: android.permission.WAKE_LOCK
  • 我尝试了White-Listing我的应用程序,但结果是一样的
  • 我尝试使用setAlarmClock() ,即使在打盹模式下也一直工作,每50个警报就有一个丢弃/延迟警报。 所以,它也不完美。 而且我不希望用户一直看到警报图标。
  • 在打盹期间,setExactAndAllowWhileIdle()不仅不起作用,而且在工作时也具有可怕的准确性。 我通常会收到很多警报信号
    1-3分钟后或1-3分钟前。
  • 我正在使用华为Mate 8和android 7.0 Nougat进行测试。

PS:在回答之前,请确保您了解从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%不可靠?!

您可能会获得准确的警报,但处于打盹模式

系统忽略唤醒锁定。

因此,如果您确实需要每30分钟触发一次,似乎AlarmManager.setAlarmClock是唯一可接受的解决方案。 这可能会否定所有打盹模式的节能……

BTW:看起来你可以通过adb shell dumpsys alarm看到警报。

我遇到了和你一样的问题,并且长时间搜索解决方案。 但我找不到一般解决方案。

可以使用Samsung设备的解决方案: Android AlarmManager在关闭应用程序时无法在某些设备上运行

第一个答案不起作用,但第二个答案:)

您是否尝试将应用添加到电池优化白名单? 正如一些新闻指出的那样(华为),华为有一些特殊的电池管理方式。