Android动态权限申请封装总结

2019-02-19  本文已影响0人  d41f12d62517

最近在做公司的项目的时候,在动态权限申请这部分没有使用市面上流行的第三方库。但是在使用的时候发现每次都需要进行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

上一篇下一篇

猜你喜欢

热点阅读