Alarm Manager Accuracy - android

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

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

Alarm manager with elapsed realtime to fire immediately and repeat every 4 hrs

How to set up a repeating alarm to fire immediately when a Button is pressed and repeat itself in every 4 hrs.?
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(),
4*60*60*1000, alarmIntent);
Repeats itself but doesnt start immediately when a Button is pressed. it takes 5 mins to fire.
What am I doing wrong here?
I changed the code as below and the alarm is fired immediately
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, AlarmManager.INTERVAL_FIFTEEN_MINUTES, 4*60*60*1000, alarmIntent);
but it doesn't repeat every 4 hrs. How can I make the alarm repeat every 4 hrs?
Use setRepeating instead of setInexactRepeating.
Use setInexactRepeating when you want you alarm to fire around the specified time but you don't really need it to trigger exactly at that time.
This method exist so that the Android Os can manage to fire all the alarms at the same time in order to save battery life.
Take a look at this question, it might help you.
Quoting the accepted answer:
you should schedule alarm with AlarmManager.setExact() and then when alarm triggers do it again for next week and so on every week.
That's probably because you are using setInexactRepeating.
From google's documentation for setInexactRepeating:
Your alarm's first trigger will not be before the requested time, but
it might not occur for almost a full interval after that time. 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. If your application demands very low jitter, use
setRepeating(int, long, long, PendingIntent) instead.
Try:
alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()+2*1000,
4*60*60*1000, alarmIntent);
and check if it fires at least after 2 secs ..
Not sure if it will solve your problem, but might lead you to a workaround.

Background wifi scanning in Android

I'd started for about a month or two and I've to develop an Indoor Positioning System based on Wifi fingerprinting. I need an app that periodically scans wifi APs and send the result data to a Server.
So far I created an app that it's able to scan wifi APs and get the results when different connections are detected. I'm doing this in main activity using a broadcast receiver. The app is also able to send the data to the server.
What I want now is move this process to a periodic process in background, even when the smartphone is in sleep mode.
I have already read some topics about how to do it but none was clear. My question is what is the best way to do this? Using a Service/IntentService with a Timer/TimerTask?
Thanks.
Edit: Thanks!! AlarmManager and Services work fine!
I think an AlarmManager fits your needs, use setRepeating to set something to repeat every X time
Schedule a repeating alarm. Note: for timing operations (ticks,
timeouts, etc) it is easier and much more efficient to use Handler. If
there is already an alarm scheduled for the same IntentSender, it will
first be canceled.
Like set(int, long, PendingIntent), except you can also supply a
period at which the alarm will automatically repeat. This alarm
continues repeating until explicitly removed with
cancel(PendingIntent). If the stated trigger time is in the past, the
alarm will be triggered immediately, with an alarm count depending on
how far in the past the trigger time is relative to the repeat
interval.
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.
If your application wants to allow the delivery times to drift in
order to guarantee that at least a certain time interval always
elapses between alarms, then the approach to take is to use one-time
alarms, scheduling the next one yourself when handling each alarm
delivery.
Note: as of API 19, all repeating alarms are inexact. If your
application needs precise delivery times then it must use one-time
exact alarms, rescheduling each time as described above. Legacy
applications whose targetSdkVersion is earlier than API 19 will
continue to have all of their alarms, including repeating alarms,
treated as exact.
Parameters
type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC,
or RTC_WAKEUP.
triggerAtMillis time in milliseconds that the alarm
should first go off, using the appropriate clock (depending on the
alarm type).
intervalMillis interval in milliseconds between
subsequent repeats of the alarm.
operation Action to perform when the
alarm goes off; typically comes from IntentSender.getBroadcast().
As the note says
Note: as of API 19, all repeating alarms are inexact. If your
application needs precise delivery times then it must use one-time
exact alarms, rescheduling each time as described above. Legacy
applications whose targetSdkVersion is earlier than API 19 will
continue to have all of their alarms, including repeating alarms,
treated as exact.
But i don't think you care much if it's not precise.
Or you can use setInexactRepeating
Schedule a repeating alarm that has inexact trigger time requirements;
for example, an alarm that repeats every hour, but not necessarily at
the top of every hour. These alarms are more power-efficient than the
strict recurrences traditionally supplied by setRepeating(int, long,
long, PendingIntent), since the system can adjust alarms' delivery
times to cause them to fire simultaneously, avoiding waking the device
from sleep more than necessary.
Your alarm's first trigger will not be before the requested time, but
it might not occur for almost a full interval after that time. 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. If your application demands very low jitter, use one-shot
alarms with an appropriate window instead; see setWindow(int, long,
long, PendingIntent) and setExact(int, long, PendingIntent).
As of API 19, all repeating alarms are inexact. Because this method
has been available since API 3, your application can safely call it
and be assured that it will get similar behavior on both current and
older versions of Android.
Parameters
type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC,
or RTC_WAKEUP.
triggerAtMillis time in milliseconds that the alarm
should first go off, using the appropriate clock (depending on the
alarm type). This is inexact: the alarm will not fire before this
time, but there may be a delay of almost an entire alarm interval
before the first invocation of the alarm.
intervalMillis interval in
milliseconds between subsequent repeats of the alarm.
Prior to API 19,
if this is one of INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR,
INTERVAL_HOUR, INTERVAL_HALF_DAY, or INTERVAL_DAY then the alarm will
be phase-aligned with other alarms to reduce the number of wakeups.
Otherwise, the alarm will be set as though the application had called
setRepeating(int, long, long, PendingIntent). As of API 19, all
repeating alarms will be inexact and subject to batching with other
alarms regardless of their stated repeat interval. operation Action to
perform when the alarm goes off; typically comes from
IntentSender.getBroadcast().
While my answer aim is to say a general way to repeat an action every X time, as other noticed, you will need Wifi Lock, Wake lock and use RTC_WAKEUP as AlarmManager type.
RTC_WAKEUP:
Alarm time in System.currentTimeMillis() (wall clock time in UTC),
which will wake up the device when it goes off.
Move your code from Activity to Service. Then, start the service periodically using AlarmManager. Service does the scanning and stops self when it is done. Then it is started again when timer elapses.
EDIT: Also look at cpu lock and wifi lock.
EDIT2: Also when creating alarm, use RTC_WAKEUP constant so that your action is triggered even if the device is in sleep mode.

