My code logic is like
Set a repeated wakeup alarm.
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 60000, pIntent);
during onReceive() of the receiver. do something very quick, may just need 100ms at most.
The operation will repeat every minute and it will be battery burden somehow ( since we want to the background service run as long as possible).
Now, according to our power monitoring tool, even if we do just some logging in onReceive(). It still takes around 1.5 seconds.
I have done some research and I conjecture it may related to the waiting in
alarm_suspend of android enhanced linux kernel.
However, I am not sure about it. Looks like there is no reason android need to keep the alarm running time that long, so I am asking if someone has some good experience on setting up the alarm and make the overhead as small as possible?
Thanks.
Related
I have to update Data in my App every 24 hours at 2 am.
Currently, I have an Alarm via the AlarmManager which sends an alarm every 24 hours with the setRepeating method.
In the past I have experienced some unreliabilities with the timing of the alarm, so I was experimenting with an intent-filter and Intent.ACTION_TIME_TICK.
My Question:
What is the difference between setting a repeated alarm every 24 hours and using an intent-filter which gets its information from the system?
You should absolutely not do anything with ACTION_TIME_TICK. Nor would it be reliable if you tried- it would only work while your app is running, and if you're backgrounded you will be killed for resources. The correct answer here is actually JobScheduler or WorkManager, depending on the nature of what you're doing. Most likely WorkManager. However if you were worried about the reliability of timing of an alarm, you probably are thinking about your problem wrong. Unless you have a VERY niche use case, a bit of inaccuracy in downloading a nightly update is generally ok. In fact it may even be welcome, to spread the load out on the server. Your inaccuracy of dl time is likely due to Doze, which is a mechanic your use case should likely account for (Doze is a power saving mode where it reduces the frequency of timed events running when the screen is off).
I have an AlarmManager which calls a BroadcastReceiver every minute. It is working fine without any problem. The BroadcastReceiver looks up the values existing on a SharedPreferences file. It checks around 4 values every minute.
I was just wondering if this is taking a toll on the system. And will it eventually make the device slower ?
PS - I cannot reduce the values anymore. That would conflict with my current design.
Thank You in advance.
PPS - A brief theory regarding the time and speed of SharedPreference would be greatly appreciated.
Well, I don't know if AlarmManager drains your battery fast, but what I suggest u to do is remove the AlarmManager part in your code, and use a Handler instead.
From the AlarmManager:
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.
precision timing required either:
setRepeating for < API19
setExact API 19 <
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. Applications are strongly discouraged from using exact alarms unnecessarily as they reduce the OS's ability to minimize battery use.
these are both pretty battery consuming.
So u would have to go with:
setInexactRepeating for < API 19
Note: 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.
but this is not very precise for an alarm that has to execute every minute.
So, you're probably best of with a Handler:
final Handler handler = new Handler()
handler.postDelayed( new Runnable() {
#Override
public void run() {
//Do your things
handler.postDelayed( this, 60 * 1000 );
}
}, 60 * 1000 );
Hope this answers your question. If anything isn't correct or should be improved, feel free to edit/add this, or leave a comment below.
First time I have tried to implement either of these and I am unsure which to use.
I want my application to create a time frame, e.g. 2/3/12 to 7/3/12. Multiple time frames such as this can be created. A different intervals (e.g. every 4 hours) I would like my application to preform some actions for each time frame. This needs to be done in the background.
I have first tried to implement this with a Service, but am having performing all the actions for each of the time frames concurrently. After reading the android blog "Multitasking the android way" I think that perhaps BroadcastReceivers are better.
Please advise
Please see my answer about using the AlarmManager - Running task periodicaly(once a day/once a week)
If you are only running a process at a set time rather than constantly (e.g. monitoring audio levels) then you are going to ask a service to sit there 90% of the time and do nothing except waste battery power. The AlarmManager solves this problem as it notifies the broadcast receiver to execute at the given times.
Edit: Also bear in mind that after phone restart all alarms are removed so you will need to register a broadcast receiver to be notified of the device boot-up so you can re-register any Alarms that are needed.
You should probably be using the AlarmManager and a IntentService.
The AlarmManager will kick of your IntentService at specified intervals. You can kick off the IntentService for each set of actions.
I'm using alarm manager in my service to set non-waking alarms every 15 seconds to execute a certain task. I don't want to wake the phone up as the task isn't time critical, so i'm using the ELAPSED_REALTIME flag to set the alarm. Here's the code:
alarm.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), 15 * 1000, intentRecurringChecks);
What I'm noticing in my logs is that the task is getting executed every 15 seconds. Does this mean the phone is staying awake even though it's screen has been turned off for half an hour? Is there a way I can be sure my application's not the one waking up the phone?
I've search about this topic but I can't find a proper answer.
Thanks for your help.
First, you shouldn't use AlarmManager for such timeouts. This is explicitly mentioned in documentation (read the bold part). It's better to use Handler based timers in your case. Here is an example: Repeat a task with a time delay?.
Second, when device is connected via USB, its not going to deep sleep mode. You should disconnect your device wait a minute or two. Attach it back and analyze the logs.
I'm trying to run a background task which runs every minute or so for an android application but I am struggling to ensure that the task actually runs every minute. I've tried a variety of approaches from using SystemClock.sleep() to the AlarmManager (both repeating alarm and a fixed alarm) but it seems that unless the device is charging any kind of repeating system has a variable repeat rate once the device is unplugged. Is there any way to run a stable consistently repeating service?
Have you implemented Timer? It works very well for what I use it for, but then again I haven't worried about the precision at all. For all I know it may be varying a bit but I doubt it. It seems pretty consistent to me.
Edit: I am not liable for your responsible or irresponsible use of this facility ;)
If you need to have a service that runs every minute, on the minute, you have two options:
Use AlarmManager.setRepeating(RTC_WAKEUP, ...). In this case, the phone will sleep, but the RTC inside the phone will wake it up every minute to handle the repeating event. This will work, but will not be terribly exact as a lot of things are happening after the phone wakes up so your code might not get execution time right away.
Obtain a WakeLock from PowerManager and use whatever you want to time your code (Timer, Handler, etc.). This forces the phone to never sleep, which means that it is most likely free to run your code almost exactly when you request.
Both approaches will definitely drain the battery of the phone fast. Normally, the phone can sleep for 4 or even 9 minutes between wakes, so waking up once per minute is a big change from that.