How can I set exact, repeating alarms in Android 4.4?
Asked Answered
R

1

16

Right now, I am setting alarms like this:

        AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

        timedate = cal.getTime();

        //convert date to milis
        long timeInMilis = (timedate.getTime());

        //Set Alarm to Repeat
        manager.setRepeating(AlarmManager.RTC_WAKEUP, timeInMilis, interval, pendingIntent);

Unfortunately, the scheduled times for repeating are inexact and I read that they could be inexact for a full interval!

So, I would like to switch over to seting an exact repeating alarm. My device requires a minimum only of the latest API 19/Android 4.4, so I can't use setRepeating.

What can I do instead to set an exact repeating alarm?

Roseliaroselin answered 16/11, 2014 at 16:52 Comment(1)
Read this post: #24299095Liquescent
C
30

Unfortunately, the scheduled times for repeating are inexact and I read that they could be inexact for a full interval!

If your targetSdkVersion is 19 or higher, yes.

What can I do instead to set an exact repeating alarm?

Use setExact() to get control for your initial delay. Then, as part of your work for processing that event, use setExact() to get control at your next desired time. IOW, you do the "repeating" part yourself.

Yes, this is irritating.

It is intentionally irritating, to steer developers to not use exact repeating alarms, as those are worse for the battery than are their inexact brethren. If the user will perceive the inexact behavior and will not appreciate it, feel free to use setExact() to make the alarms occur when the user wants. However, if the user will not perceive the inexact behavior, please use inexact alarms, as the user may notice the battery impact of your exact alarms.

Cholla answered 16/11, 2014 at 16:57 Comment(14)
I need to set an exact repeating alarm because that's the point of my application :( I wish I can use inexact. I guess my main question is I can use SetExact() above in my code but where should I schedule the alarm over again? In the broadcast receiver? how?Roseliaroselin
@KalaJ: "In the broadcast receiver?" -- given the code in your question, yes. "how?" -- by calling setExact() on AlarmManager in onReceive(), indicating when you want to get control again. Bear in mind that "exact" is a bit of a misnomer, as Android is not a real-time OS, and so you will get control near your initial time, not precisely at that time. Hence, you will want to call setExact() in your BroadcastReceiver to specify when you want control "for realz", not just by incrementing X time from now, or the cumulative drift over several alarm cycles may cause you some problems.Cholla
Okay but if i have several alarms that should be repeated exactly? I would just have to differentiate between them using a unique pending intent? and if so, then I would just say if this pending intent... then do this. If this pending intent, than do that?Roseliaroselin
@KalaJ: Well, yes, but you had to do that anyway. setExact() versus setRepeating() did not change the requirement that for each distinct alarm, you need a distinct PendingIntent.Cholla
Okay, thanks. I think I understand everything better now. Just one more question, if I put setExact() inside my broadcast receiver, can I still specify the interval/how often it repeats and does it repeat indefinitely after that like setRepeating? Do I need to do anything else that's special?Roseliaroselin
@KalaJ: "can I still specify the interval/how often it repeats" -- no. setExact() is like the old set(). It is a one-off event. That's why you have to call it on each event to set up the next event. "does it repeat indefinitely after that like setRepeating?" -- no. That's why you have to call it on each event to set up the next event. "Do I need to do anything else that's special?" -- you have to call it on each event to set up the next event.Cholla
@KalaJ: My PowerHungry sample app demonstrates using setExact() to emulate an exact repeating alarm, though I am not worrying about event time drift.Cholla
Awesome, thank you. I will take a look. What do you mean by "event time drift"? Thanks again.Roseliaroselin
@KalaJ: "What do you mean by "event time drift"?" -- you ask for an alarm to go off at 10:05:00.000. In reality, you get control at 10:05:01.234, because it took a bit to get your process forked and so on. Now, when you go to schedule the next event, the simple thing to do is schedule it based on "now, plus my polling period". Suppose your polling period is 5 minutes. You will wind up scheduling the next alarm for 10:10.01.234 or thereabouts, instead of 10:10:00.000. You need to take this into account and schedule your events based on the actual time you want them to occur.Cholla
If somehow an alarm is skipped(due to device power off) then what would happen(!!??). The pending alarm will be missed as well as the opportunity to set next days alarm. Isn't it? This is suicidal.Roobbie
@MostafaImran: No, it will be delayed until the device wakes up of its own accord (or until the next idle maintenance window, if the issue is that Doze mode blocked the alarm).Cholla
@Cholla suppose I set an alarm for today with setExact(). Your strategy suggests that when the alarm today will ring(In receiver) another alarm for tomorrow will be set. If a user shuts his device for whole day today. Then how would the alarm ring today and how would next day's alarm would be set. This scenario explains google's strategical fault on AlarmManager's new APIs.Roobbie
@MostafaImran: Then do not use setExact(). Use something else that fits your needs better: setExactAndAllowWhileIdle(), setAlarmClock(), GCM/FCM, etc. If you have additional concerns in this area, search for other answers, and if you do not find one, ask a fresh Stack Overflow question.Cholla
I am stuck in this situation bro. I need a daily alarm with precise timing. Currently I am following your your strategy :) but it's not that perfect as I explained why. On the other hand Marshmallow Doze mode has joined to ruin my life :(.Roobbie

© 2022 - 2024 — McMap. All rights reserved.