一、简单介绍
Android 6.0在手机安全方面做的一个处理就是增加了运行时权限(Runtime Permissions)。
新的权限机制更好的保护了用户的隐私,Google将权限分为两类,正常权限(Normal Permissions)和危险权限(Dangerous Permissions)。这些概念都比较好理解,Normal Permissions 主要就是一些不涉及用户隐私的权限,比如wifi,网络,这些权限和6.0之前的权限添加方式一样,只需要在AndroidManifest.xml中添加就可以。
Dangerous Permissions又称运行时权限,这个需要在Java代码中添加是否处理的代码。
二、处理方式
1、代码中判断权限是否存在:
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
判断主要是:
public static int checkSelfPermission(@NonNull Context context, @NonNull String permission) {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
return context.checkPermission(permission, android.os.Process.myPid(), Process.myUid());
}
如果有多个权限,需要使用循环来判断,就需要封装一些判断的方法,这个方法的返回值是:
-
PackageManager.PERMISSION_GRANTED 有权限
-
PackageManager.PERMISSION_DENIED 没权限
没权限的就需要调用requestPermissions申请权限,申请时会有一个弹窗出来,点击确定或取消后,会回调下面的方法:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
在这里面就可以处理点击确定或取消的结果。
三、封装
1、自定义需要的权限数组
public static final String[] REQUIRED_PERMISSIONS = new String[]{
permission.READ_EXTERNAL_STORAGE,
permission.WRITE_EXTERNAL_STORAGE};
2、判读是否需要权限的方法
/**
* M = 6.0 = 23
* N = 7.0 = 24
* O = 8.0 = 26
*
* @return
*/
public static boolean isRequiredPermissions() {
return Build.VERSION.SDK_INT >= 23;
}
public static boolean hasPermissions(Context context, String permission) {
if (!isRequiredPermissions()) {
return true;
}
if (ContextCompat.checkSelfPermission(context, permission)
!= PackageManager.PERMISSION_GRANTED) {
return false;
}
return true;
}
public static boolean hasPermissions(Context context, String[] permissions) {
if (!isRequiredPermissions()) {
return true;
}
try {
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(context, permission)
!= PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
} finally {
}
}
3、请求权限
private void requestPermissions(Activity context) {
final ArrayList<String> unsatisfiedPermissions = new ArrayList<>();
for (String permission : Utils.REQUIRED_PERMISSIONS) {
if (Utils.hasPermissions(context, permission)) {
unsatisfiedPermissions.add(permission);
}
}
ActivityCompat.requestPermissions(context, unsatisfiedPermissions.toArray(new String[unsatisfiedPermissions.size()]),
REQUEST_CODE);
}
4、结果判断处理
public static boolean isAllGranted(String permissions[], int[] grantResult) {
for (int i = 0; i < permissions.length; i++) {
if (grantResult[i] != PackageManager.PERMISSION_GRANTED
&& isPermissionRequired(permissions[i])) {
return false;
}
}
return true;
}
public static boolean isPermissionRequired(String p) {
return Arrays.asList(REQUIRED_PERMISSIONS).contains(p);
}
注意:
当我们的minSdkVersion小于23的时候,在Activity中是不能直接使用requestPermissions方法和checkSelfPermission方法的,
而是使用ActivityCompat.requestPermissions和ContextCompat.checkSelfPermission。
上述的封装只是个人经验总结,提供一个大概的思路,欢迎提意见,感谢!