应用权限最佳实践

权限请求保护设备上可用的敏感信息,并且仅在应用运行需要访问这些信息时才应使用。本文档提供了如何在无需访问此类信息的情况下实现相同(或更好)功能的技巧;这并非对 Android 操作系统中权限工作原理的详尽讨论。

有关 Android 权限的更一般性说明,请参阅权限概览。有关如何在代码中使用权限的详细信息,请参阅请求应用权限

Android 6.0+ 中的权限

在 Android 6.0(API 级别 23)及更高版本中,应用可以在运行时(而不是安装前)向用户请求权限。这使得应用可以在实际需要服务或服务保护的数据时请求权限。虽然这不会(必然)改变应用的整体行为,但它确实对敏感用户数据的处理方式产生了一些相关变化。

增加情境上下文

用户在运行时,在您的应用上下文中,会被提示授予访问这些权限组涵盖功能的权限。用户对请求权限的上下文更加敏感,如果您的请求与应用目的之间存在不匹配,则向用户提供详细解释为何请求该权限就变得更加重要。在可能的情况下,您应该在请求时和用户拒绝请求后的后续对话框中都提供请求的解释。

为了增加权限请求被接受的可能性,仅在需要特定功能时才进行提示。例如,仅当用户点击麦克风按钮时才提示访问麦克风。用户更有可能允许他们期望的权限。

授予权限的更大灵活性

用户可以在请求时在设置中拒绝访问单个权限,但当功能因此损坏时,他们可能仍会感到惊讶。最好监控有多少用户正在拒绝权限(例如使用 Google Analytics),以便您可以重构您的应用以避免依赖该权限,或者更好地解释为什么您的应用需要该权限才能正常工作。您还应该确保您的应用在用户拒绝权限请求或在设置中关闭权限时处理异常。

增加的事务负担

用户被要求单独授予权限组的访问权限,而不是作为一组。这使得最小化您请求的权限数量变得极其重要。这增加了用户授予权限的负担,因此增加了至少一个请求被拒绝的可能性。

需要成为默认处理程序的权限

某些应用依赖于访问与通话记录和短信相关的敏感用户信息。如果您想请求通话记录和短信相关的权限并将您的应用发布到 Play 商店,您必须在请求这些运行时权限之前提示用户将您的应用设置为核心系统功能的默认处理程序

有关默认处理程序的更多信息,包括向用户显示默认处理程序提示的指南,请参阅仅在默认处理程序中使用的权限指南

了解您正在使用的库

有时,您在应用中使用的库需要权限。例如,广告和分析库可能需要访问 LOCATION 权限组以实现所需功能。但从用户的角度来看,权限请求来自您的应用,而不是库。

正如用户会选择使用相同功能但所需权限更少的应用一样,开发者也应该审查他们使用的库,并选择不使用不必要权限的第三方 SDK。例如,如果您正在使用提供位置功能的库,请确保除非您正在使用基于位置的定位功能,否则不要请求 FINE_LOCATION 权限。

限制后台位置访问

当您的应用在后台运行时,位置访问应该对应用的核心功能至关重要,并对用户显示明确的益处。

测试两种权限模型

在 Android 6.0(API 级别 23)及更高版本中,用户在运行时授予和撤销应用权限,而不是在安装应用时执行此操作。因此,您将不得不在更广泛的条件下测试您的应用。在 Android 6.0 之前,您可以合理地假设,只要您的应用正在运行,它就拥有在应用清单中声明的所有权限。现在,用户可以针对任何应用开启或关闭权限,无论 API 级别如何。您应该进行测试,以确保您的应用在各种权限场景下都能正常运行。

以下提示将帮助您查找在 API 级别 23 或更高版本设备上与权限相关的代码问题

  • 识别您应用当前的权限以及相关的代码路径。
  • 测试跨权限保护服务和数据的用户流程。
  • 使用已授予或已撤销权限的各种组合进行测试。例如,相机应用可能在其清单中列出 CAMERAREAD_CONTACTSACCESS_FINE_LOCATION。您应该在这些权限开启和关闭的每种组合下测试应用,以确保应用可以优雅地处理所有权限配置。
  • 使用 adb 工具从命令行管理权限
    • 按组列出权限和状态
      $ adb shell pm list permissions -d -g
    • 授予或撤销一个或多个权限
      $ adb shell pm [grant|revoke] <permission-name> ...
  • 分析您的应用,找出使用权限的服务。

其他资源