应用权限最佳做法

权限请求可以保护设备中的敏感信息,仅当需要访问敏感信息才能使应用正常运行时,才应使用权限请求。利用本文档介绍的技巧,您无需访问此类信息即可实现相同(或更好的)功能;但本文不会详细讨论权限在 Android 操作系统中的工作方式。

如需大致了解 Android 权限,请参阅权限概览。如需详细了解如何在代码中使用权限,请参阅请求应用权限

Android 6.0 及更高版本中的权限

Android 6.0 Marshmallow 引入了一种新的权限模型,让应用可以在运行时(而不是安装之前)向用户请求权限。支持这个新模型的应用会在应用确实需要相关服务或这些服务保护的数据时请求权限。尽管这不会(不一定会)改变整体应用行为,但会给敏感用户数据的处理方式带来一些变化:

增加了情境背景信息:系统会在运行时在应用的情境中,提示用户提供访问相关权限组涵盖的功能所需的权限。用户对请求权限的情境更加敏感,如果您请求的权限与应用的用途不匹配,那么更需要向用户详细解释您为什么请求此权限;您应尽可能在请求时以及万一用户拒绝请求后出现的后续对话框中解释您的请求。

在授予权限时更加灵活:用户可以在收到请求时以及在设置中拒绝单个权限,但是当功能因此而中断时,他们可能仍会感到惊讶。最好监控有多少用户拒绝权限请求(例如使用 Google Analytics(分析)进行监控),以便通过重构应用来避免依赖该权限,或更好地解释应用需要此权限才能正常工作的原因。您还应确保应用可以处理当用户拒绝权限请求或在设置中停用权限时产生的异常。

增加了事务负担:系统将要求用户单独授予权限组的访问权限,而不是以集合的形式授予。这样,最大程度降低请求的权限数量就变得非常重要,因为数量多会增加用户授予权限的负担,并且会增大至少有一个请求被拒绝的概率。

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

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

如需详细了解默认处理程序,包括有关如何向用户显示默认处理程序提示的指南,请参阅有关仅在默认处理程序中使用的权限的指南

了解您正在使用的库

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

就像用户会选择使用较少权限即可实现相同功能的应用一样,开发者也应检查他们的库,并选择不会使用非必要权限的第三方 SDK。例如,如果您使用的库提供了定位功能,请确保您不会请求 FINE_LOCATION 权限,除非您要使用基于位置的定位功能。

限制对位置信息的后台使用权

当您的应用在后台运行时,获取位置信息访问权限对应用的核心功能至关重要,并可以为用户带来明显的好处。

解释为何需要权限

系统在您调用 requestPermissions() 时显示的权限对话框将说明应用需要哪些权限,但不会解释为何需要这些权限。在某些情况下,用户可能会感到困惑。因此,最好在调用 requestPermissions() 之前向用户解释应用需要相应权限的原因。

研究表明,如果用户知道应用需要相应权限的原因,他们会更容易接受权限请求。用户研究表明:

…用户是否愿意为某个移动应用授予给定权限,在很大程度上受此类权限关联用途的影响。例如,用户是否愿意授予访问其位置信息的权限将取决于该权限请求是否为支持应用的核心功能所必需,或者应用是否会与广告网络或分析公司分享此信息。1

卡内基梅隆大学 (CMU) 的 Jason Hong 教授在与他人一起深入探讨此主题后,得出一个一般性结论:

…与只是告诉用户应用正在使用其位置信息相比,如果用户知道应用为什么使用像他们的位置这样敏感的信息(例如,用于定位广告),用户会更容易接受。1

因此,如果您仅使用归入权限组的一小部分 API 调用,明确列出您使用哪些权限以及使用原因会非常有用。例如:

  • 如果您仅使用粗略位置,请在应用说明或应用的帮助文档中告知用户。
  • 如果您需要访问短信以接收身份验证码,从而防止用户被欺诈,请在应用说明中和/或首次访问数据时告知用户。

    注意:如果您的应用以 Android 8.0(API 级别 26)或更高版本为目标平台,请不要在验证用户凭据过程中请求 READ_SMS 权限,而应使用 createAppSpecificSmsToken() 生成应用特定的令牌,然后将此令牌传递给可以发送验证短信的其他应用或服务。

在特定条件下,让用户实时了解应用在访问敏感数据也是非常有益的。例如,如果您要访问相机或麦克风,通常最好在应用中的某个位置或在通知栏中(如果应用正在后台运行)使用通知图标通知用户,避免让您看上去是在偷偷地收集数据。

最后,如果您需要请求权限以便在应用中运行某项功能,但用户不清楚原因,则需要找到一种方法让用户知道您为什么需要最敏感的权限。

测试两种权限模型

从 Android 6.0(API 级别 23)开始,用户将在运行时授予和撤消应用权限,而不是在安装应用时授予和撤消应用权限。因此,您必须在更广泛的条件下测试应用。在 Android 6.0 之前,您可以合理地认为,如果应用能运行,它就已经获得在应用清单中声明的全部权限。自 Android 6.0 起,用户可以开启或关闭任何应用的权限,即使以 API 级别 22 或更低级别为目标平台的应用也是如此。您应测试以确保您的应用能正常运行,无论它是否具有任何权限。

以下提示可帮助您在搭载 API 级别 23 或更高级别的设备上找出与权限有关的代码问题:

  • 确定应用的当前权限和相关的代码路径。
  • 在各种受权限保护的服务和数据中测试用户流。
  • 使用授予或撤消权限的各种组合进行测试。例如,相机应用可能会在清单中列出 CAMERAREAD_CONTACTSACCESS_FINE_LOCATION。您应在测试该应用时逐一开启和关闭这些权限,确保应用可以妥善处理所有权限配置。
  • 使用 adb 工具从命令行管理权限:
    • 按组列出权限和状态:
      $ adb shell pm list permissions -d -g
    • 授予或撤消一项或多项权限:
      $ adb shell pm [grant|revoke] <permission-name> ...
  • 针对使用权限的服务对应用进行分析。

其他资源

参考文件

[1] Modeling Users’ Mobile App Privacy Preferences: Restoring Usability in a Sea of Permission Settings,作者:J. Lin B. Liu、N. Sadeh 和 J. Hong。发表于 2014 年 SOUPS 会议记录。