What happens to undelivered AlarmManager repeating alarms when phone wakes up? - android

If we schedule an inexact repeating alarm with AlarmManager.setInexactRepeating to be fired every hour, for example, what happens if the phone is in standby for 4 hours and then it is woken up? Does the system deliver 4 alarms in a row for the same PendingIntent or does it deliver only a single alarm?
EDIT: reading the documentation with more attention, the set(int, long, android.app.PendingIntent) method documentation says: Alarm intents are delivered with a data extra of type int called Intent.EXTRA_ALARM_COUNT that indicates how many past alarm events have been accumulated into this intent broadcast. Recurring alarms that have gone undelivered because the phone was asleep may have a count greater than one when delivered.
So, when the phone comes out of standby, only one alarm will be delivered, with an intent extra that contains the number of missed alarms.

Reading the documentation with more attention, the set(int, long, android.app.PendingIntent) method documentation says: Alarm intents are delivered with a data extra of type int called Intent.EXTRA_ALARM_COUNT that indicates how many past alarm events have been accumulated into this intent broadcast. Recurring alarms that have gone undelivered because the phone was asleep may have a count greater than one when delivered.
So, when the phone comes out of standby, only one alarm will be delivered, with an intent extra that contains the number of missed alarms.

it depends if you use
pending intent like this
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
it wont trigger 4 times as it cancells the previous pending intent

Related

Android: AlarmManager - Repeating Date set to past - Will future alarms trigger?

If I set the "triggerAtMillis" of the method
setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
to a past date, will the future alarms trigger?
It all depends on the type you specify
Here is the list of types:
ELAPSED_REALTIME — Fires the pending intent based on the amount of time
since the device was booted, but doesn't wake up the device.
The elapsed time includes any time during which the device was asleep.
ELAPSED_REALTIME_WAKEUP — Wakes up the device and fires the pending
intent after the specified length of time has elapsed since device boot.
RTC — Fires the pending intent at the specified time but does not wake up
the device.
RTC_WAKEUP — Wakes up the device to fire the pending intent at the
specified time.
So the answer would be yes it'll take that much time interval and according the the type repeat itself in the future.
Check the documentation for more

Android Alarm manager working, but delayed

I would like to make a delay(10 min) for user then after it, user can edit something.
to do this,I created a setAlarm function :
public void setAlarm(Context context,int user,int time) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, sef_time.class);
intent.putExtra(ONE_TIME, Boolean.FALSE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.set(AlarmManager.RTC, 1000*60*time , pi);
}
everything works fine, but my alarm manager has a delay.
for example:
setAlarm(.....,int 10);
It has a delay : 00:10:03 second or 00:10:10 second 00:10:20 second !
where is my wrong ?
As you can see here:
Beginning in API 19, the trigger time passed to this method is treated
as inexact: the alarm will not be delivered before this time, but may
be deferred and delivered some time later. The OS will use this policy
in order to "batch" alarms together across the entire system,
minimizing the number of times the device needs to "wake up" and
minimizing battery use. In general, alarms scheduled in the near
future will not be deferred as long as alarms scheduled far in the
future.
With the new batching policy, delivery ordering guarantees are not as
strong as they were previously. If the application sets multiple
alarms, it is possible that these alarms' actual delivery ordering may
not match the order of their requested delivery times. If your
application has strong ordering requirements there are other APIs that
you can use to get the necessary behavior; see setWindow(int, long,
long, PendingIntent) and setExact(int, long, PendingIntent).
Applications whose targetSdkVersion is before API 19 will continue to
get the previous alarm behavior: all of their scheduled alarms will be
treated as exact.
If it's very important that the alarm be exact, use setExact (When the device's SDK is 19 or above).
The easiest way to make system have a delay and then sound an alarm at the exact specified time is using setExact(), and the code can be something like this.
am.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + (time_you_want_to_delay_in_milliseconds) ,pi);

