A
special permission
guards access to system resources that are particularly
sensitive or not directly related to user privacy. These permissions are
different than
install-time
permissions
and
runtime
permissions
.
Some examples of special permissions include:
- Scheduling exact alarms.
- Displaying and drawing over other apps.
- Accessing all storage data.
Apps that declare a special permission are shown in the
Special app access
page in system settings (figure 1). To grant a special permission to the app, a
user must navigate to this page:
Settings > Apps > Special app access
.
Workflow
To request a special permission, do the following:
- In your app's manifest file,
declare the special
permissions
that your app might need to
request.
- Design your app's UX so that specific actions in your app are associated
with specific special permissions. Let users know which actions might
require them to grant permission for your app to access private user data.
- Wait for the user
to invoke
the task or action in your app that requires access to specific private user
data. At that time, your app can request the special permission that's
required for accessing that data.
- Check whether the user has already granted the special permission that your
app requires. To do so, use each permission's
custom checking
function
. If granted, your app can access the private user
data. If not, continue to the next step. Note: You must check whether you
have the permission every time you perform an operation that requires that
permission.
- Present a rationale
to the user in a UI element that clearly
explains what data your app is trying to access and what benefits the app
can provide to the user if they grant the special permission. In addition,
since your app sends users to system settings to grant the permission, also
include brief instructions that explain how users can grant the permission
there. The rationale UI should provide a clear option for the user to
opt-out of granting the permission. After the user acknowledges the
rationale, continue to the next step.
- Request the special permission
that your app requires to access
the private user data. This likely involves an intent to the corresponding
page in system settings where the user can grant the permission. Unlike
runtime permissions
, there is
no popup permission dialog.
- Check the user's response ? whether they chose to grant or deny the special
permission ? in the
onResume()
method.
- If the user granted the permission to your app, you can access the private
user data. If the user denied the permission instead,
gracefully degrade
your app experience
so that
it provides functionality to the user without the information that's
protected by that permission.
Request special permissions
Unlike
runtime permissions
, the
user must grant special permissions from the
Special App Access
page in
system settings. Apps can send users there using an intent, which pauses the app
and launches the corresponding settings page for a given special permission.
After the user returns to the app, the app can check if the permission has been
granted in the
onResume()
function.
The following sample code shows how to request the
SCHEDULE_EXACT_ALARMS
special permission from users:
val alarmManager = getSystemService<AlarmManager>()!!
when {
// if permission is granted, proceed with scheduling exact alarms…
alarmManager.canScheduleExactAlarms() -> {
alarmManager.setExact(...)
}
else -> {
// ask users to grant the permission in the corresponding settings page
startActivity(Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM))
}
}
Sample code to check the permission and handle user decisions in
onResume()
:
override fun onResume() {
// ...
? ?if (alarmManager.canScheduleExactAlarms()) {
? ? ? ?// proceed with the action (setting exact alarms)
? ? ? ?alarmManager.setExact(...)
? ?}
? ?else {
? ? ? ?// permission not yet approved. Display user notice and gracefully degrade
? ? ? ?your app experience.
? ? ? ?alarmManager.setWindow(...)
? ?}
}
Best practices and tips
The following sections provide some best practices and considerations when
requesting special permissions.
Each permission has its own check method
Special permissions operate differently than
runtime
permissions
. Instead,
refer to the
permissions API reference
page
and use the custom access check
functions for each special permission. Examples include
AlarmManager#canScheduleExactAlarms()
for the
SCHEDULE_EXACT_ALARMS
permission and
Environment#isExternalStorageManager()
for the
MANAGE_EXTERNAL_STORAGE
permission.
Request in-context
Similar to runtime permissions, apps should request special permissions
in-context when the user requests a specific action that requires the
permission. For example, wait to request the
SCHEDULE_EXACT_ALARMS
permission
until the user schedules an email to be sent at a specific time.
Explain the request
Provide a rationale before redirecting to system settings. Since users leave the
app temporarily to grant special permissions, show an in-app UI before you
launch the intent to the
Special App Access
page in system settings. This UI
should clearly explain why the app needs the permission and how the user should
grant it on the settings page.