4

My android app is running a repeating alarm, using setExactAndAllowWhileIdle on Marshmallow. The alarm occurs every 10s and avoids doze mode by using permission REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (device has agreed to ignore battery optimizations for this app)

 public void startAlarm(Intent alarmIntent, int delayMs, int alarmId) {
    PendingIntent recurringAlarm = PendingIntent.getBroadcast(context.getApplicationContext(), alarmId,
            alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Calendar updateTime = Calendar.getInstance();
    alarms.cancel(recurringAlarm);
    if (Build.VERSION.SDK_INT >= 23) {
        alarms.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis() + delayMs, recurringAlarm);
    } else if (Build.VERSION.SDK_INT >= 19) {
        alarms.setExact(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis() + delayMs, recurringAlarm);
    } else {
        alarms.set(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis() + delayMs, recurringAlarm);
    }
}

This alarm starts a service. The service then creates another alarm for 10s time using the same method (above). I presume that this alarm will occur every 10s because doze mode is ignored, but on rare occasions the alarm will be postponed for much longer:

  • 53 minutes 6 seconds
  • 18 minutes 40 seconds
  • 54 minutes 37 minutes 19 seconds
  • 1 day 48 minutes 30 seconds

What could be causing this strange behavior? This only seems to be occurring on a Samsung device.

Jonty800
  • 482
  • 7
  • 20
  • You're looking at the SDK of the phone. But according to the docs, the real determiner is the target SDK of your app. So if your target SDK is 23, this won't work right on phones that are pre-23. – Gabe Sechan Mar 17 '16 at 15:26
  • The device and target SDK are both 23 – Jonty800 Mar 17 '16 at 15:27

2 Answers2

3

The official doc states

To reduce abuse, there are restrictions on how frequently these alarms will go off for a particular application. Under normal system operation, it will not dispatch these alarms more than about every minute (at which point every such pending alarm is dispatched); when in low-power idle modes this duration may be significantly longer, such as 15 minutes.

I suspect Samsung has made modifications to make this duration even longer than 15 minutes. They are known for making deep reaching modifications, which cause unexpected behaviour more often than not.

F43nd1r
  • 7,690
  • 3
  • 24
  • 62
  • The alarms work every 10 seconds for a long period of time. Sometimes even days. It seems that there are rare occurrences where Samsung actually stops the alarm and destroys the service. This can happen after minutes, hours or days. I haven't been able to find any sort of pattern to this. I'm going to try and design a workaround, possibly by having another alarm which checks and then restarts the service if necessary. I don't feel optimistic. – Jonty800 Mar 27 '16 at 14:06
2

You can't set alarms this short on newer versions of Android, you should see this in the logs:

Suspiciously short interval 10000 millis; expanding to 60 seconds

If you need alarms shorter than 60 seconds, you need a different mechanism than the AlarmManager, like a Handler or HandlerThread.

Francesc
  • 25,014
  • 10
  • 66
  • 84
  • I thought that the new 60 seconds rule applied to setRepeating()? Using setExactAndAllowWhileIdle still works with alarms shorter than 60s. And they can be repeated by rescheduling a new alarm when the initial alarm is triggered. My methodology works fine on all devices except Samsung (so far) – Jonty800 Mar 17 '16 at 15:31
  • Samsung have also made their own changes, looks like they have a 5 min minimum for alarms. Try a different device; if it works, then you'll need to look at a different implementation to cover all devices. – Francesc Mar 17 '16 at 15:41
  • I know that Samsung had their own doze mode in 5.1, but was replaced with Android's version in 6.0. REQUEST_IGNORE_BATTERY_OPTIMIZATIONS works too, and the alarm fires every 10s. Its just rare that the alarm will fire with much larger delays - that's the issue. And I can't identify the cause, so I can't work on a workaround. – Jonty800 Mar 17 '16 at 15:49