Android Alarm Manager setExactAndAllowWhileIdle() not working in Android 7.0 Nougat in Doze mode
Asked Answered
S

4

26

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:

  1. I set the alarm when I open my app.
  2. 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.
  3. I call completeWakefulIntent at the end of the onReceive().
  4. 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?!

Sasin answered 13/7, 2017 at 11:27 Comment(7)
It might helpRhonda
I am having the same issue, and seeing similar observations. I wish someone from Google can step up to the plate and fix this issue.Dimidiate
@Sasin Did you find solution for this, I have the same issue.Gnomic
@caucukien Still no solution....Sasin
@Sasin did you find any solution?Clericals
@ZohabAli I gave up on this issue. I searched hundreds of forums, tried lots of combination of solutions together, and ran testing for days. Yet, I found no way to fix this problem.Sasin
I guess you can find the answer hireDarrick
C
6

You might get accurate alarms, but in Doze mode

The system ignores wake locks.

So it seems as though AlarmManager.setAlarmClock is the only acceptable solution if you really need to trigger every 30 minutes. This will probably negate all doze mode energy savings...

BTW: it seems like you can see alarms with adb shell dumpsys alarm.


Possibility: use Firebase JobDispatcher

The Firebase JobDispatcher is a library for scheduling background jobs in your Android app. It provides a JobScheduler-compatible API that works on all recent versions of Android (API level 14+) that have Google Play services installed.

Cryotherapy answered 7/11, 2017 at 10:42 Comment(4)
Yeah i have been using the adb shell to set the device to doze and monitor the alarms, however through intensive testing there was an average of 49/50 accuracy with 1 dropped/delayed alarm..... I would cope with the alarm icon being visible all the time, but dropping an alarm is catastrophic. I don't know if people noticed such issue or was it just my device acting weird.Sasin
Have you considered using Firebase JobScheduler? It uses Google play and is considered to be on time.Cryotherapy
No, I didn't. But doesn't it build on top of JobScheduler which AlarmManager is part of it?Sasin
It implements the same interface. Somewhere it was said that it allowed users to accurately schedule alarms, as Google can block evil stuff. See github.com/firebase/firebase-jobdispatcher-android/issues/187.Cryotherapy
E
0

I got the same problem as you, and searches a long time for an solution. But I doesn't find a general solution.

A solution for Samsung devices is available: Android AlarmManager not working on some devices when the app is closed

The first answer works not, but the second one :)

Epigraphy answered 20/7, 2017 at 16:34 Comment(0)
T
0

Have you tried add your app to the battery optimisation whitelist? As some news pointed out (link), Huawei has some special battery management.

Toilworn answered 10/8, 2018 at 11:52 Comment(0)
M
0

In case you want to show a notification each time the timer fires, then you can use a backend server to send a data notification to Android users.

You need to save the FCM tokens of Android clients in your backend server, and the server will be responsible for pushing notifications to those clients.

I know It's a bit complicated for just only showing a notification, but that's who the Android system works!

Michaelemichaelina answered 25/1, 2021 at 6:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.