天天看点

Android:6.0运行时权限解析1.运行时权限的变化二.新的权限机制的申请步骤

     android6.0发布好一段时间了,但是由于android手机厂商都要对android“深度定制”。因此很多用户都没有第一时间收到android6.0升级推送。笔者用的是魅族手机,到笔者写本编文章为止还没能升级到6.0系统。在这里吐槽一下bugme!android6.0的权限机制发生了较大的变化,特别是对于开发者来说要第一时间掌握如何对6.0的运行时权限进行适配。

1.运行时权限的变化

在android6.0之前,安装应用的时候回列出一个权限列表,要安装该应用就必需同意这些权限。因此应用所需要的权限只是展示给用户看一眼,而不能由用户决定到底允许哪一个权限。因此,用户安装应用的时候就相当于在面临两个选择: 1.用该软件,接收所有的权限请求。 2.不用该软件。

如此粗暴!当然,在6.0之前很多“深度定制”的rom内部已经集成管理权限的软件,但是毕竟不是原生的支持。在某些方面肯定不如官方支持的运行时权限。

运行时权限可以更好保护用户隐私,比如玩一个单机游戏,却想要申请读取短信的权限,那么在6.0系统中就必需要弹窗请求该权限,用户这个时候就可以点击拒绝~杜绝了滥用权限读取用户隐私的问题了。

新的权限机制将权限分成了两类:

第一类:Normal Permissions  这类权限一般不会涉及用户隐私,是不需要用户授权的。比如访问网络之类的。

第二类:Dangerous Permissions 这类权限涉及到用户隐私,需要用户授权。比如读取sd卡之类的。

而我们正是要对第二类权限进行处理,使用这些权限之前检查一下是否已经授权了,如果没有则请求权限。我们先看一下属于Dangerous Permissions的权限有哪些。

使用adb命令:adb shell pm list permissions -d -g即可进行查询

Android:6.0运行时权限解析1.运行时权限的变化二.新的权限机制的申请步骤

属于Dangerous Permissions的权限就是上面所列出来的,以后再使用这些权限之前记得进行检查申请操作。

有些读者可能已经发现了,这些权限是一组一组的。

用户在授权的时候如果已经对该组的某一个权限进行授权了,那么该组的其它权限相当于已经授权了,无需再次授权。可以这么理解,申请权限的时候是在申请该权限所在的组的权限,所以申请权限所弹出的对话框内容,也是针对该组说明的,而不是针对该权限说明的。

二.新的权限机制的申请步骤

1.添加权限:

在manifest文件中添加所需的权限,这一点跟之前的开发一样。

2.检查权限:

检查将要使用到的权限是否已经授权,这里以申请写sd卡的权限为例

if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
           

checkSelfPermission传入两个参数,第一个是一个Activity,第二个参数是要检查的权限。如果该权限已经被授权则返回 PackageManager.PERMISSION_GRANTED否则返回

PackageManager.PERMISSION_DENIED。用一个if判断当前检查的权限是否不等于PackageManager.PERMISSION_GRANTED,如果不等于则相当于还没授权这时就要对该权限进行申请,否则直接可以进行该权限的相关的操作。

3.申请授权:

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

第一个参数依然是Activity,第二个参数是一个要申请的权限字符串数组,既然是一个数组,意味着可以一次申请多个权限,系统会使用对话框对用户进行逐一询问。

第三个参数是Request_CODE。这个Request_Code跟startActivityForResult的Request_code差不多。

4.权限申请回调:

在申请授权之后系统会弹窗询问用户是否授权,授权结果会以回调的方式返回。

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 0:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    save();
                } else {
                    Toast.makeText(mContext,"用户取消授权,无法继续测试",Toast.LENGTH_LONG).show();
                }
                break;
        }
    }
           

首先要对第一个参数requestCode进行判断,定位是哪一个授权请求的返回结果。然后第二个参数是所申请的权限的字符数组,第三个是授权结果。如果申请的权限数量为2则grantResults与permissions这两个数组的长度则为2.如果申请的权限数量为一个的话则这两个数组的长度为1.

如果用户允许本次申请的第一个权限,则grantResults数组相应位置的值会为

PackageManager.PERMISSION_GRANTED
           

否则:

PackageManager.PERMISSION_DENIED

然后就可以根据所返回的结果进行相应的操作了。