Android 11 中的权限更新

在 Android 11 中,用户能够针对位置信息、麦克风和摄像头指定更精细的权限。此外,系统会重置以 Android 11 为目标平台的未使用的应用的权限。如果应用使用系统提醒窗口或读取与电话号码相关的信息,可能需要更新它们声明的权限。

单次授权

在 Android 11 中,每当应用请求与位置信息、麦克风或摄像头相关的权限时,面向用户的权限对话框会包含仅限这一次选项。如果用户在对话框中选择此选项,系统会向应用授予临时的单次授权。

然后,应用可以在一段时间内访问相关数据,具体时间取决于应用的行为和用户的操作:

  • 当应用的 Activity 可见时,应用可以访问相关数据。
  • 如果用户将应用转为后台运行,应用可以在短时间内继续访问相关数据。
  • 如果您在 Activity 可见时启动了一项前台服务,并且用户随后将您的应用转到后台,那么您的应用可以继续访问相关数据,直到该前台服务停止。
  • 如果用户撤消单次授权(例如在系统设置中撤消),无论您是否启动了前台服务,应用都无法访问相关数据。与任何权限一样,如果用户撤消了应用的单次授权,应用进程就会终止。

当用户下次打开应用并且应用中的某项功能请求访问位置信息、麦克风或摄像头时,系统会再次提示用户授予权限。

自动重置未使用的应用的权限

如果应用以 Android 11 为目标平台并且数月未使用,系统会通过自动重置用户已授予应用的运行时敏感权限来保护用户数据。此操作与用户在系统设置中查看权限并将应用的访问权限级别更改为拒绝的做法效果一样。如果应用已遵循有关在运行时请求权限的最佳做法,那么您不必对应用进行任何更改。这是因为,当用户与应用中的功能互动时,您应该会验证相关功能是否具有所需权限。

请求用户停用自动重置功能

如果需要,您可以要求用户阻止系统重置应用的权限。如果用户希望应用主要在后台运行,即使用户不与应用互动,应用也能正常工作,那么此做法就非常有用。此类使用场景的示例如下:

图 1. 用户已停用为给定应用自动重置权限的功能。
  • 为家人的安全提供保障
  • 同步数据
  • 与智能设备通信
  • 与配套设备配对

如需将用户定向到系统设置中您应用的页面,请调用包含 Intent.ACTION_AUTO_REVOKE_PERMISSIONS intent 操作的 intent。在此屏幕中,用户可以通过执行以下操作来阻止系统重置应用的权限:

  1. 点按权限,系统会加载应用权限设置屏幕。
  2. 关闭如果未使用此应用,则移除相关权限选项,如图 1 所示。

确定是否已停用自动重置功能

如需检查是否已针对应用停用自动重置功能,请调用 isAutoRevokeWhitelisted()。如果此方法返回 true,则系统不会自动重置应用的权限。

测试自动重置功能

如需验证系统是否重置了应用的权限,请执行以下操作:

  1. 保存系统重置应用权限所需等待的默认时长。这样,您就可以在测试后恢复此设置:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  2. 减少系统重置权限所需等待的时长。下面的示例对系统进行了修改,以致当您停止与应用互动后仅一秒钟,系统就会重置应用的权限:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  3. 手动调用自动重置进程,如以下代码段所示。在运行此命令之前,请确保测试设备已开启片刻(大约 45 秒钟)。

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  4. 验证应用能否处理自动重置事件。

  5. 恢复系统在自动重置应用权限之前所需等待的默认时长:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold
    

权限对话框的可见性

Android 11 建议不要请求用户已选择拒绝的权限。在应用安装到设备上后,如果用户在使用过程中屡次针对某项特定的权限点按拒绝,此操作表示其希望“不再询问”。

如果应用已遵循与权限相关的最佳做法,您无需更改应用即可支持此行为变更。

系统提醒窗口变更

向应用授予 SYSTEM_ALERT_WINDOW 权限的方式发生了一些变更。这些变更可以让权限的授予更有目的性,从而达到保护用户的目的。

根据请求自动向某些应用授予 SYSTEM_ALERT_WINDOW 权限

系统会根据请求自动向某些类型的应用授予 SYSTEM_ALERT_WINDOW 权限:

  • 系统会自动向具有 ROLE_CALL_SCREENING 且请求 SYSTEM_ALERT_WINDOW 的所有应用授予该权限。如果应用失去 ROLE_CALL_SCREENING,就会失去该权限。

  • 系统会自动向通过 MediaProjection 截取屏幕且请求 SYSTEM_ALERT_WINDOW 的所有应用授予该权限,除非用户已明确拒绝向应用授予该权限。当应用停止截取屏幕时,就会失去该权限。此用例主要用于游戏直播应用。

这些应用无需发送 ACTION_MANAGE_OVERLAY_PERMISSION 以获取 SYSTEM_ALERT_WINDOW 权限,它们只需直接请求 SYSTEM_ALERT_WINDOW 即可。

MANAGE_OVERLAY_PERMISSION intent 始终会将用户转至系统权限屏幕

从 Android 11 开始,ACTION_MANAGE_OVERLAY_PERMISSION intent 始终会将用户转至顶级设置屏幕,用户可在其中授予或撤消应用的 SYSTEM_ALERT_WINDOW 权限。intent 中的任何 package: 数据都会被忽略。

在更低版本的 Android 中,ACTION_MANAGE_OVERLAY_PERMISSION intent 可以指定一个软件包,它会将用户转至应用专用屏幕以管理权限。Android 11 不再支持此功能,而是必须由用户先选择要对其授予或撤消权限的应用。此变更可以让权限的授予更有目的性,从而达到保护用户的目的。

电话号码

Android 11 更改了您的应用在读取电话号码时使用的与电话相关的权限。

如果您的应用以 Android 11 为目标平台,并且需要访问以下列表中显示的电话号码 API,则必须请求 READ_PHONE_NUMBERS 权限,而不是 READ_PHONE_STATE 权限。

如果您的应用声明 READ_PHONE_STATE 以调用前面列表中的方法以外的方法,您可以继续在所有 Android 版本中请求 READ_PHONE_STATE。不过,如果您仅对前面列表中的方法使用 READ_PHONE_STATE 权限,请按以下方式更新您的清单文件:

  1. 更改 READ_PHONE_STATE 的声明,以使您的应用仅在 Android 10(API 级别 29)及更低版本中使用该权限。
  2. 添加 READ_PHONE_NUMBERS 权限。

以下清单声明代码段演示了此过程:

<manifest>
    <!-- Grants the READ_PHONE_STATE permission only on devices that run
         Android 10 (API level 29) and lower. -->
    <uses-permission android:name="READ_PHONE_STATE"
                     android:maxSdkVersion="29" />
    <uses-permission android:name="READ_PHONE_NUMBERS" />
</manifest>