Marshmallow Runtime Permissions
从 Android 6.0 (API 23) 开始系统开始将应用权限收紧,将权限分为普通(Normal Permissions)权限与危险权限(Dangerous Permissions)。
普通权限不会影响到用户的隐私,只要像以往那样在 manifest 中声明即可使用。
危险权限不仅要在 manifest 中声明,而且需要获得用户的批准。虽然可以临时将 target API 设置在 23 以下规避,但一来用户仍然可以在系统设置中强制拒绝授予权限造成应用崩溃,二来也并非长久之计。
危险权限及分组
系统分组处理危险权限的授予,如果应用已经获得某个组内的某项权限,那么也就默认获得了该组内的其他权限。比如我们已经获得了 READ_CONTACTS
权限,那么相当于 CONTACTS
组内的 WRITE_CONTACTS
和 GET_ACCOUNTS
权限也获得了。
Permission Group | Permissions |
---|---|
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 | READ_PHONE_STATE CALL_PHONE READ_CALL_LOG WRITE_CALL_LOG ADD_VOICEMAIL USE_SIP PROCESS_OUTGOING_CALLS |
SENSORS | BODY_SENSORS |
SMS | SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEIVE_MMS |
STORAGE | READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE |
基本 API 使用
与运行时权限相关的 API 主要有以下几个方法。
1 | // Context/ContextCompat |
checkSelfPermission
方法用来检测是否已经获得某项权限,返回结果为PackageManager.PERMISSION_GRANTED
或 PackageManager.PERMISSION_DENIED
。
shouldShowRequestPermissionRationale
表示应用是否应该向用户解释为何需要权限。未请求过该权限时返回 false。
requestPermissions
执行请求权限的实际操作,在调用该方法时,系统弹出对话框让用户选择是否允许获取所请求的权限。
如果用户选择了 Never ask again 并拒绝授予,那么之后调用 requestPermissions
请求该权限直接会被拒绝,shouldShowRequestPermissionRationale
都会返回 false。
onRequestPermissionsResult
方法是 Activity 的一个回调方法,类似于 onActivityResult
,返回权限请求的结果。
例子
1 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { |