Androive Native - Handle Exact Alarm Permissions On Android 12+

dimitrilc 1 Tallied Votes 267 Views Share

Introduction

In a previous tutorial, we learned how to set an exact alarm. A permission called SCHEDULE_EXACT_ALARM was used in that tutorial. Initially, I thought that it was only a normal install-time permission, but I have recently found out that this specific permission also belongs to a rare type of permission called special app access permission.

“Special app access” permissions do not usually work like other permission types (how to request, revoke, other specific behaviors). It is also hard to find in the Android Settings. Let us use the Clock app for example. In the following screenshot, it does not show alarm as a permission.

Screenshot_2022-11-09_at_12.44.05_PM.png

To be able to see the “special app access” permission, you will have to scroll down further.

Screenshot_2022-11-09_at_12.45.34_PM.png

In this tutorial, we will learn how to work with the SCHEDULE_EXACT_ALARM permission in the following scenarios:

  1. How to check for permission.
  2. How to request for the permission.

Goals

At the end of the tutorial, you would have learned:

  1. How to check for SCHEDULE_EXACT_ALARM permission.
  2. How to request for the SCHEDULE_EXACT_ALARM permission.

Tools Required

  1. Android Studio. The version used in this tutorial is Android Studio Dolphin | 2021.3.1 Patch 1.

Prerequisite Knowledge

  1. Intermediate Android.
  2. Basic permissions.

Project Setup

To follow along with the tutorial, perform the steps below:

  1. Create a new Android project with the default Empty Activity.

  2. Declare the permission below in the manifest.

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

Check For SCHEDULE_EXACT_ALARM Permission

Checking for the SCHEDULE_EXACT_ALARM permission works a bit differently than checking for other types of permission.

First, let us use the regular way to check for permission with SCHEDULE_EXACT_ALARM and see why this does not work. You can replace the code in MainActivity.kt with the code below.

private const val TAG = "MAIN_ACTIVITY"

class MainActivity : AppCompatActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
           checkScheduleExactAlarmPermWrongWay()
       }
   }

   @RequiresApi(Build.VERSION_CODES.S)
   private fun checkScheduleExactAlarmPermWrongWay(){
       val isGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.SCHEDULE_EXACT_ALARM)
       Log.d(TAG, "Has permission? ${isGranted == PERMISSION_GRANTED}")
   }
}

In Logcat, use the filter below to see the output.

level:debug MAIN_ACTIVITY

Upon first install, the code prints:

2022-11-09 14:45:45.602  6487-6487  MAIN_ACTIVITY           com...exactalarmpermissionandroid12  D  Has permission? True

This is correct because the app is granted the permission upon install.

Screenshot_2022-11-09_at_2.48.07_PM.png

The problem here is that the code will also print true even when the permission is off.

If you turn this permission off while the app is active, the app will close. This is expected behavior. This behavior ensures that your permission checker (that we will learn later) is valid for the lifetime of the app.

With the permission turned off, launch the app again and observer the output.

2022-11-09 14:54:35.236  7445-7445  MAIN_ACTIVITY           com...exactalarmpermissionandroid12  D  Has permission? True

It still prints true! The app also did not crash (I wished it did, so that developers are not caught off guard by this).

Now it is time to properly check for the permission. To check for the SCHEDULE_EXACT_ALARM permission, we will have to use the method canScheduleExactAlarms() from the AlarmManager class.

@RequiresApi(Build.VERSION_CODES.S)
private fun checkScheduleExactAlarmPermCorrectWay(){
   val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
   Log.d(TAG, "Has permission (correct method)? ${alarmManager.canScheduleExactAlarms()}")
}

If we run the code with both the wrong and correct methods,

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
   checkScheduleExactAlarmPermWrongWay()
   checkScheduleExactAlarmPermCorrectWay()
}

We can then see that the output prints false properly for the correct method.

2022-11-09 15:29:54.019  7871-7871  MAIN_ACTIVITY           com...exactalarmpermissionandroid12  D  Has permission? true
2022-11-09 15:29:54.019  7871-7871  MAIN_ACTIVITY           com...exactalarmpermissionandroid12  D  Has permission (correct method)? False

Requesting SCHEDULE_EXACT_ALARM Permission

Because SCHEDULE_EXACT_ALARM is a special app access permission, our only option is to explain to the user in our UI why the permission is needed, then, finally, send the user to the permission toggle page with an Intent and the Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM action.

The code below demonstrates how this can be done.

val alarmPermissionIntent = Intent(
   Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM,
   Uri.parse("package:com.hoang.daniwebexactalarmpermissionandroid12")
)
startActivity(alarmPermissionIntent)

You are recommended to provide the Uri for your app package, so that the user is sent directly to the correct page.

Summary

Congratulations! We have learned how to work with the special app access permission SCHEDULE_EXACT_ALARM in this tutorial. The full project code can be found at https://github.com/dmitrilc/DaniwebExactAlarmPermissionAndroid12.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.