I am trying to make an alarm fire in my app every 30 minutes using Alarm Manager's setExactAndAllowWhileIdle
but it is not working!
I test the functionality by issuing a push notification whenever I receive an alarm signal.
The problem is: when the device enters doze mode after being idle for sometime, I no longer receive alarms. However, as soon as I turn On the screen, I receive a notification. My app needs accurate alarms that need to be delivered exactly on-time every 30 minutes! It can not afford to receive delayed alarms or dropped ones because the device is in Doze mode!
I used the following in my code:
- I set the alarm when I open my app.
- I receive the alarm signal using a WakefulBroadcastReceiver. In its
onReceive()
method I set the next alarm. I also, start a startWakefulService that only issues a push notification, then stops itself. - I call completeWakefulIntent at the end of the onReceive().
- I tried testing both: RTC_WAKEUP & ELAPSED_REALTIME_WAKEUP
Notes:
- The wakefulbroadcastReceiver class is registered in the Manifest.
- I added permissions for :
android.permission.WAKE_LOCK
- I tried White-Listing my app, but the results are the same
- I tried using
setAlarmClock()
which worked all the time even during doze mode, with one dropped/delayed alarm every 50 alarms. So, it is also not perfect. And I don't want the user to see an alarm icon all the time up there. - Not only does setExactAndAllowWhileIdle() not work during doze, but also it
has terrible accuracy when it is working. I usually get lots of alarm signals
either 1-3 minutes later or 1-3 minutes earlier. - I am testing using Huawei Mate 8, and android 7.0 Nougat.
P.S: Before answering please make sure you are aware of the restrictions imposed starting Android 6.0 M and Doze mode.
Link1: https://developer.android.com/training/monitoring-device-state/doze-standby.html
In summary it says this:
- If you need to set alarms that fire while in Doze, use setAndAllowWhileIdle() or setExactAndAllowWhileIdle().
- Alarms set with setAlarmClock() continue to fire normally — the system exits Doze shortly before those alarms fire.
Now, why don't I get accurate alarm signals every 30 minutes using setExactAndAllowWhileIdle()
?!
And, why isn't setAlarmClock()
100% reliable?!