在 Android 11 中,用户能够针对位置信息、麦克风和摄像头指定更精细的权限。此外,如果以 Android 11 或更高版本为目标平台的应用在一段时间内未使用,系统就会重置这些应用的权限。如果应用使用系统提醒窗口或读取与电话号码相关的信息,可能需要更新它们声明的权限。
1.单次授权
从 Android 11 开始,每当应用请求与位置信息、麦克风或摄像头相关的权限时,面向用户的权限对话框会包含
仅限这一次
选项。如果用户在对话框中选择此选项,系统会向应用授予临时的单次授权。
应用可以在一段时间内访问相关数据,具体时间取决于应用的行为和用户的操作:
(1)当应用的 activity 可见时,应用可以访问相关数据。
(2)如果用户将应用转为后台运行,应用可以在短时间内继续访问相关数据。
(3)如果在 activity 可见时启动了一项前台服务,并且用户随后将应用转到后台,那么应用可以继续访问相关数据,直到该前台服务停止。
(4)如果用户撤消单次授权(例如在系统设置中撤消),无论是否启动了前台服务,应用都无法访问相关数据。与任何权限一样,如果用户撤消了应用的单次授权,应用进程就会终止。
单次授权timeout规则:
(1)应用进程还在
默认是从应用inactive后(importance 为IMPORTANCE_CACHED 400)算起的1 minute内单次授权有效;单次授权后在一分钟之内退出应用再打开应用,依旧有权限;退出应用超过一分钟后再打开应用,则需要再次授权。(如果在 activity 可见时启动了一项前台服务(importance 为IMPORTANCE_FOREGROUND_SERVICE 125),并且用户随后将应用转到后台,(importance一直为IMPORTANCE_FOREGROUND_SERVICE),应用可以继续访问相关数据,直到该前台服务停止)
(2)应用进程不在
如果直接杀死应用(importance 为IMPORTANCE_GONE 1000),则从应用退出算起的5s内,单次授权有效,打开应用依旧有权限;超过5s后再打开应用,需要再次授权。
2. 自动重置未使用的应用的权限
如果应用以 Android 11 或更高版本为目标平台并且数月未使用,系统会通过自动重置用户
已授予
应用的
运行时敏感权限
来保护用户数据。此操作与用户在系统设置中查看权限并将应用的访问权限级别更改为拒绝的做法效果一样。如果应用遵循了有关在运行时请求权限的最佳做法,那么不必对应用进行任何更改。这是因为,当用户与应用中的功能互动时,应该会验证相关功能是否具有所需权限。
(针对已允许的运行时权限,包括仅在使用该应用时允许的运行时权限)。
关于数月未使用中数月的定义:默认是90天:
检查频率:默认是15天:
通过UsageStats/UsageStatsManager来跟踪所有package的使用统计信息。
主要在AutoRevokeService中实现:
移除相关权限流程(在PermissionController中):
验证系统是否重置了应用的权限:
(1)减少系统重置权限所需等待的时长:
adb shell device_config put permissions auto_revoke_unused_threshold_millis2 1000
对系统进行了修改,使得当停止与应用互动后仅一秒钟,系统就会重置应用的权限。
可以通过get来查看是否设置成功:
adb shell device_config get permissions auto_revoke_unused_threshold_millis2
(2)手动调用自动重置进程
adb shell cmd jobscheduler run -u 0 -f com.android.permissioncontroller 2
强制执行permissioncontroller包下的JobID 为2的Job
3.权限对话框的可见性
从 Android 11 开始,在应用安装到设备上后,如果用户在使用过程中多次针对某项特定的权限点按拒绝,那么在应用再次请求该权限时,用户将不会看到系统权限对话框。该操作表示用户希望“不再询问”。在之前的版本中,除非用户先前已选中“不再询问”对话框或选项,否则每当应用请求权限时,用户都会看到系统权限对话框。Android 11 中的这一行为变更旨在避免重复请求用户已选择拒绝的权限。
具体操作:连续拒绝两次,则用户将不会看到系统权限对话。
系统有发REQUEST_PERMISSIONS的action,在GrantPermissionsActivity中根据权限policy,直接auto deny了。
4.系统提醒窗口变更
在 Android 11 中,向应用授予 SYSTEM_ALERT_WINDOW 权限的方式发生了一些变更。这些变更可以让权限的授予更有目的性,从而达到保护用户的目的。
(1)根据请求自动向某些应用授予 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 即可。
(2)MANAGE_OVERLAY_PERMISSION intent 始终会将用户转至系统权限屏幕
从 Android 11 开始,ACTION_MANAGE_OVERLAY_PERMISSION intent 始终会将用户转至顶级设置屏幕,用户可在其中授予或撤消应用的 SYSTEM_ALERT_WINDOW 权限。intent 中的任何 package:数据都会被忽略。
在更低版本的 Android 中,ACTION_MANAGE_OVERLAY_PERMISSION intent 可以指定一个软件包,它会将用户转至应用专用屏幕以管理权限。从 Android 11 开始将不再支持此功能,而是必须由用户先选择要授予或撤消哪些应用的权限。此变更可以让权限的授予更有目的性,从而达到保护用户的目的。
SYSTEM_ALERT_WINDOW权限定义:
添加悬浮窗权限(Manifest文件中已经声明SYSTEM_ALERT_WINDOW):
5.电话号码
Android 11 更改了应用在读取电话号码时使用的与电话相关的权限。
如果应用以 Android 11 或更高版本为目标平台,并且需要访问以下列表中显示的电话号码 API,则必须请求 READ_PHONE_NUMBERS 权限,而不是 READ_PHONE_STATE 权限。
(1)TelephonyManager 类和 TelecomManager 类中的 getLine1Number() 方法。
(2)TelephonyManager 类中不受支持的 getMsisdn() 方法。
如果应用声明 READ_PHONE_STATE 以调用前面列表中的方法以外的方法,可以继续在所有 Android 版本中请求 READ_PHONE_STATE。不过,如果仅对前面列表中的方法使用 READ_PHONE_STATE 权限,请按以下方式更新应用清单文件:
(1)更改 READ_PHONE_STATE 的声明,以使应用仅在 Android 10(API 级别 29)及更低版本中使用该权限。
(2)添加 READ_PHONE_NUMBERS 权限。
以下是Android11 Telecomm的TelecomServiceImpl.java中 canReadPhoneNumbers方法关于权限的判断:
6.后台位置信息访问权限
在搭载 Android 11 的设备上,当应用中的某项功能请求在后台访问位置信息时,用户看到的系统对话框不再包含用于启用后台位置信息访问权限的按钮。如需启用后台位置信息访问权限,用户必须在
设置页面
上针对应用的位置权限设置
一律允许
选项。主要涉及到两点:
(1)从 Android 10 系统的设备开始,就需要请求后台位置权限(ACCESS_BACKGROUND_LOCATION),并选择Allow all the time (始终允许)才能获得后台位置权限。Android 11 设备上再次加强对后台权限的管理,主要表现在系统对话框上,对话框不再提示始终允许字样,而是提供了位置权限的设置入口,需要在设置页面选择始终允许才能获得后台位置权限。
(2)在搭载Android 11 系统的设备上,targetVersion 小于 11 的时候,可以前台后台位置权限一起申请,并且对话框提供了文字说明,表示需要随时获取用户位置信息,进入设置选择始终允许即可。但是 targetVersion 为 30 的时候,你必须单独申请后台位置权限,而且要在获取前台权限之后,顺序不能乱。并且无任何提示,需要开发者自己设计提示样式。
有点绕,操作几个例子说明:
(以上代码针对1)、2)、3)不同设备上及不同targetSdkVersion申请相同权限)
1)Android 10 设备,申请前台和后台位置权限 (任意 targetSdkVersion,28为例):
运行结果:
2) Android 11 设备,targetSdkVersion<=29(Android 10),申请前台和后台位置权限:
运行结果:
3)Android 11 设备,targetSdkVersion=30(Android 11),申请前台和后台位置权限:
执行无反应。
4) Android 11设备,targetSdkVersion=30(Android 11),先申请前台位置权限,后申请后台位置权限:
执行结果:
执行结果:
具体适配方案需要应用根据自己的需求,可以通过区分应用的targetSdkVersion 版本来进行适配(applicationInfo.targetSdkVersion < Build.VERSION_CODES.R)。
7.Android11开发手册中Q&A
总的来说,单次授权和自动重置未使用的应用的权限还是很不错的,如单次授权可以避免应用在后台因为有权限而偷偷访问数据(到这里不得不提下美团 哈哈哈哈哈 各种访问位置信息,简直就不会停)等等。
在 Android 11 中,用户能够针对位置信息、麦克风和摄像头指定更精细的权限。此外,如果以 Android 11 或更高版本为目标平台的应用在一段时间内未使用,系统就会重置这些应用的权限。如果应用使用系统提醒窗口或读取与电话号码相关的信息,可能需要更新它们声明的权限。单次授权从 Android 11 开始,每当应用请求与位置信息、麦克风或摄像头相关的权限时,面向用户的权限对话框会包含仅限这一次选项。如果用户在对话框中选择此选项,系统会向应用授予临时的单次授权。 自动重置未使用的应...
各位小伙伴们早上好,不知道你们有没有惊讶于我的速度,因为不久之前我才新发布的开源库PermissionX今天又
更新
了。
是的,在不到一个月的时间里,PermissionX又迎来了一次重大的版本
更新
。如果你觉得一个月还不算快的话,可别忘了,两周之前我还发布了LitePal的新版本。对于我来说,这个速度已经是相当极限了。
不过,可能还有不少朋友不知道PermissionX是什么,这里我给出上一篇文章的链接,还没看过的小伙伴先去补补课
因项目需要做比较详细的
权限
控制,大致了解了sprin sercurity、shiro两个名气比较大的
权限
管理框架。
得到的结论是:功能足够强大,用户、
权限
、认证等等,你想到的它全都有,没想到的也有。但是我并不需要这么多功能(项目的用户认证已由其他方案完成,现只需要
权限
控制)。而且连号称轻量级的shiro我也觉得太庞大了些。因此,决定根据项目需求自己实现一套极简
权限
控制方案。
关于
权限
的数据库...
Android
11
主要是进一步收缩了应用
权限
,在
权限
管理方面比以前更加严格
最主要,影响最大的,就是存储卡
访问权限
的调整
从
Android
11
开始,应用将只能访问自己的私有目录、公共媒体目录、存储卡根目录
其它目录,只能判断文件是否存在,但是既不能读取,也不能写入
这直接影响到文件选取、拍照录像录音、文件分享、文件下载等功能
对开发者影响非常大,特别是严重依赖于外部存储的项目
首先摆正心态,积极适配,不要抗拒变化,逃避问题,影响比较多,我们逐个击破
Android
1
该窗口对应的包名如下
C:\Users\
Android
1>
adb
shell dumpsys window | findstr mCurrentFocus
mCurrentFocus=Window{35a20c5 u0 com.
android
.permissioncontroller/com.
android
.packageinstaller.permission.ui.ReviewPermissionsActivity}
Android
6.0以后由于系统运行安全的考虑,既然在Andr
有些时候系统里预装了两个电话、桌面这样的应用,开机启动后系统会弹框让你选择使用那一个。
在系统设置中应用和通知里发现有默认应用选项,点进去发现是在 PermissionController 中
默认列表界面
adb
shell dumpsys window | findstr mCurrentFocus
mCurrentFocus=Window{ffb6aca u0 com.
android
.permissioncontroller/com.
android
.packageinstaller.role.ui.D
Android
权限
|
Android
开源项目 |
Android
Open Source Project
在
Android
9 及更低版本中,软件包安装和
权限
控制功能包含在 PackageInstaller 软件包 (//packages/apps/PackageInstaller) 中。
在
Android
10 及更高版本中,
权限
控制功能位于单独的软件包 PermissionController (//packages/apps/PermissionController) 中。
申请前提,manifest一定要有,没有是不会通过的。
动态申请代码:
public final void requestPermissions(@NonNull String[] permissions, int requestCode)
启动一个供用户选择的授权界面:
final Intent intent = getPackageManager().buildRequestPermissionsIntent(permis
安卓
11
改变了此前
安卓
系统对于文件管理的规则,在
安卓
11
上,文件读写变成了特殊
权限
。应用默认只能读写自己的目录
Android
11
系统对应用写入
权限
做了严格的限制。本文介绍如何获取文件读写
权限
。项目中 build.gradle 的targetSdkVersion >= 29 ,会出现读写问题为了能直接usb安装,gradle.properties 需要设置(否则,在安装时会报异常:-15)
Android
Manifest添加
权限
设置
申请
权限
,主要用到如下4个函数
申请
权限
是否应该显示请
1. 在
Android
Manifest.xml文件中声明需要的
权限
,例如:
<uses-permission
android
:name="
android
.permission.CAMERA" />
2. 在代码中检查
权限
是否已经被授予,例如:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// 如果没有被授予,就申请
权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
3. 处理
权限
申请的结果,例如:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//
权限
已经被授予
openCamera();
} else {
//
权限
被拒绝
Toast.makeText(this, "无法打开相机,因为没有相机
权限
", Toast.LENGTH_SHORT).show();
以上就是
Android
申请
权限
的基本步骤。