美文网首页
Android动态权限申请封装总结

Android动态权限申请封装总结

作者: d41f12d62517 | 来源:发表于2019-02-19 11:37 被阅读0次

    最近在做公司的项目的时候,在动态权限申请这部分没有使用市面上流行的第三方库。但是在使用的时候发现每次都需要进行onRequestPermissionsResult 的回调,感觉比较的烦躁。想到RxPermission 这些第三方库没有在Activity中回调,就尝试的用一个透明的Fragment来做中转代理。

    最终实现的目的就是要方便维护并且与Activty解耦,所实现的效果是:

    PermissionHelper.getInstance().init(this)
                    .setmRequestCallback(new ICallbackManager.IRequestCallback() {
                        @Override
                        public void onAllPermissonGranted(boolean flag) {
                            hasPermission = true;
                            checkLicense();
                        }
                    })
                    .setmDenyPermissionCallback(new ICallbackManager.IDenyPermissionCallback() {
                        @Override
                        public void onDenyPermissions(List<String> permissions) {
                            PermissionHelper.getInstance().requestPermissions(permissions.toArray(new String[permissions.size()]));
                        }
                    })
                    .checkPermission(Manifest.permission.CAMERA,
                            Manifest.permission.READ_EXTERNAL_STORAGE,
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            Manifest.permission.READ_PHONE_STATE,
                            Manifest.permission.ACCESS_COARSE_LOCATION,
                            Manifest.permission.ACCESS_FINE_LOCATION);
    

    创建代理Fragment

    创建一个没有布局的 Fragment ,用于接收回调函数 onRequestPermissionsResult

    public class PermissionFragment extends Fragment {
    
        private static final int MAX_TRY_COUNT = 10; //requesCode 刷新次数
        private FragmentActivity mActivity;
    
        private SparseArray<ICallbackManager.IPermissionListCallback> mListCallbacks = new SparseArray<>();
        private Random mCodeGenerator = new Random();
    
        public PermissionFragment() {
        }
    
        public static PermissionFragment getInstance() {
            return new PermissionFragment();
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setRetainInstance(true);
            mActivity = getActivity();
        }
    
        private int createRequestCode() {
            int requestCode;
            int tryCount = 0;
            do {
                requestCode = mCodeGenerator.nextInt(0x0000FFFF);
                tryCount++;
            } while (mListCallbacks.indexOfKey(requestCode) >= 0 && tryCount < MAX_TRY_COUNT);
    
            return requestCode;
        }
    
        /**
         * 查询权限是否申请
         *
         * @param permissions
         */
        public void checkPermission(ICallbackManager.IPermissionListCallback listCallback, String... permissions) {
    
            ArrayList<String> requestPermissionList = new ArrayList<>();
            ArrayList<String> denyPermissionList = new ArrayList<>();
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                int grs = 0;
                for (String permission : permissions) {
                    int permissionStatus = (int) ContextCompat.checkSelfPermission(mActivity, permission);
                    grs += permissionStatus;
                    if (permissionStatus != PackageManager.PERMISSION_GRANTED) {
    
                        if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permission)) {
                            //之前用户禁止过该权限,提示用户权限用处,以及是否重新去开启
                            denyPermissionList.add(permission);
                        } else {
                            requestPermissionList.add(permission);
                        }
    
                    }
                }
    
                if (grs == 0) { //全部已经授权过,不必再申请
                    listCallback.onResultCallback(null);
                }
    
                if (!requestPermissionList.isEmpty()) {
                    requestPermissions(requestPermissionList.toArray(new String[requestPermissionList.size()]), listCallback);
                }
    
                if (!denyPermissionList.isEmpty()) {
                    listCallback.onCheckResultCallback(denyPermissionList);
                }
    
            } else { //不需要申请权限
                listCallback.onResultCallback(null);
            }
    
        }
    
        public void requestPermissions(@NonNull String[] permissions, ICallbackManager.IPermissionListCallback listCallback) {
            int requestCode = createRequestCode();
            mListCallbacks.put(requestCode, listCallback);
            requestPermissions(permissions, requestCode);
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            handlePermissionCallback(requestCode, permissions, grantResults);
        }
    
        private void handlePermissionCallback(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            ICallbackManager.IPermissionListCallback callback = mListCallbacks.get(requestCode);
    
            if (null == callback) {
                return;
            }
    
            mListCallbacks.remove(requestCode);
    
            int length = grantResults.length;
            ArrayList<Permission> needSetPermissions = new ArrayList<>();
    
            for (int i = 0; i < length; i++) {
    
                String permission = permissions[i];
                int grantResult = grantResults[i];
    
                needSetPermissions.add(new Permission(
                        permission,
                        grantResult == PackageManager.PERMISSION_GRANTED,
                        ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permission)
                ));
    
            }
    
            callback.onResultCallback(needSetPermissions);
        }
    }
    

    创建调用的辅助类

    public class PermissionHelper {
    
        private static final String REQUEST_PERMISSION = "request_permission";
        private static FragmentActivity mActivity;
    
        private ICallbackManager.IDenyPermissionCallback mDenyPermissionCallback;
        private ICallbackManager.IRequestCallback mRequestCallback;
    
        private static class Holder{
            private static PermissionHelper INSTANCE = new PermissionHelper();
        }
    
        public PermissionHelper() {
        }
    
        public static PermissionHelper getInstance(){
            return Holder.INSTANCE;
        }
    
        public PermissionHelper init(FragmentActivity activity) {
            mActivity = activity;
            return Holder.INSTANCE;
        }
    
        private PermissionFragment getFragment() {
            FragmentManager manager = mActivity.getSupportFragmentManager();
            PermissionFragment fragment = (PermissionFragment) manager.findFragmentByTag(REQUEST_PERMISSION);
    
            if (null == fragment) {
                fragment = PermissionFragment.getInstance();
                manager.beginTransaction()
                        .add(fragment, REQUEST_PERMISSION)
                        .commitAllowingStateLoss();
                manager.executePendingTransactions(); //立即执行 commit 的事务
            }
    
            return fragment;
        }
    
        public PermissionHelper setmDenyPermissionCallback(ICallbackManager.IDenyPermissionCallback mDenyPermissionCallback) {
            this.mDenyPermissionCallback = mDenyPermissionCallback;
            return Holder.INSTANCE;
        }
    
        public PermissionHelper setmRequestCallback(ICallbackManager.IRequestCallback mRequestCallback) {
            this.mRequestCallback = mRequestCallback;
            return Holder.INSTANCE;
        }
    
        /**
         * 打开设置页面打开权限
         *
         * @param context
         */
        public void startSettingActivity(@NonNull Activity context) {
    
            try {
                Intent intent =
                        new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" +
                                context.getPackageName()));
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                context.startActivity(intent);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 查询权限是否开启,如果有提醒禁止再次提醒,则跳转到设置页面
         *
         * @param permissions
         */
        public void checkPermission(String... permissions) {
    
            getFragment().checkPermission(new ICallbackManager.IPermissionListCallback() {
                @Override
                public void onResultCallback(List<Permission> permissions) {
                    boolean granted = true;
                    if(null != permissions){
                        for (Permission permission : permissions) {
                            if (!permission.granted) {
                                granted = permission.granted;
                                break;
                            }
                        }
                    }
                    if (null != mRequestCallback) {
                        mRequestCallback.onAllPermissonGranted(granted);
                    }
                }
    
                @Override
                public void onCheckResultCallback(List<String> permissions) {
    
                    if (null != mDenyPermissionCallback) {
                        mDenyPermissionCallback.onDenyPermissions(permissions);
                    }
    
                }
            }, permissions);
        }
    
        /**
         * 请求权限
         * @param permissions
         */
        public void requestPermissions(String...permissions){
            getFragment().requestPermissions(permissions, new ICallbackManager.IPermissionListCallback() {
                @Override
                public void onResultCallback(List<Permission> permissions) {
                    boolean granted = true;
                    if(null != permissions){
                        for (Permission permission : permissions) {
                            if (!permission.granted) {
                                granted = permission.granted;
                                break;
                            }
                        }
                    }
                    if (null != mRequestCallback) {
                        mRequestCallback.onAllPermissonGranted(granted);
                    }
                }
    
                @Override
                public void onCheckResultCallback(List<String> permissions) {
                    if (null != mDenyPermissionCallback) {
                        mDenyPermissionCallback.onDenyPermissions(permissions);
                    }
                }
            });
        }
    
    }
    

    在这一步的时候出现了调用 Fragment的一些错误,都显示 Fragment 没有attach Activity。最后网上资料搜索一波,最后在 getFragment 方法中加入 manager.executePendingTransactions(); //立即执行 commit 的事务。这个地方暂时还没有理解得很透彻,有知道详细原因的大神指点一下。

    最后

    因为项目的权限请求场景并不复杂,所以通过简单的封装可以达到目的,第三方的库总感觉很沉重复杂,在本项目中用就有点大材小用了。

    demo下载地址:</br>
    https://github.com/qinhaihang/permission
    </br>项目新增 gradle引入方式:

    1. 在项目的root build.gradle 中添加:
        allprojects {
            repositories {
                ...
                maven { url 'https://jitpack.io' }
            }
        }
    
    1. 在引入的 module 中添加依赖
        dependencies {
                implementation 'com.github.qinhaihang:permission:Tag'
        }
    
    

    参考的文章:
    https://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650245064&idx=1&sn=0b8519202fe165be0464dafe960ff7a5&chksm=886376a7bf14ffb1ea10944b32e7d4c04e1647b9e54d11ec037ac466c4f900f65dcfea046159&scene=0#rd

    相关文章

      网友评论

          本文标题:Android动态权限申请封装总结

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