美文网首页
两种方式封装实现6.0上申请运行时权限

两种方式封装实现6.0上申请运行时权限

作者: zx_tree | 来源:发表于2018-01-03 16:40 被阅读0次

    1.第一种 (抽取基类+回调)

    public class PermissionActivity extends AppCompatActivity {
    
        private PermissionsResultListener mListener;
        private int mRequestCode;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        protected void checkPermissions(@NonNull String[] permissions, int requestCode, PermissionsResultListener listener) {
            List<String> permissionsList = new ArrayList<>();
            //权限不能为空
            if (permissions != null || permissions.length != 0) {
                mListener = listener;
                mRequestCode = requestCode;
                for (int i = 0; i < permissions.length; i++) {
                    if (!isHavePermissions(permissions[i])) {
                        permissionsList.add(permissions[i]);
                    } else {
                        mListener.onPermissionGranted(permissions[i]);
                    }
                }
                //遍历完后申请
                requestPermissions(permissionsList);
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == mRequestCode) {
                if (grantResults.length > 0) {
                    for (int i = 0; i < grantResults.length; i++) {
                        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            mListener.onPermissionGranted(permissions[i]);
                        } else {
                            //如果应用之前请求过此权限但用户拒绝了请求,ActivityCompat.shouldShowRequestPermissionRationale(this,permissions[i])方法将返回 true,
                            // 但实际使用过程中发现第一次出现权限对话框也会返回true,如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again 选项,
                            // 此方法将返回 false
                            if (!(ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i]))) {
                                mListener.onPermissionDeniedDontAskAgain(permissions[i]);
                            } else {
                                mListener.onPermissionDenied(permissions[i]);
                            }
    
                        }
                    }
                } else {
                    mListener.onPermissionFailure();
                }
            }
        }
    
        //判断权限是否申请
        private boolean isHavePermissions(@NonNull String permissions) {
            if (ContextCompat.checkSelfPermission(this, permissions) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
            return true;
        }
    
        //申请权限
        private void requestPermissions(List<String> permissionsList) {
            ActivityCompat.requestPermissions(this, permissionsList.toArray(new String[permissionsList.size()]), mRequestCode);
        }
    
        public interface PermissionsResultListener {
    
            //拒绝权限
            void onPermissionDenied(String permissions);
    
            //获取权限失败
            void onPermissionFailure();
    
            //成功获取权限
            void onPermissionGranted(String permissions);
    
            //拒绝了权限并且勾选了不再提示
            void onPermissionDeniedDontAskAgain(String permissions);
        }
    }
    

    在使用过程中需要将Activity继承自PermissionActivity ,并实现回调方法,如下所示

    public class MainActivity extends PermissionActivity implements PermissionActivity.PermissionsResultListener {
    
        private String TAG = "MainActivity";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            checkPermissions(new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1, this);
    
    
        }
    
        @Override
        public void onPermissionDenied(String permission) {
            switch (permission) {
                case Manifest.permission.CALL_PHONE:
                    Log.e(TAG, "拒绝了拨打电话的权限");
                    break;
                case Manifest.permission.WRITE_EXTERNAL_STORAGE:
                    Log.e(TAG, "拒绝了写存储卡的权限");
                    break;
            }
        }
    
        @Override
        public void onPermissionFailure() {
            Log.e(TAG, "申请权限失败");
        }
    
        @Override
        public void onPermissionGranted(String permission) {
            switch (permission) {
                case Manifest.permission.CALL_PHONE:
                    Log.e(TAG, "同意了拨打电话的权限");
                    break;
                case Manifest.permission.WRITE_EXTERNAL_STORAGE:
                    Log.e(TAG, "同意了写存储卡的权限");
                    break;
            }
    
        }
    
        @Override
        public void onPermissionDeniedDontAskAgain(String permission) {
            switch (permission) {
                case Manifest.permission.CALL_PHONE:
                    Log.e(TAG, "拒绝了拨打电话的权限并且不再询问");
                    break;
                case Manifest.permission.WRITE_EXTERNAL_STORAGE:
                    Log.e(TAG, "拒绝了写存储卡的权限并且不再询问");
                    break;
            }
        }
    
    }
    

    上述方法看起来通俗易懂,但是在申请的权限较多时,需要进行多次的switch语句进行判断。代码稍显多。

    第二种(注解+反射)

    1.添加两个注解

    //权限授予后执行的方法注解
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface PermissionGrantedMethod {
        public int requestCode();
    }
    
    //权限拒绝后执行的方法注解
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface PermissionDeniedMethod {
        public int requestCode();
    }
    

    2.增加权限的处理类PermissionHelper

    public class PermissionHelper {
        private Object mObject;  //Fragment or Activity
        private int mRequestCode;  //请求码
        private String[] mRequestPermissions;  //请求的权限
    
        public PermissionHelper(Object object) {
            this.mObject = object;
        }
    
        public static void requestPermission(FragmentActivity activity, int requestCode, String[] permissions) {
            PermissionHelper.with(activity).requestCode(requestCode).requestPermission(permissions).request();
        }
    
        //链式调用
        public PermissionHelper with(Fragment fragment) {
            return new PermissionHelper(fragment);
        }
    
        public static PermissionHelper with(FragmentActivity activity) {
            return new PermissionHelper(activity);
        }
    
        public PermissionHelper requestCode(int requestCode) {
            mRequestCode = requestCode;
            return this;
        }
    
        public PermissionHelper requestPermission(String... permissions) {
            mRequestPermissions = permissions;
            return this;
        }
    
        //真正实现和发起权限请求
        public void request() {
            //判断当前版本是不是6.0及以上
            if (!PermissionUtil.isOverMarshmallow()) {
                //如果不是6.0以上则直接执行方法,通过反射获取方法执行
                PermissionUtil.excuteGrantedMethod(mObject, mRequestCode);
                return;
            } else {
                //如果是6.0以上,首先判断权限是否已经授予,获取还没有授予的权限
                List<String> deniedPermissionsList = PermissionUtil.getDeniedPermissionsList(mObject, mRequestPermissions);
                if (deniedPermissionsList.size() > 0) {
                    //列表中含有没有授予的权限,则需要去请求权限
                    PermissionUtil.requestPermissions(mObject, deniedPermissionsList, mRequestCode);
    
                } else {
                    //如果权限已经授予则直接执行
                    PermissionUtil.excuteGrantedMethod(mObject, mRequestCode);
                }
            }
    
        }
    
        /**
         * 判断原来没有申请到的权限是否由用户点击授予
         *
         * @param object
         * @param requestCode
         * @param permissions
         */
        public static void requestPermissionResult(Object object, int requestCode, String[] permissions, @NonNull int[] grantResults) {
            List<String> deniedPermissionsList = new ArrayList<>();
            //表示第一次申请,或上次申请权限均拒绝
            if (permissions.length == grantResults.length) {
                deniedPermissionsList = Arrays.asList(permissions);
            } else {
                deniedPermissionsList = PermissionUtil.getDeniedPermissionsList(object, permissions);
            }
    
    
            if (deniedPermissionsList.size() == 0) {
                //用户都同意授予权限,则执行方法
                PermissionUtil.excuteGrantedMethod(object, requestCode);
            } else {
                //申请的权限中有用户不同意的,同意则执行同意的代码。需要对权限进行区分。
                List<String> grantPermissionsList = PermissionUtil.getGrantPermissionsList();
                for (int i = 0; i < grantPermissionsList.size(); i++) {
                    PermissionUtil.excuteGrantedMethod(object, requestCode, grantPermissionsList.get(i));
                }
                for (int i = 0; i < deniedPermissionsList.size(); i++) {
                    if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        PermissionUtil.excuteGrantedMethod(object, requestCode, deniedPermissionsList.get(i));
                    } else {
                        PermissionUtil.excuteDeniedMethod(object, requestCode, deniedPermissionsList.get(i));
                    }
                }
    
            }
        }
    
    
    }
    

    3.权限的辅助工具类

    public class PermissionUtil {
        private static List<String> grantPermissionsList = new ArrayList<>();
    
        public PermissionUtil() {
            throw new UnsupportedOperationException("Can not instantiated");
        }
    
        //判断当前版本是否在6.0及以上
        public static boolean isOverMarshmallow() {
            return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
        }
    
        public static void excuteGrantedMethod(Object mObject, int mRequestCode, String mRequestPermission) {
            Class clazz = mObject.getClass();
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                //反射获取带有PermissionGrantedMethod的方法
                PermissionGrantedMethod permissionGrantedMethod = method.getAnnotation(PermissionGrantedMethod.class);
                //找到了有该注解的方法
                if (permissionGrantedMethod != null) {
                    //获取注解中的请求码
                    int requestCode = permissionGrantedMethod.requestCode();
                    String requestPermission = permissionGrantedMethod.requestPermission();
                    //若注解中的请求码和传递的请求码一直,则执行这个方法
                    if (requestCode == mRequestCode && requestPermission == mRequestPermission) {
                        //反射执行该方法,第一个参数是这个方法属于哪个类,第二个参数是该方法的参数
                        excuteMethod(mObject, method);
                    }
                }
    
            }
        }
    
        public static void excuteGrantedMethod(Object mObject, int mRequestCode) {
            Class clazz = mObject.getClass();
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                //反射获取带有PermissionGrantedMethod的方法
                PermissionGrantedMethod permissionGrantedMethod = method.getAnnotation(PermissionGrantedMethod.class);
                //找到了有该注解的方法
                if (permissionGrantedMethod != null) {
                    //获取注解中的请求码
                    int requestCode = permissionGrantedMethod.requestCode();
                    //若注解中的请求码和传递的请求码一直,则执行这个方法
                    if (requestCode == mRequestCode) {
                        //反射执行该方法,第一个参数是这个方法属于哪个类,第二个参数是该方法的参数
                        excuteMethod(mObject, method);
                    }
                }
    
            }
        }
    
        /**
         * 用户拒绝了权限,则执行拒绝的方法
         *
         * @param mObject
         * @param mRequestCode
         */
        public static void excuteDeniedMethod(Object mObject, int mRequestCode, String mRequestPermission) {
            Class clazz = mObject.getClass();
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                //反射获取带有PermissionDeniedMethod的方法
                PermissionDeniedMethod permissionDeniedMethod = method.getAnnotation(PermissionDeniedMethod.class);
                //找到了有该注解的方法
                if (permissionDeniedMethod != null) {
                    //获取注解中的请求码
                    int requestCode = permissionDeniedMethod.requestCode();
                    String requestPermission = permissionDeniedMethod.requestPermission();
                    //若注解中的请求码和传递的请求码一直,则执行这个方法
                    if (requestCode == mRequestCode && requestPermission == mRequestPermission) {
                        //反射执行该方法,第一个参数是这个方法属于哪个类,第二个参数是该方法的参数
                        excuteMethod(mObject, method);
                    }
                }
            }
        }
    
        //反射执行方法
        private static void excuteMethod(Object mObject, Method method) {
            try {
                method.setAccessible(true);
                method.invoke(mObject, new Object[]{});
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 获取没有授予的权限
         *
         * @param object
         * @param requestPermissions
         * @return
         */
        public static List<String> getDeniedPermissionsList(Object object, String[] requestPermissions) {
            grantPermissionsList.clear();
            List<String> deniedPermissionsList = new ArrayList<>();
            for (String requestPermission : requestPermissions) {
                if (!isHavePermissions(object, requestPermission)) {
                    //没有申请到这个权限则将其添加到列表中
                    deniedPermissionsList.add(requestPermission);
                } else {
                    grantPermissionsList.add(requestPermission);
                }
            }
    
            return deniedPermissionsList;
        }
    
        public static List<String> getGrantPermissionsList() {
            return grantPermissionsList;
        }
    
    
        //判断权限是否申请
        private static boolean isHavePermissions(Object object, @NonNull String permission) {
            if (ContextCompat.checkSelfPermission(getActivity(object), permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
            return true;
        }
    
        private static FragmentActivity getActivity(Object object) {
            if (object instanceof Fragment) {
                return ((Fragment) object).getActivity();
            } else if (object instanceof FragmentActivity) {
                return (FragmentActivity) object;
            }
            return null;
        }
    
        //申请权限
        public static void requestPermissions(Object object, List<String> deniedPermissionsList, int requestCode) {
            ActivityCompat.requestPermissions(getActivity(object), deniedPermissionsList.toArray(new String[deniedPermissionsList.size()]), requestCode);
        }
    }
    

    4.使用框架实例

    public class SecondActivity extends AppCompatActivity {
    
        private String TAG = "MainActivity";
        private static final int CALL_PHONE_REQUEST_CODE = 0x11;
        private static final String CALL_PHONE_PERMISSION = Manifest.permission.CALL_PHONE;
        private static final String WRITE_EXTERNAL_STORAGE_PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //checkPermissions(new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1, this);
            PermissionHelper.requestPermission(this, CALL_PHONE_REQUEST_CODE, new String[]{CALL_PHONE_PERMISSION, WRITE_EXTERNAL_STORAGE_PERMISSION});
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == CALL_PHONE_REQUEST_CODE)
                PermissionHelper.requestPermissionResult(this, CALL_PHONE_REQUEST_CODE, new String[]{CALL_PHONE_PERMISSION, WRITE_EXTERNAL_STORAGE_PERMISSION}, grantResults);
        }
    
        @PermissionGrantedMethod(requestCode = CALL_PHONE_REQUEST_CODE, requestPermission = CALL_PHONE_PERMISSION)
        public void Call() {
            Log.e(TAG, "拨打电话");
        }
    
        @PermissionDeniedMethod(requestCode = CALL_PHONE_REQUEST_CODE, requestPermission = CALL_PHONE_PERMISSION)
        private void error() {
            Log.e(TAG, "拨打电话权限取消");
        }
    
        @PermissionGrantedMethod(requestCode = CALL_PHONE_REQUEST_CODE, requestPermission = WRITE_EXTERNAL_STORAGE_PERMISSION)
        private void write() {
            Log.e(TAG, "写存储卡");
        }
    
        @PermissionDeniedMethod(requestCode = CALL_PHONE_REQUEST_CODE, requestPermission = WRITE_EXTERNAL_STORAGE_PERMISSION)
        private void writeQuit() {
            Log.e(TAG, "写存储卡权限取消");
        }
    
    }
    

    目前框架还不够完善,如果我在申请权限中一个申请码对应两种以上权限,如果拒绝一种,则全部拒绝的问题。后序将修改。

    相关文章

      网友评论

          本文标题:两种方式封装实现6.0上申请运行时权限

          本文链接:https://www.haomeiwen.com/subject/rdshnxtx.html