Android6.0 运行时权限(runtime permission)

从Android6.0开始(Api 23)增加了运行时权限特性,这个特性是这一版本中影响比较大的一个变化。几个需要记住的关键点:

  • 运行时需要申请的权限必须先在manifest中用<uses-permission>声明。

  • 如果targetApi设置为23以下,那么新特性不起作用,系统会沿用旧的逻辑在安装时询问并赋予权限。

  • PROTECTION_NORMAL级别的permission仍然是在安装时系统就自动授予,与之对应的是PROTECTION_DANGEROUS级别的permission需要运行时申请。

  • 每一个permission都属于一个permission Group,系统提示也是以permission Group为单位提示用户并授权的,例如app首先申请了Read Contacts的permission,用户允许,当app再次申请同一permission Group的write Contacts的permission时,系统自动允许,而不是再次弹出对话框提示用户。

运行时申请权限:

简化版本:

private void showContacts() {
     if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
             != PackageManager.PERMISSION_GRANTED) {
         requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
                 PERMISSIONS_REQUEST_READ_CONTACTS);
     } else {
         doShowContacts();
     }
 }

 @Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions,
         int[] grantResults) {
     if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS
             && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
         showContacts();
     }
 }

复杂版本:

用shouldShowRequestPermissionRationale方法判断否需要向用户解释为什么需要此权限:(如果之前用户拒绝了此权限,再次申请时最好提示一下,此方法会返回true,表示最好向用户解释一下)

if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // 是否需要给用户解释?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // 此处的方法最好做成异步的,而不要阻塞住当前进程,当用户看到解释作出反应后,再次申请权限

    } else {

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);
    }
}

//回调中处理权限是否申请成功
@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                showContacts(); 
            } else {
                //权限未被用户允许
            }
            return;
        }
    }
}

注意:如果用户在之前禁止了某个权限并且在对话框中勾选了Don’t ask again选项,那么shouldShowRequestPermissionRationale方法会反回false。

附表: Dangerous permissions 以及对应的 permission groups.

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值