Android: correct way to use AlarmManager without draining battery

I need to do a background check in my app, basically polling various URLs for new stuff. So I've read this is done with the AlarmManager.
The thing is, I don't need the user to be notified as soon as new stuff arrives. Let's say I'm checking every hour, I'm perfectly fine with not doing any check while the phone is sleeping, and resuming the checks when the phone is used. That way the user eventually gets the notification, but the drain is minimal.
So I've tried with setInExactRepeating. I'm starting it at boot time, but also at app startup (mostly for the session after install, and to make sure it's running even if the app gets "force killed"). How do I prevent all these checks to add up? (A new check should only be run if none is running, or the previous one needs to be stopped).
I've found setInexact Repeating coupled with ELAPSED_REALTIME (or RTC) works quite well to achieve very minimal battery drain. Using the flag FLAG_UPDATE_CURRENT on an existing pendingintent (same intent and id) will simply refresh the current alarm schedule if it already exists. Alternatively, add the code suggested by Ralgha to check and see if you already created the pending intent and set the alarm, and then if not, set the pending intent and alarm schedule. Both methods will likely have the same impact on battery (negligible). What will cause significant drain is doing something on a frequent schedule. The fact that you only want to update every hour and not when the screen is off, your app will use barely any battery (assuming it is done with it's processing relatively quickly and cleans up after itself nicely)
http://developer.android.com/reference/android/app/AlarmManager.html#ELAPSED_REALTIME
ELAPSED_REALTIME
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.
http://developer.android.com/reference/android/app/AlarmManager.html#setInexactRepeating%28int,%20long,%20long,%20android.app.PendingIntent%29
setInexactRepeating
These alarms are more power-efficient than the strict recurrences supplied by setRepeating(int, long, long, PendingIntent), since the system can adjust alarms' phase to cause them to fire simultaneously, avoiding waking the device from sleep more than necessary.
http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_UPDATE_CURRENT
FLAG_UPDATE_CURRENT
...if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.
You can check to see if the alarm is already set before you set it, and you can also use a flag so the alarm won't be delivered until the device is awake.
if ( PendingIntent.getBroadcast( context, 0, updateIntent, PendingIntent.FLAG_NO_CREATE ) == null )
{
pendingIntent = PendingIntent.getBroadcast( context, 0, updateIntent, 0 );
getSystemService( ALARM_SERVICE ).setInexactRepeating( AlarmManager.RTC, System.currentTimeMillis(), AlarmManager.INTERVAL_HOUR, pendingIntent );
}

Alarm Manager Accuracy

