Search code examples
androidalarmmanagerandroid-pendingintent

Android AlarmManager PendingIntent is launched before call to alarm.set()


I've read about every similar question on here but cannot find an answer, so please forgive me if this has been answered before, I really tried to search.

I'm setting up an alarm to show a notification after a certain time. The time logic is definitely solid, I can tell by my log output, this is not the problem.

I create a Pending intent like so:

Intent alarmIntent = new Intent(c, AlarmReceiver.class);
alarmIntent.putExtra("title", name);
alarmIntent.putExtra("location", building);
PendingIntent pi = PendingIntent.getBroadcast(c, 0, alarmIntent, 0);

and then set the alarm to fire after millis milliseconds. In this instance, millis is 407603959 according to my log statements. It definitely should not be firing after one second.

alarm.set(AlarmManager.RTC_WAKEUP, millis, pi);
Log.i("Alarm", "Alarm: " + name + " is set for: "
        + untilAlarm.getDays() + " days, " + untilAlarm.getHours() + " hours, "
        + untilAlarm.getMinutes() + " minutes from now. Or, " + millis 
        + " milliseconds");

It appears as though my PendingIntent is being started before the alarm is even set. I tried blocking an alarm from being created like so:

Intent alarmIntent = new Intent(c, AlarmReceiver.class);
alarmIntent.putExtra("title", name);
alarmIntent.putExtra("location", building);
PendingIntent pi = PendingIntent.getBroadcast(c, 0, alarmIntent, 
        PendingIntent.FLAG_ONE_SHOT);

if (!name.equals("test") {
    alarm.set(AlarmManager.RTC_WAKEUP, millis, pi);
    //Log statement...
}

and the alarm for test is still triggered, but the log statement is not printed to the console, meaning alarm.set was never called. The intent is still fired, and a notification is shown with the title "test".

Why is my PendingIntent being launched before the alarm is fired?


Solution

  • You are using an alarm type of AlarmManager.RTC_WAKEUP, which will set the alarm to start at a specified time, in your case millis.

    To set the alarm to start at a certain amount of time in the future, you need to either use one of these types of elapsed-time alarms:

    • ELAPSED_REALTIME

    Alarm time in SystemClock.elapsedRealtime() (time since boot, including sleep). This alarm does not wake the device up; if it goes off while the device is asleep, it will not be delivered until the next time the device wakes up.

    • ELAPSED_REALTIME_WAKEUP

    Alarm time in SystemClock.elapsedRealtime() (time since boot, including sleep), which will wake up the device when it goes off.

    Or use an RTC or RTC_WAKEUP with the current time plus the time to wait, like:

    alarm.set(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + millis, pi);