When an app sets a repeating alarm and from the users point of view the phone is in normal mode with an alarm in the notification bar what is happening with the code of the app? I assume the values of all the variables are stored in the phone memory in such a way that when the alarm wakes up the original state is restored. Does setting an alarm impose much more demand on the battery?
When an app sets a repeating alarm and from the users point of view the phone is in normal mode with an alarm in the notification bar what is happening with the code of the app?
AlarmManager has nothing to do with the AlarmClock application. There is no "alarm in the notification bar" unless you put something there yourself, which would be a bit unusual for an app employing AlarmManager.
Assuming you are referring to AlarmManager, "what is happening with the code of the app" is it better be shut down. The point behind AlarmManager is so you do not have to keep any code in memory just to watch the clock tick by.
I assume the values of all the variables are stored in the phone memory in such a way that when the alarm wakes up the original state is restored.
That is absolutely incorrect. AlarmManager does nothing of the sort. And, a well-written app using AlarmManager will get the heck out of memory when it is not delivering any immediate value. If you need data to persist between alarms, use databases or files.
Does setting an alarm impose much more demand on the battery?
A _WAKEUP alarm will have an impact on the battery proportional to the frequency with which the alarm goes off. If the alarm is nice and infrequent (e.g., user configured to every 15 minutes), the alarm itself will have little impact, but what you do when the alarm goes off might.
Related
I have two questions.
I want fire a Broadcast receiver using AlarmManager and show a notification in onReceive method. Should I use from WakeLoke for this?
What is different between setAlarmClock() and setExactAndAllowWhileIdle() ?
I use (as you wrote) the onReceive method to start a newWakeLock and it works fine for me.
The difference lies in the behavior in doze mode (Doze Mode: https://developer.android.com/training/monitoring-device-state/doze-standby).
I do not know your exact problem, but I worked very hard to develop an app which contains few timers and every timer should make a notification at the exact time even the screen is locked and the device is in the doze mode. My solution is to fire an Broadcast over an AlarmManager with the setExact(...) method.
Answer your question in reverse order
.2. setExactWhileIdle guarantees that if the system is not sleeping and not in doze, the alarm will go off within 1 minute of the given time. if the system is in doze mode, the alarm will go off within 15 minutes of the given time. In practice, if the system is not in doze mode or low on battery, the alarm will go off on time. On the other hand, setAlarmClock is the closest one can get to a guarentee that the system will deliver the alarm at a specific time; this does come at a relatively large drain on battery. So, if your goal is to implement highly time sensitive notifications such as an alarm clock, then use setAlarmClock. Otherwise try to avoid it.
.1. according to the documentation, upon an alarm being dispatched from setExactAndAllowWhildIdle or setAlarmClock:
the app will also be added to the system's temporary power exemption list for approximately 10 seconds to allow that application to acquire further wake locks in which to complete its work.
My suggestion is that if all you are doing is posting a notification, then a wake lock is not necessary. Otherwise, if you are doing longer running work, use a wake lock
Obligatory Disclaimer: battery drain is a real thing. please don't make an app that drains the battery. do everything in your power to design your app not to disturb the systems power optimization. All exact alarms and especially setAlarmClock disrupt the systems attempts to optimize battery. If its necessary, then its necessary. Otherwise, do not do it.
I am using AlarmManager, trying to create an Alarm app for android.
I noticed that setRepeating was not working when the phone sleeps.
So, I tried setExactAndAllowWhileIdle.
But, I read this:
Unlike other alarms, the system is free to reschedule this type of alarm to happen out of order with any other alarms, even those from the same app. This will clearly happen when the device is idle (since this alarm can go off while idle, when any other alarms from the app will be held until later), but may also happen even when not idle. Note that the OS will allow itself more flexibility for scheduling these alarms than regular exact alarms, since the application has opted into this behavior. When the device is idle it may take even more liberties with scheduling in order to optimize for battery life.
I need accurate timings like an alarm clock. A user sets it for 6:00 am then ringing at 6:01 or 6:02 would be wierd!
Not ringing at all because the phone is idle is catastrophic!
What can I do now?
Do not use repeating alarms for this purpose. They are not accurate/reliable enough. Schedule one alarm using set() or setExact() (depending on your target API level). When that alarm goes off, set the next one.
NOTE: Make sure that you use an alarm type that will wake the phone:
RTC_WAKEUP or
ELAPSED_REALTIME_WAKEUP
I'm trying to trigger the alarm in a specific interval only when the device is awake, This is the code which I used to achieve this:
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime(),
INTERVAL_ONE_MINUTE,
pi);
Considering documentations about AlarmManager.ELAPSED_REALTIME android is not supposed to trigger the alarm when device screen is off (If I mistake not)
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
Contrary to my expectation alarm was triggered by system when the screen is off, Am I missing something here?
Why are you not using
protected void onPause();
to fire there
pi.cancel();
alarmManager.cancel(pi);
When they speak of the device going to sleep, that doesn't mean the screen is off.
See: When does android device go to sleep mode?
See: http://developer.android.com/training/scheduling/wakelock.html
When the device's screen isn't on, it still will be woken up to do things from time to time. To save battery, it'll sleep, but apps will inevitably wake it up to do things.
You could check to see if the screen is on: How can I tell if the screen is on in android?
The documentation you cite is just saying that the alarm won't fire when the device goes to sleep when ELAPSED_REALTIME is used.
Sounds like you want the alarm to fire when the application process is still alive. You might look at using ActivityLicecycleCallbacks:
http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html
This will let you schedule/cancel the alarm based on the process lifecycle as opposed to a single activity.
You might also look at
Application.onTrimMemory
to see when it gets called by the OS. You might find some use cancelling your alarm there.
I'm have a widget that is being updated from a service. When the user then turn off the screen, the service stops and won't start to update the widget again when the user wake up the device. So on to my question, is there some way to "restart" the service when the user wake up the device? I know I can keep the service keep going when the screen is locked, but I think it would drain to much battery then... I have google'd alot but haven't found anything...
Thanks in advance!
EDIT: Okey, this is strange! Now somehow it does that automatically, so it's working now! Thanks anyway!
EDIT 2: Or, now I don't really think it's the screen lock that stops the service, cause it just sometimes stops randomly without crashdialog when I use the phone... Anyone know how I should do to fix that?
For a widget it usually doesn't make sense to keep a service running all the time, you usually update the widget periodically.
The easiest way to do this and to be battery efficient is to schedule an intent using AlarmManager and setAlarmInexactRepeating:
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 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.
The intent should trigger a BroadcastReceiver which in turn should trigger your service to update the widget. Using IntentService is usually a good choice for that.
If you need more control over the intent scheduling, you can also set the alarms yourself in when the service is finished with updating the widget, and supply RTC or ELAPSED_REALTIME as the type of alarms. Both types won't wake up the device if it's sleeping. If the device is not sleeping (but locked) you'll effectively piggy back on other events that woke the device.
If you really need to update as soon as the device is unlocked, the ACTION_USER_PRESENT broadcast might be what you need, but I'd still recommend to implement that as an addition to scheduling a periodic update.
Yes this is Possible!
When the user turn off the screen You Have to handle BroadCast Receiver (http://developer.android.com/reference/android/content/BroadcastReceiver.html)
That handle to Stop service & the service stops and stop to update the widget,
when the user wake up the device you have to Receive Broadcast start to update the widget.
I think it would be The best idea to save more battery.
For More information Please Refer this Link
I have an app which allows users to schedule alarms to sound at certain times, repeating at intervals of their choosing. I am using JSON to persist the alarm details, using SharedPreferences as storage.
I am using AlarmManager to schedule when my app should be notified that an alarm should sound to notify the user. I am currently using the setRepeating() method of AlarmManager, supplying the interval provided by the user. This works well, and in theory the app would never need to update the JSon which stores the next alarm time, as AlarmManager will just reschedule the next alarm time using the interval.
However, my thinking is that when the device is rebooted, I will need to supply a up to date alarm time to AlarmManager to avoid AlarmManager thinking an alarm has been missed as this is not necessarily the case.
So, what's the best way to do this?
update the JSon next alarm time when the alarm is sounded, even though this may not be necessary (setRepeating() handles this as long as there is no reboot)?
register for and listen for shutdown broadcasts and update JSon then (this raises questions - just how long will the app get to calculate and write alarm details to storage given that the phone is shutting down)?
don't update the JSon but add logic to the object which is woken by the AlarmManager to decide if the alarm just broadcast is valid and the user should be alerted?
I'm sure any of the above will work, but I can't decide which is the nicest way to do it.
This seems mostly a matter of choice. The problem you note parallels a general problem seen in Linux laptops and solved by anachrond. In my opinion, I would simply update the time and store it in SharedPreferences every time the event is received. Trying to listen for when the system shuts down might not be entirely reliable (what happens when your users -- probably drunk college students -- drop their device and the battery flies out?). Instead, I believe the best thing to do in this scenario would be to -- each time the alarm fires -- recalculate the time to send the next one, store it somewhere, and upon boot schedule appropriately.