在 Android 11 中,用户能够针对位置信息、麦克风和摄像头指定更精细的权限。此外,系统会重置以 Android 11 为目标平台的未使用应用的权限,如果应用读取与电话号码相关的信息,则可能需要更新其声明的权限。
单次授权
在 Android 11 中,每当应用请求与位置信息、麦克风或摄像头相关的权限时,面向用户的权限对话框就会包含仅限这一次选项。如果用户在对话框中选择此选项,系统会向应用授予临时的单次授权。
然后,应用可以在一段时间内访问相关数据,具体时间取决于应用的行为和用户的操作:
- 当应用的 Activity 可见时,应用可以访问相关数据。
- 如果用户将应用转为后台运行,应用可以在短时间内继续访问相关数据。
- 如果您在 Activity 可见时启动了一项前台服务,并且用户随后将您的应用转到后台,那么您的应用可以继续访问相关数据,直到该前台服务停止。
- 如果用户撤消单次授权(例如在系统设置中撤消),无论您是否启动了前台服务,应用都无法访问相关数据。与任何权限一样,如果用户撤消了应用的单次授权,应用进程就会终止。
当用户下次打开应用并且应用中的某项功能请求访问位置信息、麦克风或摄像头时,系统会再次提示用户授予权限。
注意:如果应用在请求运行时权限时已遵循最佳做法,您无需更改应用即可支持单次授权。
自动重置未使用的应用的权限
如果应用以 Android 11 为目标平台并且数月未使用,系统会通过自动重置用户已授予应用的敏感权限来保护用户数据。此操作与用户在系统设置中查看权限并将应用的访问权限级别更改为拒绝的做法效果一样。如果应用遵循有关在运行时请求权限的最佳做法,那么您不必对应用进行任何更改。这是因为,当用户与应用中的功能互动时,您应该会验证相关功能是否具有所需权限。
请求用户停用自动重置功能
如果需要,您可以要求用户阻止系统重置应用的权限。如果用户希望应用主要在后台运行,即使用户不与应用互动应用也能正常工作,在这种情况下此做法就非常有用,此类用例的示例如下:
- 为家人的安全提供保障
- 同步数据
- 与智能设备通信
- 与配套设备配对
要在系统设置中将用户定向到您的应用页面,请调用包含Settings.ACTION_APPLICATION_DETAILS_SETTINGS
Intent 操作的 Intent。在此屏幕中,用户可以通过执行以下操作来阻止系统重置应用的权限:
- 点按权限,系统会加载应用权限设置屏幕。
- 关闭如果未使用此应用,则移除相关权限选项,如图 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 建议不要请求用户已选择拒绝的权限。在应用安装到设备上后,如果用户在使用过程中屡次针对某项特定的权限点按拒绝,此操作表示其希望“不再询问”。
如果应用已遵循与权限相关的最佳做法,您无需更改应用即可支持此行为变更。
电话号码
Android 11 更改了您的应用在读取电话号码时使用的与电话相关的权限。
如果您的应用以 Android 11 为目标平台,并且需要访问以下列表中显示的电话号码 API,则必须请求 READ_PHONE_NUMBERS
权限,而不是 READ_PHONE_STATE
权限。
TelephonyManager
类和TelecomManager
类中的getLine1Number()
方法。TelephonyManager
类中不受支持的getMsisdn()
方法。
如果您的应用声明 READ_PHONE_STATE
以调用前面列表中的方法以外的方法,您可以继续在所有 Android 版本中请求 READ_PHONE_STATE
。不过,如果您仅对前面列表中的方法使用 READ_PHONE_STATE
权限,请按以下方式更新您的清单文件:
- 更改
READ_PHONE_STATE
的声明,以使您的应用仅在 Android 10(API 级别 29)及更低版本中使用该权限。 - 添加
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>