1

So I have been working on medication intake app, where I need to remind the user locally ( no internet/push notification needed) about taking their medication. I am using Android Alarm manager for this. Below is the code Note I am trying to schedule the alarm for a specific date: "13 July 2018 at 3h30 PM". I schedule and wait but the reminder didn't fire (so not broadcast) however if I used AlarmManager.ELAPSED_REALTIME_WAKEUP with a defined amount of millisecond it does fire ( but AlarmManager.RTC_WAKEUP just does not work) `

    AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    Intent myIntent;
    PendingIntent pendingIntent;
    long reminderDateTimeInMilliseconds = 000;

    myIntent = new Intent(this,MedicationScheduleBroadCastReceiver.class);

    pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,PendingIntent.FLAG_UPDATE_CURRENT);

    //TODO : Reminder the user to take medication on the 13th July 2018 at 15:30
    Calendar calendarToSchedule = Calendar.getInstance();

    calendarToSchedule.set(Calendar.YEAR, 2018);
    calendarToSchedule.set(Calendar.MONTH, 07);
    calendarToSchedule.set(Calendar.DAY_OF_MONTH, 13);
    calendarToSchedule.set(Calendar.HOUR_OF_DAY, 15);
    calendarToSchedule.set(Calendar.MINUTE, 30);

    reminderDateTimeInMilliseconds = calendarToSchedule.getTimeInMillis();

    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){

        manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, reminderDateTimeInMilliseconds, pendingIntent);
    }
    else{

        manager.set(AlarmManager.RTC_WAKEUP, reminderDateTimeInMilliseconds, pendingIntent);
    }

`

2 Answers2

6

So I figure out the issue, the main issue was the calendar month in Java is actually 0 index based so ( Jan:0 - Dec:11) so below is the updated code.

AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent myIntent;
PendingIntent pendingIntent;
long reminderDateTimeInMilliseconds = 000;

myIntent = new Intent(this,MedicationScheduleBroadCastReceiver.class);

pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,PendingIntent.FLAG_UPDATE_CURRENT);

//TODO : Reminder the user to take medication on the 13th July 2018 at 15:30
// Note: For the month of July the int value will actuall be 6 instead of 7
Calendar calendarToSchedule = Calendar.getInstance();
calendarToSchedule.setTimeInMillis(System.currentTimeMillis());
calendarToSchedule.clear();

//.Set(Year, Month, Day, Hour, Minutes, Seconds);
calendarToSchedule.set(2018, 06, 13, 15, 30, 0);


reminderDateTimeInMilliseconds = calendarToSchedule.getTimeInMillis();

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){

    manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, reminderDateTimeInMilliseconds, pendingIntent);
}
else{

    manager.set(AlarmManager.RTC_WAKEUP, reminderDateTimeInMilliseconds, pendingIntent);
}
0

Alarms are not fired if device is in Doze mode. Use setAndAllowWhileIdle or setExactAndAllowWhileIdle for alarms to be fired in Doze mode also.

From the Android Doc.

  • Network access is suspended.
  • The system ignores wake locks.
  • Standard AlarmManager alarms (including setExact() and setWindow()) are deferred to the next maintenance window. 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.
  • The system does not perform Wi-Fi scans.
  • The system does not allow sync adapters to run. The system does not allow JobScheduler to run.
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
  • But as you can see for all devices/emulator that have API level 26 and above I am actually using what you have mentioned "setExactAndAllowWhileIdle" and FYI I am testing on a device that have Android Oreo but still can't get it to fire – Jude Babs Babandakana Jul 13 '18 at 12:06
  • You can see work manager, i have switched to WorkManger from AlarmManager (due to unreliable behaviour) – Khemraj Sharma Jul 13 '18 at 12:10
  • but what I am trying to accomplish, it is apparently more appropriate to use AlarmManager to do it than workManager, see below link: https://stackoverflow.com/questions/50299814/how-to-schedule-notifications-using-workmanager – Jude Babs Babandakana Jul 13 '18 at 12:18
  • Yes thanks for correcting me, Your requirement needs Alarm Manager. – Khemraj Sharma Jul 13 '18 at 12:22
  • Let me test your case, I'll get back to you. – Khemraj Sharma Jul 13 '18 at 12:22
  • I think that you should be using setAlarmClock() because while setExactAndAllowWhileIdle() can fire during doze maintenance windows, it is still subject to delays...[setExactAndAllowWhileIdle is not exact](https://stackoverflow.com/questions/33110246/setexactandallowwhileidle-is-not-exact-as-of-developer-reference) – Elletlar Jul 13 '18 at 14:58
  • @Elletlar this did not help. – Jude Babs Babandakana Jul 24 '18 at 07:41
  • Can you tell a bit more? what is causing issue.? – Khemraj Sharma Jul 24 '18 at 07:43