Android 6.0(权限申请)反射和注解实现权限封装

Android 6.0(权限申请)反射和注解实现权限封装

    • 概述
    • 未封装是怎么样的
    • 框架封装

概述

成年人也是过期的小朋友!大家六一儿童节快乐呀,写过Android 6.0权限RxPermission的使用和源码解析,还没写过Android 原生方式实现Android 6.0权限申请,今天我们就用原生的代码用反射+注解的方式对权限进行封装,话不多说直接上代码。

未封装是怎么样的

public class Test1 extends AppCompatActivity {
    TextView tv_call_phone;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.permissions_test1);
        tv_call_phone = findViewById(R.id.tv_call_phone);
        tv_call_phone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (ContextCompat.checkSelfPermission(Test1.this,Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(Test1.this,new String[]{"Manifest.permission.CALL_PHONE"},0);
                }
                else{
                    callPhone();
                }

            }
        });
    }
    public void callPhone(){
        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri parse = Uri.parse("tel:" + "130xxxxxxxx");
        intent.setData(parse);
        startActivity(intent);
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode==0){
            if(grantResults!=null&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
                callPhone();
            }
            else{
                Toast.makeText(this,"权限被拒绝了",Toast.LENGTH_SHORT).show();
            }
        }
    }
}

以上代码并没有做过任何处理,如果每次申请权限的地方都需要这么做,那就比较麻烦了,那么我们肯定要对点击事件中的代码和onRequestPermissionsResult()里面的代码进行处理,那么要处理成什么样子?接下来看洛

框架封装

  1. 传递什么参数 :第一个利用反射来做的话,肯定要传反射类this,第二个请求码,第三个权限组
  2. 调用方式 :这里我们可以用静态方法把参数全传过去,这里我们采用链式调用的方式,比如Okhttp,Gilde,甚至是Android的AlertDialog都是使用的这个方式

这里我们先定义两个注解一个请求权限成功的注解PermissionSucceed,一个请求权限失败的注解PermissionFail,关于注解的这里我不多解析,不了解的可以去网上看看

@Target({ElementType.METHOD}) //作用于方法上
@Retention(RetentionPolicy.RUNTIME)//表示运行时注解
public @interface PermissionSucceed {
    int requestCode();
}
@Target(ElementType.METHOD)//作用于方法上
@Retention(RetentionPolicy.RUNTIME)////表示运行时注解
public @interface PermissionFail {
    int requestCode();
}

定义完注解后,接下来我们来实现构建我们的链式调用,使用链式调用呢,可以让我们代码看起来更简洁,调用的时候一行代码搞定

public class PermissionHelper {
    private Object object;
    private int code;
    private String []mRequestPermission;
    private PermissionHelper(Object object){
        this.object=object;
    }
    public static PermissionHelper with(Activity activity){
        return new PermissionHelper(activity);
    }
    public static PermissionHelper with(Fragment fragment){
        return new PermissionHelper(fragment);
    }
    public PermissionHelper requstCode(int requestCode){
        this.code=requestCode;
        return this;
    }
    public PermissionHelper requstPermission(String... mRequestPermission){
        this.mRequestPermission=mRequestPermission;
        return this;
    }
    public void requst(){
        if(!PermissionUtils.isOverMarshmallow()){
            PermissionUtils.executeSucceedMethod(object,code);
            return;
        }
        List deniedPermissions = PermissionUtils.
                getDeniedPermissions(object, mRequestPermission);
        //直接授权通过
        if(deniedPermissions.size()==0){
            PermissionUtils.executeSucceedMethod(object,code);
        }
        //没授权通过
        else{
            ActivityCompat.requestPermissions(Utils.getActivity(object),mRequestPermission,code);
        }
    }
    public static void requestPermissionsResult(Object object,int requestCode,String [] permission){
        List deniedPermissions = PermissionUtils.getDeniedPermissions(object, permission);
        if(deniedPermissions.size() == 0){
            // 权限用户都同意授予了
            PermissionUtils.executeSucceedMethod(object,requestCode);
        }else{
            // 你申请的权限中 有用户不同意的
            PermissionUtils.executeFailMethod(object,requestCode);
        }

    }
}