Difference between setRepeating and setInexactRepeating of AlarmManager

What are the parameters of the following:
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_FIFTEEN_MINUTES, alarmIntent);
And of the following:
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
What is the difference and also how are the two different in terms of functionality?
Both examples schedule a repeating alarm that will send the given alarmIntent. On both cases, the first time it is sent will be immediate (calendar.getTimeInMillis() returns the current time). On both cases, the device will be woken up when the alarm needs to be sent (as evident by AlarmManager.RTC_WAKEUP).
There are two differences between these calls. The simpler one is that the intent will be sent every fifteen minutes on the first call, and every day on the second call (as you can see in the third parameter). The more complicated difference is the function call itself: setRepeating will schedule the first alarm for exactly every fifteen minutes; setInexactRepeating will schedule the second alarm for approximately every 24 hours, meaning it might deviate from that interval - with the advantage of consuming less power.
Do notice that this has changed in API 19, where these two calls are synonymous. See this guide, and this API documentation.
Decide how precise your alarm needs to be
Choosing the alarm type is often the first step in creating an alarm. A further distinction is how precise you need your alarm to be.
For most apps, setInexactRepeating() is the right choice. When you use this method, Android synchronizes multiple inexact repeating alarms and fires them at the same time. This reduces the drain on the battery.
For the rare app that has rigid time requirements as example, the alarm needs to fire precisely at 4:00 p.m. everyday then use setRepeating().
Reference: Decide how precise your alarm needs to be
To augment previous answers, there are a number of other best practices to consider when using repeating alarms, particularly inexact alarms requested using setInexactRepeating().
Alarm Type
Non-WAKEUP alarms are better than WAKEUP alarms from a power management perspective. Using the former your alarm may fire late, but it will still fire either when the device is woken by the user, or when another wakeup alarm fires. Using WAKEUP alarms will wake the device out of sleep, consuming additional battery and potentially causing other inexact alarms to fire that have been delayed that could otherwise have been delayed longer (reducing the batching power-saving benefits that inexact alarms provide).
Prefer alarms using the ELAPSED timebase rather than the RTC timebase. The former are more likely to have a more random distribution across devices than RTC alarms, which reduces the risk of network congestion and on the server if the alarm is triggering some sort of poll. Phones running Gingerbread (or older) suffer from a bug whereby RTC inexact alarms have a tendency to align closely to the real-time clock, e.g. approximately 30s past each quarter of an hour. ELAPSED alarms don't suffer from this bug on these earlier platform versions. Even if your alarm doesn't trigger any network activity, remember that if it is a wakeup alarm it may trigger other alarm non-wakeup intents that may hit the network.
Timebase
Be careful to specify the requested start time in the correct time domain for the alarm type. Failure to do this can result in alarms being set in the past (they fire right away) if setting an RTC alarm with an ELAPSED timebase or far in the future if setting an ELAPSED alarm using the RTC timebase. You can check what alarms an app has scheduled using dumpsys alarm via the adb shell.
Interval
Specifying an inexact alarm interval of anything other than the interval constants defined in the AlarmManager API is redundant on SDK <19: they will be scheduled as exact not inexact alarms, losing all the power-saving benefits that inexact alarms provide.
Edit: here's further explanation of the bug relating to gingerbread and honeycomb 3.0 devices: https://code.google.com/p/android/issues/detail?id=31550
setRepeating is more accurate and setInexactRepeating is for saving battery but no accurate , setInexactRepeating is good for maintenance in background for example and setRepeating is necessary for example for alarm clock .
Use setInexactRepeating() is used when app is not seriously used to required for example wake up early in the morning . if Alarm wake up approximately that time there is no any life dangeous.
like medicine pills app where highly critical patient use that app to reminde nurse or doctor staff the is compulsory to use setRepeating().
When you use setInexactRepeating()
then Android synchronizes repeating alarms from multiple apps and fires them at the same time(once). This reduces the total number of times the system must wake the device.
thus reducing drain on the battery.
repeating alarms are inexact. Note that while setInexactRepeating() is an improvement over setRepeating() also
it can still overwhelm a server if every instance of an app hits the server around the same time. Therefore, for network requests, add some randomness to your alarms.

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