Beginning with API 19 (KITKAT) alarm delivery is inexact.
For my app this is very bad news.
There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent).
But I do not see any 'setRepetitiveExact' method, what does this means ? they completely discourage this thing and they did not even made an API :S ?
I know it can drain battery but I still want to use it, I need to be exact!, I do not want this to happen eventually when the phone wakes up :S...
what does this means ? they completely discourage this thing and they did not even made an API :S ?
Correct.
I still want to use it, I need to be exact!
Then do it yourself. Use setExact() to set up the first event. In the handler for that event (e.g., BroadcastReceiver), set up the next event with another call to setExact().
Related
This is something I have been trying for a long time but have never been able to entirely get to work chiefly because of the inability to make the timer accurate. I am wanting to build an Android desk clock-type application which allows one to set a timer and then have it go off reliably after the interval requested with audio notification, i.e. you set it, let it run, then when the time runs out the device starts beeping to let you know the time is up and/or put a notification on screen.
The trick is that, particularly in the newer versions of Android, there seem to be a variety of different power management and anti-malware features to contend with that seem to make it quite difficult, and other threads here about building alarm clocks are quite old and thus useless in the face of rapid and ongoing changes to the API by Google.
Strategies that I've tried so far include running a service with foreground notification and using the alarm manager (and yes even with the "setExact" stuff which, apparently the API docs say actually isn't what it says on the tin because of these throttling features!), but in either case, particularly once the device falls asleep, the alarm may sometimes work but other times it goes off belatedly if at all, and this random, inconsistent behavior is clearly not acceptable.
Is there a robust (or as robust as possible) way to make a user-notifying timer as of 2021, compatible with, say, API levels 18 to 30? Note that I've tried looking at open source source code for the DeskClock app but it's not the most friendly code and moreover it has many more features than I'd want to have in this simpler app, which makes it hard to figure out what all are the essential bits. It does seem the alarm manager is used, but I'm not sure how they're getting exact timeout.
Strategies that I've tried so far include running a service with foreground notification and using the alarm manager (and yes even with the "setExact" stuff which, apparently the API docs say actually isn't what it says on the tin because of these throttling features!)
The documentation for setExact explicitly states (emphasis mine):
Schedule an alarm to be delivered precisely at the stated time.
This method is like set(int, long, android.app.PendingIntent), but does not permit the OS to adjust the delivery time. The alarm will be delivered as nearly as possible to the requested trigger time.
It doesn't say anything about throttling.
Further, it goes on (again, emphasis mine):
Note: only alarms for which there is a strong demand for exact-time delivery (such as an alarm clock ringing at the requested time) should be scheduled as exact.
Is that not what you're looking for?
If I set a repeating alarm on my application's first run. Then what are the chances that affects the disabling of alarm. I mean if I do not interfere with the alarm then does there is a chance that the android OS will disable it?
Alarm will not be killed by the OS like a normal service.
In case of repeating alarms, behavior differs from api 21 (or api 19, dont remember). After API 21, repeating alarms are not 'setexact()' i.e. OS will optimize them and alarms may not go off at the exact time specified.
In case of reboot, OS will not automatically reload the alarms for you. You have to handle the logic in 'RECEIVE_BOOT_COMPLETED'
What is difference between AlarmManager.setAndAllowWhileIdle() and AlarmManager.setExactAndAllowWhileIdle()? How does these both affect Doze mode introduced in Android 6.0 (Marshmallow) API?
Refer to the documentation of AlarmManager:
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
Indeed, both the methods you mentioned specify that they behave like their counterparts without the "AndAllowWhileIdle" (set and setExact). So one of them will deliver the alarm at the exact time and the other will not be exact.
I was ready through the documentation and i was having some questions about setReating and setInexactRepeating. I was reading some other posts, but i could't find an answere.
The documentation says for both:
Note: as of API 19, all repeating alarms are inexact.
Does is mean that both methods are exactly the same in api 19 and above? Also how inexact is inexact? And if there is any delay, what are the effects for the following alarm?
Thanking in advance.
As one can read at the end of the official documentation as of API 19 [and future versions] all calls to setRepeating() will delegate to setInexactRepeating() instead. So as of KitKat and upcoming versions both methods do the exact same thing.
The delay will not effect the following alarms refering to the official documentation.
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.
I wanted to make a widget that updates every sec(more battery consumption) or min(less battery consumption).
I followed as in this thread
, but runs only in every 30mins.
I configured that, once onUpdate is run, it updates in 1mins and
onReceived is run in every 30mins.
Can anyone tell me what I am doing wrong?
From my experience AlarmManager doesn't work well (or at all) with intervals lower than 1 minute. Besides:
Note: The Alarm Manager is intended for cases where you want to have
your application code run at a specific time, even if your application
is not currently running. For normal timing operations (ticks,
timeouts, etc) it is easier and much more efficient to use Handler.
Moreover:
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS
will shift alarms in order to minimize wakeups and battery use. There
are new APIs to support applications which need strict delivery
guarantees; see setWindow(int, long, long, PendingIntent) and
setExact(int, long, PendingIntent). Applications whose
targetSdkVersion is earlier than API 19 will continue to see the
previous behavior in which all alarms are delivered exactly when
requested.
You are doing nothing wrong, the widget service indeed only updates every 30 minutes(minimum).
To make it update faster you need to use AlarmManager, or your own application that will call the service. Unlike soulreaver answer, the alarm manager does work with times less then 1 minute.