上面代码所用到的PermissionUtils工具类

public class PermissionUtils {
    /**
     * 执行成功的方法
     */
    public static void executeSucceedMethod(Object object,int requestCode){
        Class aClass = object.getClass();
        // 获取class中多有的方法
        Method[] declaredMethods = aClass.getDeclaredMethods();
        // 遍历找到我们打了注解的方法
        for(Method method:declaredMethods){
            //判断方法上是否打了PermissionSucceed注解
            if(method.isAnnotationPresent(PermissionSucceed.class)){
                //获取该注解的一些类,并获取注解里面的值
                PermissionSucceed annotation = method.getAnnotation(PermissionSucceed.class);
                int i = annotation.requestCode();
                if(i==requestCode){
                    //设置方法的一个访问权限
                    method.setAccessible(true);
                    try {
                        //反射执行该方法
                        method.invoke(object,null);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }


            }
        }
    }
    //执行失败的方法
    public static void executeFailMethod(Object object,int requestCode){
        Class aClass = object.getClass();
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for(Method method:declaredMethods){
            if(method.isAnnotationPresent(PermissionFail.class)){
                PermissionFail annotation = method.getAnnotation(PermissionFail.class);
                int i = annotation.requestCode();
                if(i==requestCode){
                    method.setAccessible(true);
                    try {
                        method.invoke(object,null);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }

            }
        }
    }
    // 获取没有授予过得权限
    @SuppressLint("NewApi")
    public static List getDeniedPermissions(Object object, String... permission){
        List deniedPermission=new LinkedList<>();
        for(String list:permission){
            if(object instanceof Activity){
                if(((Activity)object).checkSelfPermission(list)!= PackageManager.PERMISSION_GRANTED){
                    deniedPermission.add(list);
                }
            }
            else{
                if(((Fragment)object).getActivity().checkSelfPermission(list)!= PackageManager.PERMISSION_GRANTED){
                    deniedPermission.add(list);
                }
            }
        }
        return deniedPermission;
    }
    //Android 6.0的判断
    public static boolean isOverMarshmallow() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
    }
    //将传过来的Object进行转换
    public static Activity getActivity(Object object){
        if(object instanceof Activity){
            return (Activity) object;
        }
        else{
            ((Fragment)object).getActivity();
        }
        return null;
    }
}

最后Activity如何使用

public class Test2 extends AppCompatActivity {
    TextView tv_call_phone;
    // 打电话权限申请的请求码
    private static final int CALL_PHONE_REQUEST_CODE = 0x0011;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.permissions_test1);
        tv_call_phone=findViewById(R.id.tv_call_phone);
        tv_call_phone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            PermissionHelper.with(Test2.this).requstCode(CALL_PHONE_REQUEST_CODE).requstPermission(Manifest.permission.CALL_PHONE).requst();
            }
        });
    }

    @PermissionSucceed(requestCode = CALL_PHONE_REQUEST_CODE)
    public void callPhone(){
        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri parse = Uri.parse("tel:" + "130xxxxxxxx");
        intent.setData(parse);
        startActivity(intent);
    }
    @PermissionFail(requestCode = CALL_PHONE_REQUEST_CODE)
    public void callPhoneFaill(){
        Toast.makeText(Test2.this,"拒绝了",1000).show();
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionHelper.requestPermissionsResult(this,requestCode,permissions);
    }
}

参考: Android 6.0(权限申请)基于Rxjava2的RxPermissions2的使用.
参考: Android 6.0(权限申请)RxPermission2源码解析.

你可能感兴趣的:(权限申请,权限封装,注解放射,android)