Android检查应用权限是否被禁用,解决权限被禁用时程序崩溃

一、问题描述

        在Android开发中,往往会用到许多诸如摄像头、录音等权限。但是,我们都知道,小米、魅族等定制系统,或者360等安全软件在程序请求打开相机、录音等操作时,会先弹出对话框提示用户是否允许程序执行这些操作,如果用户选择允许则接下来的操作一切正常,如果用户选择拒绝之后,程序后面的工作将无法正常允许,甚至崩溃。

        那么如何判断用户是拒绝还是允许了该权限呢?

 

二、错误的判断方式

在我到网上搜索这个问题的过程中,搜到了很多如下的判断方式,然而这其实是无效的(),先贴出代码看一下:

boolean permission = (PackageManager.PERMISSION_GRANTED == getPackageManager()
		.checkPermission("android.permission.CAMERA", getPackageName()));
if (permission) {
	Toast.makeText(this, "有这个权限", Toast.LENGTH_SHORT).show();
} else {
	Toast.makeText(this, "没有这个权限", Toast.LENGTH_SHORT).show();
}

如上,这段代码其实只是判断了你的程序是否在manifest文件中声明了某权限,并无法判断用户是否拒绝了某权限。

 

三、问题研究

当我们打开系统的应用权限管理或者安全软件的权限管理时,可以看到程序申请的权限列表,但是一些敏感权限都是有3种状态的,即“允许”、“提醒”、“禁用”。所以我们需要的不是判断权限是否在manifest文件中声明了没有,而是判断程序的权限状态到底是允许还是禁用。

然而,只有在安卓 6.0 之上才有这样的方法可以判断这个状态。

 

四、正确的解决方式

1.动态权限申请(Android 6.0 以上)

        在 onCreate() 方法中调用权限检查,如果未拥有权限则动态申请权限

    private void checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            String[] permissions = new String[]{Manifest.permission.CAMERA};
            int i = ContextCompat.checkSelfPermission(this, permissions[0]);
            if (i != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, permissions, 200);
                return;
            }
        }
    }

        还需要添加一个回调方法

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]
            grantResults) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == 200) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initFragment();
            } else {
                Toast.makeText(this, "请在设置中打开权限后继续", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivityForResult(intent, 200);
            }
        }
    }

 

2.使用 try-catch 这种暴力的解决方法吧

将相应代码 try-catch 起来,然后在catch块中提示用户打开相应权限。

 

try {
	mCamera = Camera.open(0); // 任意可能被拒绝权限程序崩溃的代码
} catch (RuntimeException e) {
	e.printStackTrace();
	Toast.makeText(getActivity(), "请打开xx权限", Toast.LENGTH_LONG).show();
}

如果是发送短信等权限,则可以通过判断短信是否发送成功判断
 

 

 

    原文作者:阿飞__
    原文地址: https://blog.csdn.net/afei__/article/details/51545653
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