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

来源:互联网 发布:秦丝软件 编辑:程序博客网 时间:2024/05/17 01:58

当应用的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,覆写该方法进行相应处理即可。

@Overridepublic 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

阅读全文
0 0
原创粉丝点击