Android 6.0 运行时权限机制了解与应用

  目前的安卓手机系统版本普遍都在5.0、6.0以上甚至7.0、8.0。在Andorid 6.0系统之后开始引入了运行时权限这个机制。权限机制在android中原本就有的在manifest中编写的permission标签,而新增的运行时权限则是将容易暴露用户隐私的一些权限列为危险权限,在程序需要的时候向用户请求是否提供权限从而保护用户隐私。简单的讲就是为了更好的保护用户的安全和隐私。

  市面上很多软件都存在滥用权限的行为,在安装软件时就发现安装列表上申请了一大堆的权限,不管是用不用的到的一股脑的全部先申请个遍可谓未雨绸缪。这种情况下在Android6.0以前如果用户不满意其中一个权限拒绝了授予权限就会导致整个app都没法正常安装使用,而若是Android6.0以后部分危险权限可以先不申请,通过代码在需要的地方请求用户进行授权,这就可以避免一些权限滥用以及部分权限不授权就无法使用app其他功能的情况。

  权限被分为了正常权限、危险权限还有特殊权限。所有的危险的Android系统权限都属于权限组,申请了某一权限组中的某一个权限就等于申请了该权限组中的所有权限。对于这些分类的描述在官方文档中都可以找的到,你可以访问http://developer.android.com/reference/andorid/Manifest.permission.html可以查看权限分类(不过这个貌似要fq),当然如果不能fq或者看不懂英文也可以通过Android官方文档中文网查看。下图为危险权限及权限组列表:

Android 6.0 运行时权限机制了解与应用

Android 6.0 运行时权限机制了解与应用

其实没必要去记有多少权限,哪些是危险的哪些是普通的,需要用到的时候查一下表对照一下就可以,如果要申请的权限属于危险权限则需要进行运行时权限处理,如果是普通权限只要在manifest中声明权限即可。

接下来以一个demo来看看如何进行运行时权限处理:

先创建一个项目,添加一个按钮

Android 6.0 运行时权限机制了解与应用

Android 6.0 运行时权限机制了解与应用

在as3.0版本这样写编译时就提示需要检查权限申请问题,我们直接alt+enter自动补全看一下

Android 6.0 运行时权限机制了解与应用

不得不说as很好用呢,直接自动补全了检查权限的if语句,我们添加log进行打印判断,若打印出该log则我们目前是没有权限拨打电话的。

Android 6.0 运行时权限机制了解与应用

运行完点击一下,可以看到我们目前是没有权限的,这时我们就需要开始处理运行时权限的申请。

当然刚刚的代码需要稍微整理一下逻辑,申请完权限之后记得要在onRequestPermissionsResult中处理返回的结果。

public class MainActivity extends AppCompatActivity {
    public static final int REQUSTCODE = 1;
    Button btn_call;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_call = findViewById(R.id.btn_call);

        btn_call.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ActivityCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling
                    //    ActivityCompat#requestPermissions
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for ActivityCompat#requestPermissions for more details.
                    Log.i("test","call permission denial");
                    ActivityCompat.requestPermissions(MainActivity.this,new String[]{
                            Manifest.permission.CALL_PHONE
                    },REQUSTCODE);
                }else{
                    call();
                }

            }
        });
    }

    /**
     * 调起拨打电话
     */
    public void call() {
        try{
            Intent intent = new Intent(Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel:10086"));
            startActivity(intent);
        }catch (SecurityException e){
            e.printStackTrace();
        }

    }

    /**
     * 申请权限后返回界面处理结果
     * @param requestCode 请求码
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        switch (requestCode){
            case REQUSTCODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
                {
                    call();
                }else{
                    Toast.makeText(MainActivity.this,"permisson denial",
                            Toast.LENGTH_SHORT).show();
                }
                break;
                default:break;
        }
    }
}

运行之后就可以看一下效果

Android 6.0 运行时权限机制了解与应用

点击允许之后就开始拨打电话了

Android 6.0 运行时权限机制了解与应用

此demo为个人练手用途,需要demo的可以点击传送门