I have been successfully using the following construct to start an AlarmManager in some of my apps upto Android 5:
Intent serviceIntent = new Intent(context, MyService.class);
PendingIntent pi = PendingIntent.getService(context, alarmId, serviceIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
DateTime inMinutes = (new DateTime()).plusMinutes(60);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, inMinutes.getMillis(), pi);
But since Marshmallow, the AlarmManager is either not set or not firing any more after some idle time. It seems like the currently running alarm fires one more time, but then no new alarm will be set.
I read some documentation and it's most probably about Marshmallow Doze. So I implemented the following (and checked that it's actually being executed):
Intent serviceIntent = new Intent(context, MyService.class);
PendingIntent pi = PendingIntent.getService(context, alarmId, serviceIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
DateTime inMinutes = (new DateTime()).plusMinutes(minutes);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if(Build.VERSION.SDK_INT >= 23)
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, inMinutes.getMillis(), pi);
else {
if(Build.VERSION.SDK_INT >= 19) {
am.setExact(AlarmManager.RTC_WAKEUP, inMinutes.getMillis(), pi);
} else {
am.set(AlarmManager.RTC_WAKEUP, inMinutes.getMillis(), pi);
}
}
It doesn't change anything.
Is there a reliable way to set and fire alarms even on Marshmallow after some idle time?