特殊权限保护对系统资源的访问,这些资源特别敏感或与用户隐私没有直接关系。这些权限不同于安装时权限和运行时权限。
特殊权限的一些示例包括
- 计划精确警报。
- 显示和绘制在其他应用之上。
- 访问所有存储数据。
声明特殊权限的应用显示在系统设置中的特殊应用访问页面(图 1)中。要向应用授予特殊权限,用户必须导航到此页面:设置 > 应用 > 特殊应用访问。
工作流
要请求特殊权限,请执行以下操作
- 在应用的清单文件中,声明应用可能需要请求的特殊权限。
- 设计应用的 UX,以便应用中的特定操作与特定的特殊权限相关联。让用户了解哪些操作可能需要他们授予应用访问私人用户数据的权限。
- 等待用户在应用中调用需要访问特定私人用户数据的任务或操作。此时,应用可以请求访问该数据所需的特殊权限。
- 检查用户是否已授予应用所需的特殊权限。为此,请使用每个权限的自定义检查函数。如果已授予,则应用可以访问私人用户数据。否则,继续执行下一步。注意:每次执行需要该权限的操作时,都必须检查您是否拥有该权限。
- 提供理由,在 UI 元素中清楚地解释应用尝试访问哪些数据以及如果用户授予特殊权限,应用可以为用户提供哪些好处。此外,由于应用会将用户发送到系统设置以授予权限,因此还应包含简要说明,说明用户如何在其中授予权限。理由 UI 应为用户提供明确的选择,以便他们选择不授予权限。在用户确认理由后,继续执行下一步。
- 请求应用访问私人用户数据所需的特殊权限。这可能涉及到系统设置中相应页面的意图,用户可以在其中授予权限。与运行时权限不同,没有弹出权限对话框。
- 在
onResume()
方法中检查用户的响应——他们是否选择授予或拒绝特殊权限。 - 如果用户授予您的应用权限,您可以访问用户的私有数据。如果用户拒绝了权限,则优雅地降低您的应用体验,以便它在没有受该权限保护的信息的情况下为用户提供功能。
请求特殊权限
与运行时权限不同,用户必须从系统设置中的“特殊应用访问”页面授予特殊权限。应用可以使用意图将用户发送到该页面,这会暂停应用并启动给定特殊权限的相应设置页面。用户返回应用后,应用可以在 onResume()
函数中检查权限是否已授予。
以下示例代码演示了如何向用户请求SCHEDULE_EXACT_ALARMS
特殊权限
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))
}
}
检查权限并在 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(...)
}
}
最佳实践和提示
以下部分提供了一些在请求特殊权限时应遵循的最佳实践和注意事项。
每个权限都有自己的检查方法
特殊权限与运行时权限的工作方式不同。相反,请参考权限 API 参考页面,并使用每个特殊权限的自定义访问检查函数。例如,AlarmManager#canScheduleExactAlarms()
用于SCHEDULE_EXACT_ALARMS
权限,Environment#isExternalStorageManager()
用于MANAGE_EXTERNAL_STORAGE
权限。
在上下文中请求
与运行时权限类似,应用应在用户请求需要该权限的特定操作时,在上下文中请求特殊权限。例如,等到用户安排在特定时间发送电子邮件时,再请求SCHEDULE_EXACT_ALARMS
权限。
解释请求
在重定向到系统设置之前提供理由。由于用户暂时离开应用以授予特殊权限,因此在启动到系统设置中“特殊应用访问”页面的意图之前,请显示应用内 UI。此 UI 应清楚地解释应用为何需要该权限以及用户如何在设置页面上授予该权限。