Scheduling operations via AlarmManager in Android Android07.05.2017
Android:name='com.taxiemall.utility.BroadcastAlarmManger' android:enabled='true' android:exported='true'/ Also you have to handle Reboot manually. After every reboot registered alarm are cleared. So register a broadcast receiver for Android reboot and register you alarm again inside it. SOLUTION 2: This is the library that worked. AlarmManager has many kinds of alarms built into it, both one-time and periodic, exact and inexact. To learn more about the different kinds of alarms, see Schedule repeating alarms. AlarmManager, like notifications, uses a PendingIntent that it delivers with the specified options. This example uses an alarm that is referenced to real time. A determination is made whether the next occurrence of 14:00 will be today or tomorrow, and that value is returned as the trigger time for the alarm. Starting in Android 4.4, the AlarmManager defaults all alarms to be inexact, meaning there is a small window within which they will trigger. Android documentation: AlarmManager. AlarmManager Related Examples. API23+ Doze mode interferes with AlarmManager. Android AlarmManager Example In the example I will schedule an alarm to send SMS at a particular time in future. We have two classes 1: MainAcitvity: in this class, we will schedule the alarm to be triggered at particular time. 2: AlarmReciever: when the alarm triggers at scheduled time, this class will receive the alarm, and send the SMS.
Introduction
Scheduling and repeating alarms are generally used as a local reminder to notify user about some event.
Android provides
AlarmManager
to create and schedule alarms. AlarmManager
class provides access to the system alarm service. This allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent
that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running.AlarmManager
runs outside the lifetime of your application. Once an alarm is scheduled, it will invoke even when your application is not running or in sleep mode.An scheduled alarm will execute unless it is stopped explicitly by calling
cancel()
method, or until device reboots. This means, you need to re-schedule them explicitly when device boot completes.Alarms offer the following features:
- Schedule alarms for a set time or interval.
- Maintained by the OS, not your application, so alarms are triggered even if your application is not running, or the device is asleep.
- Can be used to trigger periodic tasks (such as an hourly news update), even if your application is not running.
- Your app does not use resources (such as timers or background services), since the OS manages the scheduling.
Alarms are not the best solution if you need a simple delay while your application is running, for example, a short delay for a UI event. For short delays, it's easier and more efficient to use the
postAtTime()
and postDelayed()
methods of a Handler.Alarm have three properties, as follows:
- Alarm type (see in the following list).
- Trigger time (if the time has already passed, the alarm is triggered immediately).
- Pending Intent.
A repeating alarm has the same three properties, plus an Interval:
- Alarm type (see in the following list).
- Trigger time (if the time has already passed, it triggers immediately).
- Interval.
- Pending Intent.
There are four alarm types:
- RTC (Real Time Clock). The alarm times are referenced to UTC time. This does not wake the device. Fires the pending intent at a specified time. If the device is asleep, it will not be delivered until the next time the device wakes up.
- RTC_WAKEUP. The alarm times are referenced to UTC time and will wake the device to trigger if it is asleep. Fires the pending intent at a specified time, waking up the device if asleep.
- ELAPSED_REALTIME. This is based on the time elapsed since the device boot. This does not wake the device. It is better for time interval alarms-such as every 30 minutes. Fires the pending intent after the specified length of time since device boot. If the device is asleep, it fires when the device is next awake.
- ELAPSED_REALTIME_WAKEUP. This is based on the time elapsed since the device boot. This wakes the device if it is sleeping. Fires the pending intent after the specified length of time since device boot. It wakes up the device if it is asleep.
RTC is most commonly used for setting alarm service in Android.
If you choose a wake-up alarm type, Android will wake the device from sleep but will not keep the device awake for you. You must obtain a
WakeLock
from PowerManager
while doing your background work from a wake-up event. Otherwise, Android is likely to put the device back to sleep quickly, which will halt what you may be doing.Thera are some methods which are used to schedule alarms. These methods are based on exact, inexact time of execution and repeating or single execution.
- set(int type, long triggerAtMillis, PendingIntent operation). Schedules the alarm and if there is already an alarm by the intent then previous one will be canceled. It allows executing only one time.
- setExact(int type, long triggerAtMillis, PendingIntent operation). It behaves same as
set()
but it does not allow OS to adjust time. The alarm will fire on exact time. - setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation). It behaves same as
set()
but repeats for the given interval of time. - setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation). Same as
setRepeating()
but the executing time will not be exact. - setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation). Executes within a given window of time and works same as
set()
. It can be used for strict ordering of execution in case of multiple alarms.
After android API 19 (KitKat) all the alarms are inexact, this is done to save battery life and disable multiple wakeups. By doing so all the alarms are bundled to its near about time and triggered at once. There are new APIs to support applications which need strict delivery guarantees; see
setWindow()
and setExact()
. Applications whose targetSdkVersion
is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.One-time alarm
The following recipe will demonstrate how to create alarms with
AlarmManager
.Setting an alarm requires a Pending Intent, which Android sends when the alarm is triggered. This intent can point to any system component, such as a
BroadcastReceiver
or Service
, that can be executed when the alarm triggers. Therefore, we need to set up a Broadcast Receiving to capture the alarm intent. Our UI will consist of just a simple button to set the alarm. To start, open the Android Studio and follow these steps:- Add the following
<receiver>
to the<application>
element at the same level as the existing<activity>
element:
Open activity_main.xml and add the following button:
Create a new Java class called
AlarmBroadcastReceiver
using the following code:Open ActivityMain.java and add the method for the button click:
Creating the alarm is done with this line of code:
Here's the method signature:
To set the alarm, we create a Pending Intent with our previously defined alarm action:
This is an arbitrary string and could be anything we want, but it needs to be unique, so we prepend our package name. We check for this action in the Broadcast Receiver's
onReceive()
callback.If you click the Set Alarm button and wait for two minutes, you will see the
Toast
when the alarm triggers. If you are too impatient to wait and click the Set Alarm button again before the first alarm is triggered, you wouldn't get two alarms. Instead, the OS will replace the first alarm with the new alarm, since they both use the same Pending Intent. If you need multiple alarms, you need to create different Pending Intents, such as using different Actions.If you want to cancel the alarm, call the
cancel()
method by passing the same Pending Intent you have used to create the alarm. If we continue with our recipe, this is how it would look:Repeating alarm
If you want to create a repeating alarm, use the
setRepeating()
method. The signature is similar to the set()
method, but with an interval
. This is shown as follows:For the
Interval
, you can specify the interval time in milliseconds or use one of the predefined AlarmManager
constants:- INTERVAL_DAY
- INTERVAL_FIFTEEN_MINUTES
- INTERVAL_HALF_DAY
- INTERVAL_HALF_HOUR
- INTERVAL_HOUR
Let's write a very basic service that will simply display the current time as a
Toast
every time it is triggered.That service must be registered in the AndroidManifest.xml with a
<service>
tag. Otherwise, AlarmManager
which is external to your application will not be aware of how to trigger it.Below is layout to control our
AlarmService
.Following is the Activity to register/unregister alarm.
As of Android 5.1 (API version 22) there is a minimum period of 1 minute for repeating alarms. If you need to do work within one minute, just set the alarm directly, then set the next one from that alarm's handler, etc. If you need to do work within 5 seconds (for example), post it to a
Handler
instead of using the AlarmManager
.The sample activity presents two buttons: one to begin firing regular alarms, and the other to cancel them. The operation to trigger is referenced by a
PendingIntent
, which will be used to both set and cancel the alarms. We create an intent referencing the service directly, and then we wrap that intent inside a PendingIntent obtained with getService()
.The alarm in the example is registered to trigger 1 minute after the button is pressed, and then every 1 minute after that. Every 1 minute, a
Toast
will come onscreen with the current time value, even if the application is no longer running or in front of the user. When the user displays the activity and presses the Stop button, any pending alarms matching our PendingIntent are immediately canceled and will stop the flow of Toast
s.Precision alarm
What if we wanted to schedule an alarm to occur at a specific time? Perhaps exactly at 14:00? Setting
AlarmManager
with some slightly different parameters could accomplish this.This example uses an alarm that is referenced to real time. A determination is made whether the next occurrence of 14:00 will be today or tomorrow, and that value is returned as the trigger time for the alarm.
Starting in Android 4.4, the
AlarmManager
defaults all alarms to be inexact, meaning there is a small window within which they will trigger. Along with this new behavior, the setExact()
API method was added to allow developers to declare that the following alarm cannot fall within an inexact window. Prior to 4.4, simply calling set()
with the appropriate start time was sufficient.Setting alarms in Android API Level 23 and above
If our application targets an API level below 19 (KitKat), scheduled alarms will run exactly at the alarm time. For applications targeting KitKat or later, the schedule is considered inexact and the system may re-order or group alarms to minimize wake-ups and save battery.
After API Level 23, the Android Development team went a little further and Doze mode was introduced on the Android System to reduce battery consumption when the device is unplugged from the power adapter, motionless, and not used by the user for a long period of time.
Xamarin Android Alarmmanager Example
The Doze system will try to decrease the device's wake-up frequency deferring background jobs, network updates, syncs, and our precious alarm until the device exits Doze mode or a recurring maintenance window runs to execute pending jobs, certain alarms, or synchronization with the network. After the maintenance window finishes, the device would enter Doze mode again if it was not used in the meantime:
Doze mode is likely to impact your application and will defer your alarms until a maintenance window comes in, unless you use the methods
setAndAllowWhileIdle()
and setExactAndAllowWhileIdle()
to allow the execution of your alarms in a deep idle state.Moreover, the number of times that the Doze Mode maintenance window runs will be less frequent in cases of long-term inactivity, so the impact of this new mechanism on our scheduling will increase, hence causing more unpredictable jitters at the alarm time.
During the doze mode the applications are also not allowed to access the network, the WakeLocks are ignored and Wi-Fi scans are not executed.
If we need precision scheduling and you are targeting Marshmallow or later, we shall use the new
setExactAndAllowWhileIdle()
method introduced at API level 23:The Android system has protection that prevents abuse for exact alarms that fire off too frequently.
AlarmManager
only wakes up the device and dispatches one alarm per minute, and in low power mode it can be as low as one every 15 mins.If your application targets a version between KitKat (API Level 19) and Marshmallow (API Level 23), the
setExact
method is enough for timing precision:But we'll need to check that the methods exist before we try to call it; otherwise, our app will crash when run under earlier API levels. Lets sketch out our new exact alarm code:
This will deliver our alarm at exactly the specified time on all platforms.
Don't forget that you should only use exact scheduling when you really need it, for example, to deliver alerts to the user at a specific time. For most other cases, allowing the system to adjust our schedule a little to preserve battery life is usually acceptable.
Android Marshmallow API Level 23 also comes with the
setAndAllowWhileIdle
function, which allows us to create an alarm to sound in Doze mode, but with less exactness compared to setExactAndAllowWhileIdle()
.The system will try to batch these kinds of alarm across the entire system, minimizing the number of times the device wakes up, and hence reducing the energy consumption of the system. Here is the code to create an alarm that triggers, even in Doze mode, 10 hours from now:
In order to test your application's behavior in doze mode, the Android SDK team added some new commands to the
dumpsys
tool to manually change the device's power state from the command line.It is also important to remember that Doze mode requires that your device is unplugged from the charger. To force the device to a state where it is disconnected from the charger, we should run the following command on a command line with access to SDK Tools:
Then, to enter idle mode, we should turn off the screen and run the following commands:
After the device is put in idle mode, we can enable the maintenance window by running the following command:
If we run the same step again the device goes back to an idle state; however, if we want to go back to an active state, we should run the next command:
With these handy commands we are able to verify that the alarm sounds even in deep idle states.
Re-starting Alarm Service on device reboot
As discussed earlier, once an alarm service is started, it execute until it is explicitly stopped or until device reboots. This means that, if your device is restarted then your alarm is stopped. To avoid such situation, you have to restart your alarm service as soon as device boot completes. Below code snippet will help you to start alarm service once device reboots.
To start your alarm on device reboot, you have to register your above declared
DeviceBootReciever
class in your application manifest. This also need android.permission.RECEIVE_BOOT_COMPLETED
.How to check that alarm has been scheduled already or not?
Create an equivalent
PendingIntent
which you used with setRepeating()
with PendingIntent.FLAG_NO_CREATE
flag.Intent intent = new Intent(context, WidgetUpdateReceiver.class);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_NO_CREATE);
While using
PendingIntent.FLAG_NO_CREATE
, if the described PendingIntent
does not already exists, it simply return null
.How to get WakeLock
WAKE_LOCK
permission is required because the wake lock is being used while processing in onReceive()
method present in BroadcastReceiver
class.Example of WakeLock for
BroadcastReceiver
.List all alarms in device
You can know the alarm has been set and when are they going to alarmed and interval. Also how many times this alarm has been invoked.
Job Scheduler
AlarmManager
is a great candidate for scheduling if an application needs to perform a local event at an exact time or inexact interval. Alarm clock or reminder applications are great examples for AlarmManager
usage. However, the documentation discourages using AlarmManager
for scheduling network-related tasks. For this tasks you can use JobScheduler which is an API for scheduling various types of jobs against the framework that will be executed in your application's own process.This example is suited for repeating alarm at certain interval (e.g. hourly, daily, etc) but doesn’t gurantee accuracy of repeating time (e.g. 9am daily). Refer to Caveats of Repeating Alarm.
Usage
NOTES:
PendingIntent.FLAG_CANCEL_CURRENT
to make sure only 1 alarm is created/overwritten no matter how many timesstartAlarm
is called- setInexactRepeating: The 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.
triggerAtMillis
indicate when is the first time it should triggered. If the time has passed, it might trigger immediately.triggerAtMillis
is in GMT/UTC
Caveats of Repeating Alarm
If an alarm is delayed (by system sleep, for example, for non
_WAKEUP
alarm types), a skipped repeat will be delivered as soon as possible. After that, future alarms will be delivered according to the original schedule; they do not drift over time. For example, if you have set a recurring alarm for the top of every hour but the phone was asleep from 7:45 until 8:45, an alarm will be sent as soon as the phone awakens, then the next alarm will be sent at 9:00.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.
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, android.app.PendingIntent) and setExact(int, long, android.app.PendingIntent).
It seems as of
API 19 (Android 4.4 - KitKat)
, calling setRepeating
is same as setInexactRepeating
. It is suitable for job that repeats within a certain interval (hourly, daily, etc.), but doesn’t need to execute at the exact time (e.g. 9am every day). I believe the repeating alarm will drift (as setRepeating
behaviour is inexact as of API 19), as in the following sequence might occur- Day 1: 9am
- Day 2: 9.05am
- Day 3: 9.30am
- Day 4: 10am
- Day 5: 10am
- Day 6: 11.30am
If you need to repeat at specific time daily (e.g. 9am every day), use setExact or setWindow (allow slight delay as per the window specified, but more energy efficient). If you need extreme accuracy (e.g. Alarm Clock) and execute even though the system is in low-power idle modes, use setExactAndAllowWhileIdle. Ubar 4 0 6 – the dock replacement.
You have to program the repetition part yourself, set the next alarm again after the current alarm is triggered at
onReceive
.Refer to Daily Repeating Alarm/Reminder at Specific Time With AlarmManager.
Set Alarm Timing Example
Example: trigger once immediately.
Example: trigger once 5 minutes later.
Example: trigger once every 5 minutes
AndroidManifest.xml
Edit
AndroidManifest.xml
.NOTE: The
AlarmManager
Records 1 5 10 – innovative personal database software. won’t survive a device reboot. You have to implement a device bootup receiver and call ReminderReceiver.startAlarm(context)
.NOTE: Refer Setup Android Notification.
NOTE: To support multiple alarm, use a different
requestCode
for each alarm. Refer Android AlarmManager: Multiple Alarm With Arguments/Parameters.NOTE: AlarmManager is removed when the app is uninstalled, and it seems the Alarm is cancelled after APK update (not sure if this is true or always true).
References:
Buy me a coffee☕ or support my work to keep this space ? and ad-free.
If you can't, do send some ? to @d_luaz or help to share this article.
If you can't, do send some ? to @d_luaz or help to share this article.
Pixtory App (Alpha) - easily organize photos on your phone into a blog.
COVID-19 - data, chart, information & news.
暖心芽 (WIP) ?❤️? - reminder of hope, warmth, thoughts and feelings.
Travelopy - travel discovery and journal
LuaPass - offline password manager
WhatIDoNow - a public log of things I am working on now
COVID-19 - data, chart, information & news.
暖心芽 (WIP) ?❤️? - reminder of hope, warmth, thoughts and feelings.
Travelopy - travel discovery and journal
LuaPass - offline password manager
WhatIDoNow - a public log of things I am working on now
Android Alarmmanager Example
A dream boy who enjoys making apps, travelling and gardening. Follow me on @d_luaz.