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.
To be able to see the “special app access” permission, you will have to scroll down further.
In this tutorial, we will learn how to work with the SCHEDULE_EXACT_ALARM
permission in the following scenarios:
- How to check for permission.
- How to request for the permission.
Goals
At the end of the tutorial, you would have learned:
- How to check for
SCHEDULE_EXACT_ALARM
permission. - How to request for the
SCHEDULE_EXACT_ALARM
permission.
Tools Required
- Android Studio. The version used in this tutorial is Android Studio Dolphin | 2021.3.1 Patch 1.
Prerequisite Knowledge
- Intermediate Android.
- Basic permissions.
Project Setup
To follow along with the tutorial, perform the steps below:
-
Create a new Android project with the default Empty Activity.
-
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.
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.