前段时间在写着玩时用到了一个定位的库,但却总没能成功获取到地理位置,反而换了部手机却又可以了。想到两部手机的版本定位不了的是6.0的,而另一部是4.4的,所以应该是权限没有。查看日志后也确是如此,为此就记录一下关于6.0(api 23)之后的运行时权限的获取问题。虽然这个很早就有了,但是仍有部分应用其实还是没有对此做处理的。本篇是以一个开源库PermissionsDispatcher
的使用来写这篇学习笔记。
Github链接:hotchemi/PermissionsDispatcher
新旧权限获取的差异(大部分情况)
6.0以前
用户: 应用安装时会罗列出全部需要的权限,确定安装则表示同意应用获取这些权限,如果因为某个权限用户不想授予,则唯一的方法就是取消安装,最后结果是可能因为一小部分功能需要这个权限使得用户没能安装使用上该应用,这对于双方都是不愿看到的。
开发者: 在AndroidManifest
文件中声明所需要的权限,请求授权简单,需要什么权限加个uses-permission
就可以了。
6.0及其之后
用户: 用户可以在手机的设置中或者一些有权限管理的应用中对我们的应用权限进行操作,禁止他们不愿意授予的权限。结果是他们仍然可以安装使用应用而且还能,而且使用时也更放心。
开发者: 需要在需要权限的地方添加代码动态申请权限的授予,在等到用户同意时才能进入到该需要权限的功能模块。相对之前而言请求授权是复杂了些,但是对于用户确是更为友好。
权限级别
系统的权限大致可分为正常权限、危险权限、特殊权限
- 正常权限:涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。例如,设置时区的权限就是正常权限。如果应用声明其需要正常权限,系统会自动向应用授予该权限。
- 危险权限:涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如,能够读取用户的联系人属于危险权限。如果应用声明其需要危险权限,则用户必须明确向应用授予该权限。
- 特殊权限:有许多权限其行为方式与正常权限及危险权限都不同。SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 特别敏感,因此大多数应用不应该使用它们。如果某应用需要其中一种权限,必须在清单中声明该权限,并且发送请求用户授权的 intent。系统将向用户显示详细管理屏幕,以响应该 intent。
权限组
所有危险的 Android 系统权限都属于权限组。如果设备运行的是 Android 6.0(API 级别 23),并且应用的 targetSdkVersion 是 23 或更高版本,则当用户请求危险权限时系统会发生以下行为:
如果应用请求其清单中列出的危险权限,而应用目前在权限组中没有任何权限,则系统会向用户显示一个对话框,描述应用要访问的权限组。对话框不描述该组内的具体权限。例如,如果应用请求 READ_CONTACTS 权限,系统对话框只说明该应用需要访问设备的联系信息。如果用户批准,系统将向应用授予其请求的权限。
如果应用请求其清单中列出的危险权限,而应用在同一权限组中已有另一项危险权限,则系统会立即授予该权限,而无需与用户进行任何交互。例如,如果某应用已经请求并且被授予了 READ_CONTACTS 权限,然后它又请求 WRITE_CONTACTS,系统将立即授予该权限。
- 任何权限都可属于一个权限组,包括正常权限和应用定义的权限。但权限组仅当权限危险时才影响用户体验。可以忽略正常权限的权限组。
- 如果设备运行的是 Android 5.1(API 级别 22)或更低版本,并且应用的 targetSdkVersion 是 22 或更低版本,则系统会在安装时要求用户授予权限。再次强调,系统只告诉用户应用需要的权限组,而不告知具体权限。
危险权限及其权限组
权限组 | 权限 |
---|---|
CALENDAR (日历) |
READ_CALENDAR WRITE_CALENDAR |
CAMERA (相机) |
CAMERA |
CONTACTS (通讯录) |
READ_CONTACTS WRITE_CONTACTS GET_ACCOUNTS |
LOCATION (地理位置) |
ACCESS_FINE_LOCATION ACCESS_COARSE_LOCATION |
MICROPHONE (麦克风) |
RECORD_AUDIO |
PHONE (电话)</ |