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);
Related
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 need to set a repeating alarm every X hours that would even fire in doze mode. However, the only Apis available in AlarmManager for Android 23 are setExactAndAllowWhileIdle and setAndAllowWhileIdle which are not for repeating alarms.
I am wondering if I should reschedule the alarm every time it fires? or is there any better solution?
I am wondering if I should reschedule the alarm every time it fires?
That is exactly what you should do.
The idea behind doze is to attempt to prevent draining the battery. Repeated alarms drain battery, so the builtin way to repeat alarms by passing an extra parameter was removed in android 6. It can still be done, but as you were wondering, that requires you to manually reschedule the alarm.
Be sure to reschedule the alarm immediately when it fires, before doing anything else that could go wrong and prevent the alarm from being rescheduled.
I set multiple alarms and in order to control them I change my phone's time. They will work normally ? What In other words, will alarms collapse if I change my phone's time?
Well it all depends on the type you have passed in the set method of alarm Manger.
if you have used ELAPSED_REALTIME or ELAPSED_REALTIME_WAKEUP, alarm will not trigger
ELAPSED_REALTIME
Added in API level 1
int 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.
if you have user RTC or RTC_WAKEUP, alarm will be triggered according the device time
RTC
Added in API level 1
int 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.
I don't know what you mean by collapse. But the alarm is only aware of the device's time and so if you do change your device time, it should work against that instead.
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.
Hello I was reading on android docs about these two constans of AlarmManager but didn't get exactly the difference between them.
RTC Alarm time in System.currentTimeMillis() (wall clock time in UTC).
RTC_WAKEUP Alarm time in System.currentTimeMillis() (wall clock time in UTC), which will wake up the device when it goes off.
Does not RTC wake up the device and fire the PendingIntent when device is in sleeping mode ?
Thanks in advance.
Does not RTC wake up the device and fire the PendingIntent when device is in sleeping mode ?
RTC and ELAPSED_REALTIME do not wake up the device out of sleep mode. If the device is in sleep mode at the time of the event, nothing immediately happens. You will be notified about missed events when the device wakes up for other reasons (e.g., user presses the power button).
RTC_WAKEUP and ELAPSED_REALTIME_WAKEUP will wake up the device out of sleep mode. If your PendingIntent is a broadcast PendingIntent, Android will keep the device awake long enough for onReceive() to complete. If you have significant work, that you do not want to do in onReceive() (because onReceive() is called on the main application thread), you will need to arrange to keep the device awake long enough for some service of yours to complete the work, such as by using WakefulBroadcastReceiver.