Android AlarmManager not working on some devices when the app is closed

From the documentation of setRepeating():

As of API 19, all repeating alarms are inexact.

Moreover, setRepeating() does not work with Doze.

You should use exact alarms (set by the appropriate AlarmManager method based on the API level of the device):

if (Build.VERSION.SDK_INT >= 23) {
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
            triggerTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
    alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
} else {
    alarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}

And reschedule them every time they fire.

For the rescheduling you could add the original trigger time to the Intent:

intent.putExtra(KEY_TRIGGER_TIME, triggerTime);

Then retrieve this extra in onReceive(), add your desired interval to it and reschedule the alarm using the new value:

@Override
public void onReceive(Context context, Intent intent) {
    long triggerTime = intent
            .getLongExtra(KEY_TRIGGER_TIME, System.currentTimeMillis());

    // adding one day to the current trigger time
    triggerTime += TimeUnit.DAYS.toMillis(1);

    // set a new alarm using the new trigger time
    // ...
}

NOTE: As @Opiatefuchs mentioned in the comment above, some manufacturers (such as Xiaomi or Huawei) may implement certain battery saver functions that can prevent alarms from being fired and cannot be bypassed programmatically.

Leave a Comment