AlarmManager firing alarm past the time it was set on the same day, setRepeating
Asked Answered
G

3

7

So basically I have this code, time returns 24hour time and repeats the alarm daily.

public setAlarm(String time, Context context){
    String[] strTime;

    strTime = time.split(":");

    int hour, min, sec;
    //set when to alarm
    hour = Integer.valueOf(strTime[0]);
    min = Integer.valueOf(strTime[1]);
    sec = 0;

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, hour);
    cal.set(Calendar.MINUTE, min);
    cal.set(Calendar.SECOND, sec);
    //Create a new PendingIntent and add it to the AlarmManager
    Intent intent = new Intent(context, AlarmReceiverActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 19248, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
    am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}

Anyways, the problem is when I set the alarm 9am while the time is 9:10am, the alarm will go off. Why? I want it not to alarm if it is set past the system time. Ex. set the alarm at 9am while the system time is 9:10am

Germanophobe answered 15/7, 2013 at 3:14 Comment(0)
G
21

I got it working now. I added a checker of the alarm time and current time.

public setAlarm(String time, Context context){
        String[] strTime;

        strTime = time.split(":");

        int hour, min, sec;
        //set when to alarm
        hour = Integer.valueOf(strTime[0]);
        min = Integer.valueOf(strTime[1]);
        sec = 0;

        long _alarm = 0;
        Calendar now = Calendar.getInstance();
        Calendar alarm = Calendar.getInstance();
        alarm.set(Calendar.HOUR_OF_DAY, hour);
        alarm.set(Calendar.MINUTE, min);
        alarm.set(Calendar.SECOND, sec);

        if(alarm.getTimeInMillis() <= now.getTimeInMillis())
            _alarm = alarm.getTimeInMillis() + (AlarmManager.INTERVAL_DAY+1);
        else
            _alarm = alarm.getTimeInMillis();               

        //Create a new PendingIntent and add it to the AlarmManager
        Intent intent = new Intent(context, AlarmReceiverActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 19248, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
        am.setRepeating(AlarmManager.RTC_WAKEUP, _alarm, AlarmManager.INTERVAL_DAY, pendingIntent);
    }
Germanophobe answered 16/7, 2013 at 18:17 Comment(2)
AlarmManager.INTERVAL_DAY+1 - Why do you add +1?Tiphanie
Because "If an alarm is delayed (by system sleep, for example, for non _WAKEUP alarm types), a skipped repeat will be delivered as soon as possible. After that, future alarms will be delivered according to the original schedule; they do not drift over time. For example, if you have set a recurring alarm for the top of every hour but the phone was asleep from 7:45 until 8:45, an alarm will be sent as soon as the phone awakens, then the next alarm will be sent at 9:00. " So, the alarm will fire up if you set it on the same dayVirgievirgil
F
3

The accepted answer is wrong as I tried it and then figured out the solution.

It is wrong because, as you can see here: Calendar now = Calendar.getInstance(); Calendar alarm = Calendar.getInstance(); alarm.set(Calendar.HOUR_OF_DAY, hour); alarm.set(Calendar.MINUTE, min); alarm.set(Calendar.SECOND, sec);

"Calendar now" and "Calendar alarm" will always be the same no matter what because they are doing the same thing almost at the exact same spot in the code so the Calendar.getInstance() wil always be the same.

The solution is this

    long _alarm;
    Calendar now = Calendar.getInstance();
    long oldtimer = now.getTimeInMillis();

    cal.set(Calendar.HOUR_OF_DAY, Hours2int);
    cal.set(Calendar.MINUTE, minutes2int);
    cal.set(Calendar.SECOND, cur_cal.get(Calendar.SECOND));
    cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
    cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
    cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));

    //Calendar alarm = Calendar.getInstance();

    long newtimer = cal.getTimeInMillis();


    if(newtimer < oldtimer) {
        //do the thing
    }
Fiasco answered 16/5, 2015 at 4:44 Comment(1)
Or even simpler: if (cal.getTimeInMillis() < System.currentTimeMillis()) { cal.add(Calendar.DATE, 1); }Loxodromic
D
0

Use setInexactRepeating instead of setRepeating

    Calendar cal= Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, 9);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    PendingIntent pi = PendingIntent.getService(context, 0,
        new Intent(context, MyClass.class),PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
   am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                            AlarmManager.INTERVAL_DAY, pi);
Davie answered 15/7, 2013 at 4:24 Comment(4)
When u want to fire alarm exactly developer AndroidDavie
Still having the same problem.. Intent intent = new Intent(context, AlarmReceiverActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 19248, intent, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE); am.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);Germanophobe
Okay. Let me tell you the example again. I want my device to alarm every 9am. If the system time is already 9:10am, and I will set the alarm 9am. Right after setting it, the alarm will go off. This instance occurs using .setReapeting. How can I prevent it from alarming if it was set past the system time?Germanophobe
my next comment would have been that only to add the check :) glad it finally worked :)Davie

© 2022 - 2024 — McMap. All rights reserved.