请求特殊权限

特殊权限保护对系统资源的访问,这些资源特别敏感或与用户隐私没有直接关系。这些权限与安装时权限运行时权限不同。

图 1:系统设置中的特殊应用访问屏幕。

特殊权限的一些示例包括:

  • 安排精确警报。
  • 显示和绘制在其他应用之上。
  • 访问所有存储数据。

声明特殊权限的应用显示在系统设置中的特殊应用访问页面(图 1)。要向应用授予特殊权限,用户必须导航到此页面:设置 > 应用 > 特殊应用访问

工作流程

要请求特殊权限,请执行以下操作:

  1. 在您的应用清单文件中,声明您的应用可能需要请求的特殊权限
  2. 设计您的应用 UX,以便应用中的特定操作与特定特殊权限相关联。让用户知道哪些操作可能需要他们授予您的应用访问私人用户数据的权限。
  3. 等待用户调用应用中需要访问特定私人用户数据的任务或操作。此时,您的应用可以请求访问该数据所需的特殊权限。
  4. 检查用户是否已授予您的应用所需的特殊权限。为此,请使用每个权限的自定义检查函数。如果已授予,您的应用可以访问私人用户数据。如果没有,请继续执行下一步。注意:每次执行需要该权限的操作时,都必须检查您是否具有该权限。
  5. 向用户呈现理由说明,在UI元素中清晰地解释您的应用尝试访问哪些数据,以及如果用户授予特殊权限,应用可以为用户提供哪些好处。此外,由于您的应用会将用户引导至系统设置以授予权限,因此还应包含简短说明,解释用户如何在系统设置中授予权限。理由UI应为用户提供明确的选项,以便选择不授予权限。用户确认理由后,继续执行下一步。
  6. 请求您的应用访问私有用户数据所需的特殊权限。这可能涉及到对系统设置中相应页面的意图,用户可以在该页面授予权限。与运行时权限不同,没有弹出式权限对话框。
  7. onResume()方法中检查用户的响应——他们选择授予还是拒绝特殊权限。
  8. 如果用户向您的应用授予了权限,您可以访问私有用户数据。如果用户拒绝了权限,则优雅地降低应用体验,以便在没有受该权限保护的信息的情况下为用户提供功能。
图2:在Android上声明和请求特殊权限的工作流程。

请求特殊权限

运行时权限不同,用户必须从系统设置中的特殊应用访问页面授予特殊权限。应用可以使用意图将用户引导至该页面,这会暂停应用并启动给定特殊权限的相应设置页面。用户返回应用后,应用可以在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应清晰地解释应用为何需要该权限以及用户如何在设置页面授予该权限。