Android6.0运行是权限在某些手机适配问题(小米手机)

当应用的targtSdkVersion小于23时,即便运行在android6.0及以上设备,ContextWrapper.checkSelfPermission和Context.checkSelfPermission失效,返回值始终为PERMISSION_GRANTED,

这时必须要用PermissionChecker.checkSelfPermission

来检查手机权限。

检查是否具有权限主要涉及3个方法: 

1、ContextWrapper.checkSelfPermission和Context.checkSelfPermission 
只有Build.VERSION.SDK_INT>=23才能调用,且targetSdkVersion>=23结果才有效。

因此在targetSdkVersion<23时要用PermissionChecker.checkSelfPermission。 
2、PermissionChecker.checkPermission 
当在小米4.4上用户手动改变权限后,再次检查权限返回结果有误。适用于Android6.0以上的权限判断。

小米4.4需要使用AppOpsManager的权限检验方法。 
综上:以上两种,优先选择PermissionChecker.checkPermission。 
3、AppOpsManager 
为了兼容小米4.4用户可以改变权限的情况,只能使用AppOpsManager。

(其实PermissionChecker.checkPermission底层用了Context.checkPermission和AppOpsManager)用法如下:

private boolean checkPermissionForXiaomi(){
    AppOpsManager manager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);

    try {

        Method method = manager.getClass().getDeclaredMethod("checkOp", int.class, int.class, String.class);
        int property = (Integer) method.invoke(manager, 26,
            Binder.getCallingUid(), getPackageName());

        if (AppOpsManager.MODE_ALLOWED == property) {
            return true;
        } else {
            return false;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return false;
}

三、请求权限API

请求权限主要涉及shouldShowRequestPermissionRationale和requestPermissions方法,用法如下:

if (checkPermissions()) {
    Toast.makeText(this,"已经获取权限",Toast.LENGTH_SHORT).show();
} else {
    Log.d("haha", "no permission.");
    //请求权限
    if (Build.VERSION.SDK_INT < 23) return;
    if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {//上次请求权限被拒绝
        //这里一般自定义一个界面告知用户为何需要此权限
        //一般手机还是会弹出用户授权界面,但小米4.4对此作了处理  需通过intent跳转到对应的权限管理界面
        //requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
    } else {
        requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
    }

}
private boolean checkPermissions(){
    if (Build.VERSION.SDK_INT < 23) {//一般android6以下会在安装时自动获取权限,但在小米机上,可能通过用户权限管理更改权限
        return true;
    }else {

        if (getApplicationInfo().targetSdkVersion < 23) {
            //targetSdkVersion<23时 即便运行在android6及以上设备 ContextWrapper.checkSelfPermission和Context.checkSelfPermission失效
            //返回值始终为PERMISSION_GRANTED
            //此时必须使用PermissionChecker.checkSelfPermission

            if (PermissionChecker.checkPermission(this, Manifest.permission.CAMERA, Binder.getCallingPid(), Binder.getCallingUid(), getPackageName()) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                return false;
            }

        } else {

            if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                return false;

            }
        }
    }

}

1、shouldShowRequestPermissionRationale 
上一次请求被拒绝则返回true,此时开发者应该有一个页面说明请求权限的原因。 
2、requestPermissions 
会直接到用户授权界面,注意小米4.4有自己的权限管理设置,这里不会弹出权限界面,需要作特殊处理直接跳转到对应的设置界面。如下

/**
 * 打开权限设置界面
 */
public void openXiaomiSetting() {
    try {
        Intent localIntent = new Intent(
            "miui.intent.action.APP_PERM_EDITOR");
        localIntent.setClassName("com.miui.securitycenter",
            "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
        localIntent.putExtra("extra_pkgname", getPackageName());
        startActivityForResult(localIntent, 2);
    } catch (ActivityNotFoundException localActivityNotFoundException) {
        Intent intent1 = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent1.setData(uri);
        startActivityForResult(intent1, 2);
    }

}
3、用户授权结果的回调是onRequestPermissionsResult,覆写该方法进行相应处理即可。

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    //权限处理结果的回调
    switch (requestCode){
        case 1:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                Log.d("haha",permissions[0]+" granted.");
                Toast.makeText(this,"获取权限成功!",Toast.LENGTH_SHORT).show();
            }
            break;
        case 2:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                Log.d("haha",permissions[0]+" granted.");
                Toast.makeText(this,"小米获取权限成功!",Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            break;
    }
}

注:经测试特殊权限只能用AppOpsManager

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值