I am using AlarmManager to create alarms to be fired in exact moments through several days, but for some reason in a few devices it's not working after the first day.
The methods below are used to add daily alarms to the AlamManager, where one alarm is added to each day between start and end date:
public void setDailyALarm(GCMReminderModel reminder) {
Intent alarmIntent = manageAlarmIntent(reminder);
Calendar startDate = getStartDateValid(reminder);
Calendar endDate = getEndDateValid(reminder);
//Alarm start like a date start from gcm
Calendar alarm = (Calendar) startDate.clone();
do {
for(Hour hour : reminder.getHours()) {
String hourString = hour.getByDayOfWeek(alarm.get(Calendar.DAY_OF_WEEK));
if(hourString.isEmpty()) {
continue;
} else {
final String[] hourArray = hourString.split(":");
final int hourOfDay = Integer.parseInt(hourArray[0]);
final int minuteOfDay = Integer.parseInt(hourArray[1]);
alarm.set(Calendar.HOUR_OF_DAY, hourOfDay);
alarm.set(Calendar.MINUTE, minuteOfDay);
}
if ((getMidnightDate().before(alarm) && endDate.after(alarm)) &&
reminder.getSendDate().before(alarm.getTime())) {
LogHelper.logEvent("SCHEDULE ALARM");
scheduledAlarm(context, alarmIntent, alarm, reminder);
}
}
LogHelper.logEvent("ALARM AFTER - " + alarm.getTime().toString());
alarm.add(Calendar.DAY_OF_MONTH, 1);
//Percorre pela semana agendando os alarmes enquanto a data do alarme for menor que a data de fim
} while (endDate.after(alarm));
}
public void scheduledAlarm(Context context, Intent intent, Calendar alarmHour, GCMReminderModel reminder) {
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
long primaryKeyValue = 0;
if (realm.where(NotificationModel.class).findAll().size() > 0) {
primaryKeyValue = (realm.where(NotificationModel.class).max(Constants.NOTIFICATION_IDENTIFIER).longValue() + 1);
}
NotificationModel notification = realm.createObject(NotificationModel.class);
notification.setIdentifier(primaryKeyValue);
switch (reminder.getMessageType()) {
case Constants.MESSAGE:
notification.setIdMessage(reminder.getIdReminder());
break;
case Constants.QUESTION:
notification.setIdQuestion(reminder.getIdReminder());
break;
case Constants.QUESTIONLEVEL:
notification.setIdQuestionLevel(reminder.getIdReminder());
break;
case Constants.QUESTIONALTERNATIVE:
notification.setIdQuestionAlternative(reminder.getIdReminder());
break;
}
notification.setTimeMillis(alarmHour.getTimeInMillis());
notification.setIdType(reminder.getMessageType());
realm.commitTransaction();
intent.putExtra(Constants.NOTIFICATION_IDENTIFIER, notification.getIdentifier());
addNewAlarm(context, alarmHour.getTimeInMillis(), notification, intent);
LogHelper.logEvent("---------------------------------------------------------------------------------------------");
LogHelper.logEvent("ALARM SCHEDULED FOR : " + alarmHour.getTime() + " (NOW IS = " + new Date() + ")" + " - ID: " + notification.getIdentifier().intValue());
LogHelper.logEvent("---------------------------------------------------------------------------------------------");
}
public void addNewAlarm(Context context, long timeInMills, NotificationModel notification, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).
setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
timeInMills,
PendingIntent.getBroadcast(context,
notification.getIdentifier().intValue(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT)
);
LogHelper.logEvent("ENTROU NO SET_EXACT_AND_ALLOW_WHILE_IDLE");
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE))
.setExact(
AlarmManager.RTC_WAKEUP,
timeInMills,
PendingIntent.getBroadcast(context,
notification.getIdentifier().intValue(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT)
);
} else {
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE))
.set(AlarmManager.RTC_WAKEUP,
timeInMills,
PendingIntent.getBroadcast(context,
notification.getIdentifier().intValue(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT)
);
}
}
Checking the dump log, it's possible to see that the alarms were added to the AlarmManager
RTC_WAKEUP #3: Alarm{42043900 type 0 <package>}
type=0 when=+20h25m42s217ms repeatInterval=0 count=0
operation=PendingIntent{41b48800: PendingIntentRecord{420437a0 <package> broadcastIntent}}
In some devices, as the Moto G2 with Android 6.0, only the alarms set for the first day are called, while in other devices, like the Xiomi Redmi PRO also with Android 6.0, all alarms are correctly called. At first I though that it might be because of permissions, given the way the Android Marshmallow treats it, but in other devices with Android M is working (like the Redmi PRO).
Does anyone has an ideia of what can be causing this? I checked the Developers page and all the required configurations and classes are in order.