13

I have a BroadcastReceiver which reschedules alarms on events such as booting and time change. But when the time is past the trigger time of the alarm (For example, when the user manually changes the time from the settings), AlarmManager fires the alarm immediately before I can add a day to reschedule my alarm. How can I avoid this?

I'm currently using the set and add methods of the Calendar to schedule the alarms.

        for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; dayOfWeek++) {
            if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek >= nowDay &&
                    !(dayOfWeek == nowDay && alarm.timeHour < nowHour) &&
                    !(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) {

                calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                alarmSet = true;
                break;
            }
        }

        if (!alarmSet) {
            for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; dayOfWeek++) {
                if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek <= nowDay) {
                    calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                    calendar.add(Calendar.WEEK_OF_YEAR, 1);
                    break;
                }
            }
        }

It is also stated in the docs:

If the stated trigger time is in the past, the alarm will be triggered immediately.

How can this behaviour be altered?

Piyush
  • 1,744
  • 1
  • 15
  • 28

3 Answers3

6

This is intended. See e.g. Set a Repeating Alarm

A trigger time. If the trigger time you specify is in the past, the alarm triggers immediately.

or the same here

If the stated trigger time is in the past, the alarm will be triggered immediately.

To avoid this you will have to either manually check your alarms before adding them,

if(alarmTimeStamp < System.currentTimeMillis()) {
    // if is repeating schedule in __interval__
    // else ignore
}

or ignore them in your receiver if the date is in the past.

David Medenjak
  • 33,993
  • 14
  • 106
  • 134
  • I know, I have read the docs. But I explicitly want a way to stop this from happening. – Piyush Jan 06 '16 at 22:47
  • @PiyushShrivastava just updated the answer. You will have to do date checkings yourself, since there is no general solution. – David Medenjak Jan 06 '16 at 22:51
  • I've implemented date checking. But the problem is that the alarm manager triggers the alarm before my receiver even gets called. How do I get the receiver to be called before that? – Piyush Jan 07 '16 at 10:07
  • @PiyushShrivastava you will have to do your date checking before adding the alarm, and not just in the receiver – David Medenjak Jan 07 '16 at 10:11
  • I'm checking the date before adding an alarm. This is reflected in the code I posted above. This problem only occurs when user manually changes time or date. – Piyush Jan 07 '16 at 14:34
0

As David stated, pre-check the alarm date/time before using it; if it's in the past, then add a second or minute or whatever before feeding it to the AlarmManager.

If a user is entering the date/time, then pre-check the input in the same way.

zerobandwidth
  • 1,213
  • 11
  • 18
  • Pre-checking the input is only possible if the user changes the alarm time. Not if the time is changed from the settings. – Piyush Feb 22 '16 at 12:32
0

How about creating a BroadcastReceiver for listening to time change.

In Manifest file,

 <receiver android:name=".MyReceiver">
            <intent-filter >
                <action android:name="android.intent.action.TIME_SET"/>
            </intent-filter>
 </receiver>

and your BroadcastReceiver file

public class MyReceiver extends BroadcastReceiver{

    @Override 
    public void onReceive(final Context context, Intent intent) {
        Log.d("MyReceiver", "Time Changed");
        // The times have changed; so have their signs.
        updateYourAlarm();
    } 
}
Atif Farrukh
  • 2,219
  • 2
  • 25
  • 47
  • I already have TIME_SET and DATE_CHANGED actions added in the manifest. The problem still persists. – Piyush Feb 22 '16 at 12:40
  • BroadcastReceiver onReceive called mutiple times when changing the date or time manually, in manifest i use this two as intent filters TIME_SET and DATE_CHANGED – Sarath Kumar Aug 04 '17 at 13:02