Android6.0权限适配

Android6.0引入了新的权限机制,早已有大神对此做过讲解,比如这篇文章:

http://blog.csdn.net/lmj623565791/article/details/50709663

本文对Android权限相关知识做一些其它补充。

一、 获取某个应用的权限清单(Manifest.xml中申请的权限)

 private List<String> getAppRegistPermissions(){
        List<String> permissionList = new ArrayList<>();
        try {
            PackageManager pm = getPackageManager();
            PackageInfo pack = pm.getPackageInfo(getPackageName(),PackageManager.GET_PERMISSIONS);
            String[] permissionStrings = pack.requestedPermissions;
            permissionList = Arrays.asList(permissionStrings);
            return permissionList;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return permissionList;
    }

二、检查APP是否申请了某项权限

int granted = 0;
//1、android6.0及以上
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
	granted = checkSelfPermission(permission);
}
//2、使用support包中的ContextCompat
granted = ContextCompat.checkSelfPermission(this, permission);

//3、通过PackageManager判断
PackageManager pm = getPackageManager();
granted=pm.checkPermission(permission, getPackageName());


三、适配Android6.0以上

1、在AndroidManifest文件中添加需要的权限。
2、检查权限

 private boolean hasPermission(String... permissions) {
        for (String permission : permissions) {
            int granted = ContextCompat.checkSelfPermission(this, permission);
            if(granted == PackageManager.PERMISSION_DENIED){
                return false;
            }
        }
        return true;
    }


3、申请授权

 private void requestPermissions(int reqCode, String... permissions) {
        ActivityCompat.requestPermissions(this, permissions, reqCode);
    }


4、处理权限申请回调

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
List<String> deniedPermissions = new ArrayList<>();
    for(int i=0; i<grantResults.length; i++){
      if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
        deniedPermissions.add(permissions[i]);
      }
    }

    if(deniedPermissions.size() > 0){
      //权限被拒绝
    } else {
     //权限申请成功
    }
}	


不过还有个API值得提一下:

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
        Manifest.permission.READ_CONTACTS)) 
    // Show an expanation to the user *asynchronously* -- don't block
    // this thread waiting for the user's response! After the user
    // sees the explanation, try again to request the permission.

}
     这个API主要用于给用户一个申请权限的解释,该方法只有在用户在上一次已经拒绝过你的这个权限申请。也就是说,用户已经拒绝一次了,你又弹个授权框,
你需要给用户一个解释,为什么要授权,则使用该方法。
那么将上述几个步骤结合到一起就是:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

四、权限封装

从android6.0后可以看出,权限检查、权限申请完全一致,就权限回调处理不太一样,也就是说,如果我们要做封装,难点就在于完成权限申请成功和失败的处理。然而

权限成功和失败的处理和具体业务逻辑绑定的,我们没法预先知道具体方法,这时候反射就排上用场了。在Activity或Fragment中定义我们自己的业务方法,然后在方法上使用定义好的注解来标识,这样我们就可以在申请权限后通过反射Activity或Fragment,拿到标识了权限注解的方法,进行调用。完整代码如下:

1、定义注解

权限申请成功后调用的方法

/**
 * 标识权限获取成功
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PermissionSuccess {
  int requestCode();
}


申请被用户拒绝后调用的方法
/**
 * 标识权限获取失败
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionFail {
  int requestCode();
}

2、权限工具类

public class PermissionUtil {

    public static void needPermission(Fragment context, int reqCode, String... permissions) {
        checkPermission(context, reqCode, permissions);
    }


    public static void needPermission(Activity context, int reqCode, String... permissions) {
        checkPermission(context, reqCode, permissions);
    }


    @TargetApi(Build.VERSION_CODES.M)
    private static void checkPermission(Object context, int reqCode, String... permissions) {

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            //6.0以下
            executeSuccessResult(context, reqCode);
            return;
        }
        boolean granted = hasPermission(context, permissions);//检查权限
        if (granted) {
            executeSuccessResult(context, reqCode);
        } else {
            if (context instanceof Fragment) {
                ((Fragment) context).requestPermissions(permissions, reqCode);
            } else {
                ((Activity) context).requestPermissions(permissions, reqCode);
            }
        }
    }

    private static void executeSuccessResult(Object context, int reqCode) {
        Method successMethod = getTargetMethod(context, reqCode, PermissionSuccess.class);
        try {
            successMethod.invoke(context);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void executeFailResult(Object context, int reqCode) {
        Method successMethod = getTargetMethod(context, reqCode, PermissionFail.class);
        try {
            successMethod.invoke(context);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static Method getTargetMethod(Object context, int reqCode, Class annotation) {
        Method[] declaredMethods = context.getClass().getDeclaredMethods();
        for (Method method : declaredMethods) {
            if (!method.isAccessible()) {
                method.setAccessible(true); //私有的方法必须强制
            }
            //判断方法上是否使用了目标注解
            boolean annotationPresent = method.isAnnotationPresent(annotation);
            if (annotationPresent) {
                if (isTargetMethod(method, reqCode, annotation)) { //比较requestCode是否相等
                    return method;
                }
            }
        }
        return null;
    }

    private static boolean isTargetMethod(Method method, int reqCode, Class cls) {
        if (cls.equals(PermissionSuccess.class)) {
            return reqCode == method.getAnnotation(PermissionSuccess.class).requestCode();
        } else if (cls.equals(PermissionFail.class)) {
            return reqCode == method.getAnnotation(PermissionFail.class).requestCode();
        }
        return false;
    }


    private static boolean hasPermission(Object context, String... permissions) {
        Activity activity = null;
        if (context instanceof Fragment) {
            activity = ((Fragment) context).getActivity();
        } else {
            activity = (Activity) context;
        }
        for (String permission : permissions) {
            int granted = ContextCompat.checkSelfPermission(activity, permission);
            if (granted == PackageManager.PERMISSION_DENIED) {
                return false;
            }
        }
        return true;
    }

    public static void onRequestPermissionsResult(Fragment context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        handlePermissionsResult(context, requestCode, permissions, grantResults);
    }


    public static void onRequestPermissionsResult(Activity context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        handlePermissionsResult(context, requestCode, permissions, grantResults);
    }

    private static void handlePermissionsResult(Object context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        boolean permissionGranted = true;
        for (int grant : grantResults) {
            if (grant == PackageManager.PERMISSION_DENIED) {
                permissionGranted = false;
                break;
            }
        }
        if (permissionGranted) {
            //获得权限
            executeSuccessResult(context, requestCode);
        } else {
            //权限被用户拒绝
            executeFailResult(context, requestCode);
        }
    }
}



下载完整Demo 



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值