How to use alarm manager at accurate time interval?
I used alarm manager but it response inaccurate.
Can anyone help me?
I used this code
PendingIntent sender;
AlarmManager am;
long firstTime;
Intent itnt = new Intent();
itnt.setAction("abts.medismo.medismo.ALARMRECEIVER");
sender = PendingIntent.getBroadcast(context, 0,itnt, 0);
am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(sender);
firstTime = SystemClock.elapsedRealtime();
am.setInExactRepeating(AlarmManager.ELAPSED_REALTIME,firstTime, Integer.parseInt(sep[3]), sender);
You should use ELAPSED_REALTIME_WAKEUP, because if the phone is asleep it wont fire until it wakes up again.
There are two issues here.
The first, as others have pointed out, is that your alarms are not "wakeup" alarms. This means that if the device is asleep when the trigger time is reached, the alarm will not cause the device to wake up and process the alarm immediately. Instead, it will be processed as soon as something else causes the device to become active, such as the user picking it up and pushing the power button to start using it.
The second issue is that you are using setInexactRepeating(). As the name implies, these alarms are never going to be delivered at precisely predictable times. As the documentation says, "In addition, while the overall period of the repeating alarm will be as requested, the time between any two successive firings of the alarm may vary."
This is often enough for most apps, and it is more efficient in terms of battery use. However, if you truly need the alarm to be delivered at a specific time, you need to set the alarm time yourself instead of relying on periodic alarms. In addition, as of API version 19, you should use the new setExact() APIs if you truly need precise delivery.
I believe your observed inaccuracy may be caused by the subtle variation of flags for the alarms.
AlarmManager.ELAPSED_REALTIME and AlarmManager.ELAPSED_REALTIME_WAKEUP utilize elapsedRealtime(), which is the number of milliseconds since the device last booted up, good for measuring elapsed time for timers and the like.
AlarmManager.RTC and AlarmManager.RTC_WAKEUP utilize currentTimeMillis(), which is the system clock:
time in milliseconds since January 1, 1970 00:00:00 UTC. This method shouldn't be used for measuring timeouts or other elapsed time measurements, as changing the system time can affect the results.
All four of the AlarmManager clock flags I've listed will include time spent in sleep, but only the *_WAKEUP flags will wake the device to sound the alarm; the default flags will wait until the device is otherwise awakened and then sound the alarm immediately.
Make sure you select the flag that matches your use-case, and ensure that the value of your delay {Integer at sep[3]?} is the amount of time to wait between alarms in milliseconds; as you have it, your Integer is being unboxed and cast to a long; it works, but unless there's a reason for it, I recommend switching to a primitive long; so a 15 minute delay would be:
int delay = 900000L // 15 minutes * 60 seconds * 1000 milliseconds
http://developer.android.com/reference/android/app/AlarmManager.html
http://developer.android.com/reference/android/os/SystemClock.html

Android Alarm What is the difference between four types of Alarm that AlarmManager provides and when to use what?

I want to know the difference between RTC, RTC_WAKEUP, ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP.
I want to write an alarm application where I will set alarm and close my application and expect for alarm for the time set.
There will be multiple alarms. Right now I am writing for emulator but later will test on device. In emulator, once I set the alarm and close the emulator and restart it, then will it be cleared, as I find with RTC, RTC_WAKEUP and ELAPSED_REALTIME. I am confused. Should I used ELAPSED_REALTIME_WAKEUP? I have not seen any tutorial using ELAPSED_REALTIME_WAKEUP.
please explain.
Thanks.
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.
RTC
Alarm time in System.currentTimeMillis() (wall clock time in UTC). 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.
RTC_WAKEUP
Alarm time in System.currentTimeMillis() (wall clock time in UTC), which will wake up the device when it goes off.
Types of Alarms :
ELAPSED_REALTIME – Fires the pending intent after the specified length of time since device boot. If the device is asleep, it fires when the device is next awake.
ELAPSED_REALTIME_WAKEUP – Fires the pending intent after the specified length of time since device boot. It wakes up the device if it is asleep.
RTC – Fires the pending intent at a specified time. If the device is asleep, it will not be delivered until the next time the device wakes up.
RTC_WAKEUP – Fires the pending intent at a specified time, waking up the device if asleep.
There are two general clock types for alarms: "elapsed real time" and "real time clock" (RTC). Elapsed real time uses the "time since system boot" as a reference, and real time clock uses UTC (wall clock) time. This means that elapsed real time is suited to setting an alarm based on the passage of time (for example, an alarm that fires every 30 seconds) since it isn't affected by time zone/locale. The real time clock type is better suited for alarms that are dependent on current locale.
Source: https://developer.android.com/training/scheduling/alarms.html
From the site you can get the difference between the 4 constanst
Below is example of the setting alarm
Calendar mCalendar = Calendar.getInstance();
mCalendar.add(Calendar.SECOND, 20);
Intent intent_Timer = new Intent(TimerEvents.this, AlarmReceiver.class);
intent_Timer.putExtra("alarm_message", "Drax Rules!!!");
// In reality, you would want to have a static variable for the request
// code instead of 192837
PendingIntent sender = PendingIntent.getBroadcast(this, 192837,
intent_Timer, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), sender);
Hope this will be helpful to you

Categories

Resources