Nicholas Muir Nicholas Muir - 2 months ago 10
Android Question

Alarm being called instantaneously when time set to 0:00

I am making an alarm that activates like any other alarm on the hour and minute that the user selects. I found a problem when the time is set at 0:00 the alarm activates immediately.

I have a custom

AlarmManager
in which I call schedule repeating like this:

CustomAlarmManager alarmManager = new CustomAlarmManager(getActivity());
alarmManager.scheduleRepeatingAlarm(getActivity(),
alarmID, alarmHour, alarmMinute);


And for the problematic example these values are being passed:

Id = 619
Hour = 0
Minute = 0


This is the
setRepeatingAlarm()
function:

public void scheduleRepeatingAlarm(Context context, int alarmID, int hour, int minute) {
System.out.println("schedule is running");
Intent intent = new Intent(context, AlarmNotificationReciever.class);
Bundle extras = new Bundle();
extras.putBoolean(KEY_REPEAT, true);
extras.putInt("AlarmId", alarmID);
intent.putExtras(extras);
PendingIntent pIntent = PendingIntent.getBroadcast(context,
alarmID, intent, PendingIntent.FLAG_CANCEL_CURRENT);

Calendar calender = Calendar.getInstance();
calender.set(Calendar.HOUR_OF_DAY, hour);
calender.set(Calendar.MINUTE, minute);

if (android.os.Build.VERSION.SDK_INT >= 19) {
setSingleExactAlarm(calender.getTimeInMillis(), pIntent);
} else {
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calender.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pIntent);

}
}


I am assuming the problem is going to be with these lines here:

Calendar calender = Calendar.getInstance();
calender.set(Calendar.HOUR_OF_DAY, hour);
calender.set(Calendar.MINUTE, minute);


And this line when setting the alarm:

setSingleExactAlarm(calender.getTimeInMillis(), pIntent);


For ever other hour and minute combination it seems to work and treat it as a time to go off. But for hour = 0 and minute = 0 it just fires straight away.

Thanks in advance for your help.

Answer

This is the expected behaviour.

Calendar.getInstance() returns a Calendar instance set to the current date/time.

Leaving the date untouched and setting the hour and minute to 0 effectively sets the alarm in the past (it is considered a missed alarm).

From the documentation of setRepeating():

If the stated trigger time is in the past, the alarm will be triggered immediately, with an alarm count depending on how far in the past the trigger time is relative to the repeat interval.

You could do something like this to perform a check:

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);

Calendar now = Calendar.getInstance();

if(calendar.before(now)) {
    // handle this as you wish

    // adding a day to calendar
    calendar.add(Calendar.DATE, 1);
}