在 Android 6.0 及更高版本中,Android 应用权限模型旨在让用户更容易理解、使用和安全地使用权限。该模型将需要危险权限(请参阅受影响的权限)的 Android 应用从安装时权限模型转变为运行时权限模型
- 安装时权限
(Android 5.1 及更低版本)用户在安装或更新应用时,会向应用授予危险权限。设备制造商和运营商可以预装已预先授予权限的应用,而无需通知用户。
- 运行时权限
(Android 6.0 至 9)用户在应用运行时向应用授予危险权限。何时请求权限(例如,当应用启动或用户访问特定功能时)取决于应用,但用户可以授予/拒绝应用访问特定权限组。OEM/运营商可以预装应用,但不能预先授予权限,除非他们经过例外流程。(请参阅创建例外。)
(Android 10)用户可以看到更高的透明度,并且可以控制哪些应用拥有活动识别 (AR) 运行时权限。系统会通过运行时权限对话框提示用户选择始终允许、使用时允许或拒绝权限。在升级到 Android 10 的操作系统时,授予应用的权限会被保留,但用户可以进入设置并更改这些权限。
运行时权限可防止应用在未经用户同意的情况下访问私人数据,并让用户更清楚地了解应用正在寻求或已被授予的权限类型。运行时模型鼓励开发者帮助用户了解应用为何需要请求的权限,并提供更高的透明度,以便用户可以更好地决定是否授予或拒绝这些权限。
受影响的权限
Android 6.0 及更高版本要求危险权限使用运行时权限模型。危险权限是较高风险的权限(例如 READ_CALENDAR
),这些权限授予请求应用访问私人用户数据或控制设备,这可能会对用户产生负面影响。要查看危险权限的列表,请运行以下命令
adb shell pm list permissions -g -d
Android 6.0 及更高版本不会更改普通权限的行为。这些都是非危险权限,包括普通权限、系统权限和签名权限。普通权限是较低风险的权限(例如 SET_WALLPAPER
),这些权限授予请求应用访问隔离的应用级功能,对其他应用、系统或用户的风险极小。与 Android 5.1 及更低版本一样,系统会在安装时自动向请求应用授予普通权限,并且不会提示用户批准。有关权限的详细信息,请参阅 <permission> 元素文档。
Android 10 中的硬性限制和软性限制
除了是危险权限之外,权限还可以是硬性限制或软性限制。在这两种情况下,受限制的权限都必须列入许可名单。未列入许可名单的硬性限制的行为与未列入许可名单的软性限制的行为不同
- (硬性限制)应用无法被授予未列入许可名单的权限。
- (软性限制)未列入许可名单的应用的行为取决于它们请求的具体权限。请求权限的公共文档中描述了该行为。
安装应用时,安装程序(例如 Google Play 商店)可以选择不将应用的受限权限列入许可名单。权限受到平台的限制,只有当应用满足平台政策的特殊条件时才可授予。硬性限制权限类型的示例包括短信和通话记录权限。
许可名单在安装期间以及以下情况下发生
- 应用在 Android 9 到 10 升级期间已安装。
- 权限被预先授予或应用被预装。
- 角色需要的权限已被定义为将该权限列入许可名单。
- 安装程序(例如 Google Play 商店)将权限标记为已列入许可名单。
用户无法手动将权限列入许可名单。
要求
运行时权限模型适用于所有应用,包括预装应用和作为设置过程一部分交付到设备的应用。应用软件要求包括
- 在运行 Android 6.0 及更高版本的所有设备上,运行时权限模型必须保持一致。这通过 Android 兼容性测试套件 (CTS) 测试来强制执行。
- 应用必须在运行时提示用户授予应用权限。有关详情,请参阅更新应用。对于提供对设备的预期操作至关重要的基本设备功能的默认应用和处理程序,可能会授予有限的例外。(例如,用于处理
ACTION_CALL
的设备的默认拨号器应用可能具有电话权限访问权限。)有关详情,请参阅创建例外。 - 具有危险权限的预加载应用必须以 API 级别 23 为目标,并维护运行时权限模型。也就是说,应用安装期间的界面流程不得偏离 PermissionController 的 AOSP 实现,用户可以撤消预装应用的危险权限,等等。
- 无头应用必须使用 Activity 来请求权限,或与另一个具有必要权限的应用共享 UID。有关详情,请参阅无头应用。
权限迁移
在 Android 5.x 上授予应用的权限在更新到 Android 6.0 或更高版本后仍然有效,但用户可以随时撤消这些权限。
在 Android 9 到 10 的更新中,所有硬性限制权限都将被列入许可名单。有关实施前台/后台拆分权限的详情,请参阅Android 10 隐私权变更,从请求后台位置信息开始。
集成
在集成 Android 6.0 及更高版本的应用运行时权限模型时,您必须更新预装应用以使用新模型。您还可以为作为核心功能默认处理程序/提供程序的应用定义例外,定义自定义权限,以及自定义 PermissionController
应用中使用的主题。
更新应用
系统映像上的应用和预装应用不会自动预先授予权限。我们建议您与预装应用开发者(OEM、运营商和第三方)合作,使用开发者指南对所需的应用进行修改。具体而言,您必须确保修改预装应用,以避免在用户撤消权限时发生崩溃和其他问题。
预加载应用
在 Android 9 及更低版本中,使用危险权限的预加载应用必须以 API 级别 23 或更高版本为目标,并维护 Android 6.0 及更高版本的 AOSP 权限模型。例如,应用安装期间的界面流程不得偏离 PermissionController
的 AOSP 实现。用户甚至可以撤消预装应用的危险权限。
在 Android 6.0 到 9 中,某些权限在安装流程期间被授予。但是,从 10 开始,安装流程(由 Package Installer
应用执行)与权限授予(在 Permission Controller
应用中)是不同的功能。
无头应用
只有 Activity 可以请求权限。服务不能直接请求权限。
- 在 Android 5.1 及更早版本中,无头应用可以在安装时请求权限,或者如果它们是在没有使用 Activity 的情况下预装的。
- 在 Android 6.0 及更高版本中,无头应用必须使用以下方法之一来请求权限
- 添加 Activity 以请求权限。(这是首选方法。)
- 与另一个具有必要权限的应用共享 UID。仅当您需要平台将多个 APK 视为单个应用时,才使用此方法。
目标是避免因在不相关的情况下出现的权限请求而使用户感到困惑。
自定义 PackageInstaller 界面
如果需要,您可以通过更新 PackageInstaller 使用的默认设备主题(Theme.DeviceDefault.Settings
和 Theme.DeviceDefault.Light.Dialog.NoActionBar
)来自定义权限界面主题。但是,由于一致性对于应用开发者至关重要,因此您不能自定义权限界面的放置、位置和出现规则。
要包含其他语言的 strings,请将字符串贡献给 AOSP。
创建例外
您可以使用 PackageManager 中的 DefaultPermissionGrantPolicy.java
类,向作为核心操作系统功能默认处理程序或提供程序的应用预先授予权限。示例
ACTION_CALL (Dialer) Default Phone, Contacts, SMS, Microphone
SMS_DELIVER_ACTION (SMS/MMS) Default Phone, Contacts, SMS
定义自定义权限
您可以将自定义权限和组定义为普通权限或危险权限,并将 OEM/运营商特定的权限添加到现有权限组,就像您在 Android 5.x 及更早版本中所做的那样。
在 Android 6.0 及更高版本中,如果您添加新的危险权限,则必须以与其他危险权限相同的方式处理它(在应用运行时请求并可由用户撤消)。具体而言
- 您可以将新权限添加到当前组,但不能修改危险权限和危险权限组的 AOSP 映射。(换句话说,您不能从组中删除权限并将其分配给另一个组)。
- 您可以在设备上安装的应用中添加新的权限组,但不能在平台清单中添加新的权限组。
测试权限
Android 包括兼容性测试套件 (CTS) 测试,这些测试验证各个权限是否已映射到正确的组。通过这些测试是 Android 6.0 及更高版本 CTS 兼容性的要求。
撤消权限
在 Android 13 及更高版本中,您可以使用 Context.revokeSelfPermissionsOnKill()
撤消您自己授予的运行时权限。撤消操作是异步发生的,并且在可以安全执行且不会中断用户的情况下触发。当撤消操作被触发时,在调用 UID 中运行的所有进程都将被终止。
务必了解,撤消单个权限可能不会反映在设置界面中,因为设置界面按组处理权限。通常,只要组中至少有一个权限被授予,权限组就会显示为已授予。如果确保用户能够在设置中确认撤消操作对您很重要,请务必撤消权限组中的每个权限。要了解哪些权限属于某个组,您可以使用 PackageManager.getGroupOfPlatformPermission
和 PackageManager.getPlatformPermissionsForGroup
。
当系统撤消请求的权限时,如果其相应的前台权限均未授予,系统也会撤消相应的后台权限。
只要进程保持在前台,就不会触发撤消操作,但也可以通过手动终止当前 uid 中运行的所有进程来立即触发撤消操作,例如使用 System.exit()
。但是,建议让系统决定何时触发它。
权限撤消生效后,您可以再次请求该权限,并且系统会提示用户授予或拒绝该请求。无法请求用户之前已拒绝的权限。虽然我们鼓励您撤消当前拥有但不再需要的权限,但您应注意不要在撤消生效之前告知用户撤消操作。