Exact Alarms
Exact alarms are alarms that will be invoked at a precise moment in the future.
Exact Alarm Permissions​
Before using exact alarms in your application, you need to declare one of these two permissions:
Depending on your application's use cases, you should only declare either one of them.
SCHEDULE_EXACT_ALARM
Permission​
You should use SCHEDULE_EXACT_ALARM
permission if:
- Your application targets API level 31 (or above).
- Your application only uses exact alarms for secondary features, not core functionality.
SCHEDULE_EXACT_ALARM
permission has these characteristics:
- Before Android 14 (API level 34), this permission is granted by default. On Android 14 and above, this permission is no-longer being pre-granted to most newly installed apps targeting Android 13 and higher.
- There is a setting page where user can grant/revoke this permission. Read more about this setting page here.
- There is a dedicated method where you can check whether user has granted this permission. Read more about this here.
- You can listen to a broadcast whenever this permission state is changed. Read more about this here.
Basic Usages​
Opening SCHEDULE_EXACT_ALARM
Setting Page​
There is a dedicated setting page for user to toggle SCHEDULE_EXACT_ALARM
permission. To access this page, navigate to Settings > Apps > Special app access > Alarm & reminders. Or you can programmatically open this page by using ACTION_REQUEST_SCHEDULE_EXACT_ALARM
intent action:
import android.content.Context
import android.content.Intent
import android.os.Build
import android.provider.Settings
import androidx.core.content.ContextCompat.startActivity
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
startActivity(
context,
Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM),
null,
)
}
If we want to access our app's setting page directly, we can add our application package's URI to the intent:
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.core.content.ContextCompat.startActivity
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
startActivity(
context,
Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).apply {
data = Uri.parse("package:${context.packageName}")
},
null,
)
}
Checking Whether User Has Granted SCHEDULE_EXACT_ALARM
Permission​
You can check whether user has granted SCHEDULE_EXACT_ALARM
permission for your application by using canScheduleExactAlarms()
method:
import android.app.AlarmManager
import android.content.Context
import android.os.Build
import android.util.Log
val alarmManager = context.getSystemService(AlarmManager::class.java)
val canSchedule = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
alarmManager.canScheduleExactAlarms()
} else {
null
}
Log.i("TAG", canSchedule.toString())
Listening Whenever SCHEDULE_EXACT_ALARM
Permission State Changes​
You can listen to a broadcast whenever SCHEDULE_EXACT_ALARM
permission is being granted (not revoked) by using ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
intent action.
Here is a simple broadcast receiver class that listens to the intent action:
package com.hanmajid.androidnotebook
import android.app.AlarmManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
/**
* Simple broadcast receiver that listens to [AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED]
* intent action.
*/
class ScheduleExactAlarmPermissionStateChangedBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED) {
val alarmManager = context.getSystemService(AlarmManager::class.java)
val canSchedule = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
alarmManager.canScheduleExactAlarms()
} else {
null
}
Log.i("TAG", canSchedule.toString())
}
}
}
Then you can register the broadcast receiver in your Context or AndroidManifest.xml
file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<receiver
android:name=".ScheduleExactAlarmPermissionStateChangedBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" />
</intent-filter>
</receiver>
</application>
</manifest>