当应用的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; }
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; } } } }
/** * 打开权限设置界面 */ 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