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.
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 am working with Android API especially Alarms, IntentService and notifications. I am using AlarmManager to schedule a periodic IntentService which might or might not fire notifications.
My questions is What happens when the device is in sleep mode?
Alarm will not fire and thus IntentService will not run at all. I am not sure if this will be the case.Will it make a difference if I make it a WakefulIntentService? I believe wake locks are needed to ensure the service keeps running after the BroadCastReciever returns. However, in this case there is no broadcast reciever.
Alarm and IntentService will run, but any notification will not have any impact since the device is sleeping. In this case, do I have to explicitly get a wakelock from PowerManager to fire notification ?
What happens when the device is in sleep mode?
That depends upon your type of alarm and the component your PendingIntent is to invoke.
If your alarm type ends in _WAKEUP, and you are using a broadcast PendingIntent, the device will wake up and remain awake through the call to onReceive() of the BroadcastReceiver. Once onReceive() returns, the device can fall asleep again. This is why WakefulIntentService and WakefulBroadcastRecevier were created -- to offer tested patterns for how to pass control to an IntentService and keep the device awake while the service completes its work.
If your alarm type ends in _WAKEUP and you are not using a broadcast PendingIntent, as the saying goes, your mileage may vary. You may not get control before the device falls back asleep. This is not a recommended pattern.
If your alarm types does not end in _WAKEUP, the device will not wake up due to your alarm.
With respect to the Notification, given the nature of the API, one hopes that it is the OS' responsibility to keep the device awake long enough for the ringtone or vibration pattern to play, as we do not know the precise instant when the Notification appears, nor do we know whether the ringtone will play (e.g., device is on silent mode).
I just went through this tutorial:
update-widget-in-onreceive-method
(btw: would you propose any improvements to that code?)
At the end someone mentions:
I'm just wondering if there is a way to extend this further so that when the device is asleep (screen off), the updates stop. Then when the device wakes up, the updates resume.
So my question: is there a way of doing this? how?
or is the alarmmanager automatically stopped? - I don't think so.
You can specify whether the device will wake up when scheduling the AlarmManager.
Quote from the documentation:
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.
Same goes for AlarmManager.RTC and AlarmManager.RTC_WAKEUP
So you probably want one of the two AlarmManager.RTC or AlarmManager.ELAPSED_REALTIME. These continue while the device is awake and stop when the device is in standby. If this alarm is triggered while the device is asleep it will be delivered when the user turns the device back on though, exactly what you want. And no, the AlarmManagers scheduled alarms are not cancelled automatically in general.
The part mentioned here can be found in this part of the tutorial, specific this line:
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 20*1000, pendingIntent);
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.