Everything you need to know about Alarm permissions in Android
Table of Contents
There are 2 types of alarm that you can set in your app, it can either be an inexact alarm or an exact alarm. This totally depends on the use-case your app is targeting. But in most cases, it’s recommended that you create an inexact alarm unless the functionality of your app depends precisely timed alarm.
Using an exact alarm
If your app needs to perform certain operations that are time-sensitive and have to be executed at a precise time then it is okay to use an exact alarm. Otherwise, an inexact alarm should be sufficient to cater the most of the common use cases such as scheduling a background sync or log upload
When the system triggers an exact alarm, it results in consuming a great deal of system resources so one has to be cautious while making use of an exact alarm. Common use cases where an exact alarm is required are an alarm clock app or a calendar app
Use-cases that can be addressed using an exact alarm
- Showing a time-based notification for a calendar event
- Developing an alarm or calendar app
Ways to set an exact alarm
setExact()
: UsesetExact()
when you want your alarm to be triggered at a nearly precise time in the future. Note that this will still be impacted by the state battery-saving restrictions on the device. If your app’s work is time crtical, consider usingsetExactAndAllowWhileIdle()
setExactAndAllowWhileIdle()
: Invoke an alarm at a nearly precise time in the future, even if battery-saving measures are in effectsetAlarmClock()
: Schedule an alarm that represents an alarm clock. This will cause the device to fully wake the device up causing the screen to turn on, play a sound, vibrate, etc. These alarms will be allowed to trigger even if the system is in a low-power idle (a.k.a. doze) mode
Permissions required:
If you are making use of an exact alarm, you need to declare either of the 2 permissions: SCHEDULE_EXACT_ALARM
or USE_EXACT_ALARM
. Your app should use exact alarms, and declare either SCHEDULE_EXACT_ALARM
or USE_EXACT_ALARM
permission, only if a user-facing function in your app requires precisely-timed actions.
If your app targets Android 12 or above, you must obtain the “Alarms & reminders” special app access. To do so, declare the SCHEDULE_EXACT_ALARM
permission in your app’s manifest file, as shown below:
<manifest ...> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
For apps targeting Android 13 and above, you have the choice to declare either the SCHEDULE_EXACT_ALARM
or the USE_EXACT_ALARM
permission.
<manifest ...> <uses-permission android:name="android.permission.USE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
While both the permissions look similar, they are designed to support different use-cases. Check the details below:
Using USE_EXACT_ALARM permission:
USE_EXACT_ALARM is a restricted permission that is granted automatically. Since this permission is a restricted permission, apps that request this restricted permission are subject to review, and those that do not meet the acceptable use case criteria will be disallowed from publishing on Google Play. Here’s what is mentioned in the Google policies:
Your app must use the USE_EXACT_ALARM functionality only when your app’s core, user facing functionality requires precisely-timed actions, such as:
https://support.google.com/googleplay/android-developer/answer/9888170?sjid=10510309997098831402-AP
- The app is an alarm or timer app.
- The app is a calendar app that shows event notifications.
If you have a use case for exact alarm functionality that’s not covered above, you should evaluate if using SCHEDULE_EXACT_ALARM as an alternative is an option.
Using SCHEDULE_EXACT_ALARM permission
Unlike, the SCHEDULE_EXACT_ALARM
permission must be granted by the user. System or User can revoke this permission at any point in time. Use canScheduleExactAlarms()
method to check whether the permission is granted to your app or not. On revoking the permission, all the future exact alarms will get canceled.
If canScheduleExactAlarms() returns false
, You can take the users to the “Alarms & reminders” special app access screen in system settings where they can provide this special access to our app.
val alarmManager: AlarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager when { alarmManager.canScheduleExactAlarms() -> { // permission granted } else -> { // open alarm permission screen Intent().apply { action = ACTION_REQUEST_SCHEDULE_EXACT_ALARM }.also { startActivity(it) } } }
When the SCHEDULE_EXACT_ALARMS
permission is granted to your app, the system sends it the ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
broadcast. Implement a broadcast to listen to the state change and perform further actions. The system does not send the broadcast when permission is revoked
Also always make sure to check the current alarm permission state with the broadcast receiver before performing any action. It is important as this check protects your app from the case where the user grants your app permission, and then revokes it almost immediately afterward.
class AlarmReceiver : BroadcastReceiver() { private val TAG = "AlarmReceiver" override fun onReceive(context: Context, intent: Intent) { val alarmManager: AlarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager when (intent.action) { ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED -> { if(alarmManager.canScheduleExactAlarms()) // Permission granted } "from alarm" -> { // Alarm fired } } } }
Using an inexact Alarm
When using an inexact alarm, the system invokes the alarm at some point in the future. Although it is not guaranteed to get the alarm delivered at the exactly requested time, an inexact alarm provides some guarantee regarding the timing of alarm delivery while respecting battery-saving restrictions. On Android 12 and above, the system invokes the alarm within one hour of the requested trigger time, unless battery-saving restrictions are on.
Inexact alarms help in conserving the device’s resources as the system can batch these requests and optimize resource utilization.
Use-cases that can be addressed using inexact alarm:
- Your app needs to upload logs or sync the data with the backend. These operations do not have to be time-critical or precisely timed. You can either make use of AlarmManager’s
set()
/setAndAllowWhileIdle()
or WorkManager - You need to perform some action during a certain time window in the future. This can be done using
setWindow()
. If your app targets Android 12 or above, the smallest allowed window length is 10 minutes.
Ways to set an inexact alarm
- Trigger an alarm after a specific time
An alarm can be triggered after a specific time usingset()
,setInexactRepeating()
, orsetAndAllowWhileIdle()
methods. On Android 12 and above, the system invokes the alarm within one hour of the requested trigger time, unless battery-saving restrictions are in effect. - Trigger an alarm during a time window
setWindow()
can be used to trigger an alarm during a time window. If your app targets Android 12 or above, the system can delay the delivery of a time-windowed inexact alarm by at least 10 minutes. Because of this,windowLengthMillis
parameter values below600000
are clipped to600000
Millis
Permissions required
No permission is required to set an inexact alarm
Example
private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) } alarmMgr?.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent )
I hope this article helps you in implementing alarm permissions correctly. If it does, please leave a comment below.
I am not sure where you’re getting your information, but great topic.
Hi Bryan,
I hope this post helped you in getting a better understanding of Alarms. i am glad you liked it.
Thank you, it helped me a lot.
Thank you, it helped me a lot.
Thanks. I am glad it helped.