Android 14 Behavior Change: Schedule exact alarms are denied by default

Carter Chen

--

Android 14 introduces several cool new features and behavior changes.

Among them, the schedule exact alarms are denied by default is a significant change, which I believe is quite important. This article will focus on exploring this issue.

Keywords

We often need to schedule precise alarms to trigger tasks, such as sending reminders at specific times (e.g., calendar events) or alerting users a few minutes before an event (e.g., shopping APP shopping events, train APP notifications).

These situations require setting up exact alarms. If your task needs to be triggered at an exact time, you should be familiar with the following keywords or APIs:

It all started with Android 12 (Android S)

Android 12 introduced the SCHEDULE_EXACT_ALARM permission for the first time. Starting from Android 12, whenever you want to set exact alarms, you must add the following line to your AndroidManifest.xml:

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

Otherwise, when you call setExact(), the system will throw a SecurityException.

Hence, the most straightforward approach for Android 12 is to incorporate the SCHEDULE_EXACT_ALARM permission. Given that the system grants this permission by default, users are unlikely to be aware of or inclined to disable the exact alarm permission, as long as they comply. (In the rare event of it being disabled, don’t worry, we will later discuss best practices for addressing this situation)

What about Android 14 and beyond?

The Android official docs states that the permission for exact alarms will be default-off in several scenarios:

  • Targets Android 13 (API level 33) or higher.
  • Declares the SCHEDULE_EXACT_ALARM permission in the manifest.
  • Doesn’t fall under an exemption or pre-grant scenario.
  • Isn’t a calendar or alarm clock app.

However, the official announcement also states that, if you want to publish your app on Google Play, starting from August 31, 2023, the app’s targetSdkVersion must specify Android 13 (API level 33) or higher.

Doesn’t this signify that every developer must make the necessary adjustments to comply with Android 14?

Indeed! Developers who depend on exact alarms must ensure they adapt to this change.

If you want to determine whether your app is affected, you can refer to the following cheat sheet for a quick check:

Best Practices for Scheduling Exact Alarms

What am I supposed to do? Well, no need to worry too much because Google is here to guide us and has provided a Best Practice:

val alarmManager: AlarmManager = context.getSystemService<AlarmManager>()!!
when {
alarmManager.canScheduleExactAlarms() -> {
alarmManager.setExact(...)
}
else -> {
...
}
}
  • In case your app doesn’t have the permission initially, you can use an Intent with the ACTION_REQUEST_SCHEDULE_EXACT_ALARM action to trigger the permission activation page and enable it.
startActivity(Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM))
  • Remember to register the ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED broadcast in advance. If you receive this action, it means that the user has enabled the SCHEDULE_EXACT_ALARM permission. Then, you can proceed to handle the relevant UI or dialog display or hiding.
class MyBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED) {
...
}
}
}

Alternative Solution: Third-party Library AlarmScheduler

Considering that SCHEDULE_EXACT_ALARM and canScheduleExactAlarms() were introduced after Android 12, maintaining a production app can be challenging when users are spread across various Android versions, including Android 14, 13, 12, 11, and even older ones. Adapting your Android app to multiple versions can indeed be a headache 😥.

If you’re looking to simplify the hassle of backward compatibility, you might want to give our open-source library, AlarmScheduler, a try ❤️

dependencies {
implementation 'com.carterchen247:alarm-scheduler:x.x.x'
}

AlarmScheduler’s mission is to offer developers the best development experience when it comes to setting precise alarms. It provides a user-friendly API while also taking into account backward compatibility and adaptation to various Android versions.

Scheduling Exact Alarms

You can schedule your first precise alarm with ease using AlarmScheduler.schedule(config) :

val config = AlarmConfig(
triggerTime = Date().time + 10000L,
type = 1
) {
dataPayload("reminder" to "have a meeting")
}

AlarmScheduler.schedule(config)

Defining AlarmTask Types

By utilizing the custom AlarmTask interface, you can specify different alarm tasks. When the alarm triggers, it will invoke the onAlarmFires callback:

class DemoAlarmTask : AlarmTask {

companion object {
const val TYPE = 1
}

override fun onAlarmFires(alarmId: Int, dataPayload: DataPayload) {
// trigger here
}
}

Error Handling

You can also include an additional callback when calling AlarmScheduler.schedule(config), allowing us to handle the outcome of the scheduling accordingly:

AlarmScheduler.schedule(config) { result ->
when (result) {
is ScheduleResult.Success -> {
// do your stuff
}
is ScheduleResult.Failure -> {
// handle error
when (result) {
ScheduleResult.Failure.CannotScheduleExactAlarm -> {
// ...
}
is ScheduleResult.Failure.Error -> {
// ...
}
}
}
}
}

Encapsulated Schedule Exact Alarm Permission Page Navigation

The logic for navigating to the Schedule Exact Alarm permission page on Android 12 and above has been encapsulated as an extension function:

fun Activity.openExactAlarmSettingPage() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
startActivity(
Intent(
Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM,
Uri.parse("package:$packageName")
)
)
}
}

Schedule Exact Alarm Permission User Consent Event Listening

You can detect whether users have granted Schedule Exact Alarm permission by using AlarmSchedulerEventObserver. This allows us to manage subsequent UI and dialog display/hiding:

AlarmSchedulerEventObserver { event ->
if (event is ScheduleExactAlarmPermissionGrantedEvent) {
// do your stuff
}
}

Conclusion

That’s about it! This article provided an overview of the behavior changes in Android 14 regarding exact alarms, along with relevant considerations and solutions.

While it’s true that every year brings its share of behavior changes and adjustments, I believe that both Android’s official team and developers share a common goal: to continually improve the user experience.

Our collective efforts are ultimately driven by the desire to bring joy and satisfaction to our users. As long as our users are delighted with the results, all the hard work becomes truly worthwhile.

Happy coding ❤️

References

--

--

Responses (1)