zoukankan      html  css  js  c++  java
  • android6.0权限管理工具EasyPermissionUtil

    前言

    android6.0開始,权限的申请发生了改变,申请变的动态化,也就是执行时权限,和iOS相仿,动态化的意思是指,在每次使用须要危急权限的方法的时候。须要检查程序是否获得了该权限的许可。动态化的权限申请能够让用户更加清晰的知道程序须要什么权限。以及程序中哪些地方的操作须要涉及用户安全。

    不再是只在程序安装的时候,一次性把所须要的普通的、危急级别的权限一次性列出来。然后展示给用户。

    当project项目的target Sdk为23时,因为考虑到用户假设没有进行权限的动态检查,那么在执行到须要权限的代码时,会发生crash。而当你的target Sdk为23下面时,则不强制要求权限的动态监測,此时app不会crash。还是能够正常的使用功能。

    Google官网上动态申请权限的方法分了在Activity和Fragment这两种,通过ContextCompat以及子类,ActivityCompat和FragmentCompat去进行权限的申请和权限的检查,而申请的方式是弹出一个系统的不能够改写的对话框。结果是通过Activity和Fragment的onRequestPermissionResult()方法进行返回。
    详细能够參考官网

    可是这样的代码会促使以前的project进行大改造或者说代码的逻辑会耦合的写在同一个方法里。显的不方便和臃肿。

    所以下面的EasyPermissionUtil就是简化权限请求的方式,同一时候能够使代码的逻辑更加清晰。

    EasyPermissionUtil:简化权限请求

    因为权限的请求和结果的返回须要分开Activity和Fragment两种去进行操作,这样会比較麻烦,所以EasyPermissionUtil中投机取巧,通过开启一个新的activity进行权限申请和检查的操作。这样不用去区分多种情况,同一时候也能够把全部的申请过程和结果统一由EasyPermissionUtil进行处理。
    接下来看一下总体的思想:
    这里写图片描写叙述

    使用的方法

    PermissionUtil.getInstance().request(MainActivity.this, new String[]{Manifest.permission.READ_CALENDAR}, mRequestCode,
        new PermissionResultCallBack() {
            @Override
            public void onPermissionGranted() {
                // 当全部权限的申请被用户允许之后,该方法会被调用
            }
    
            @Override
            public void onPermissionDenied(String... permissions) {
                // 当权限申请中的某一个或多个权限,被用户以前否定了,并确认了不再提醒时,也就是权限的申请窗体不能再弹出时,该方法将会被调用
            }
    
            @Override
            public void onRationalShow(String... permissions) {
                // 当权限申请中的某一个或多个权限,被用户否定了,但没有确认不再提醒时,也就是权限窗体申请时,但被否定了之后,该方法将会被调用.
            }
        });

    项目源代码下载以及介绍。请看github。

    项目源代码

    在PermissionUtil中,要做的是:
    1.进行权限检查
    2.没有得到权限许可的进行权限申请
    3.返回权限申请的结果

    public class PermissionUtil {
    
        private PermissionResultCallBack mPermissionResultCallBack;
        private volatile static PermissionUtil instance;
        private int mRequestCode;
        private Context mContext;
        private Fragment mFragment;
        private List<PermissionInfo> mPermissionListNeedReq;
        private String[] mPermissions;
    
        public static PermissionUtil getInstance() {
            if (instance == null) {
                synchronized (PermissionUtil.class) {
                    if (instance == null) {
                        instance = new PermissionUtil();
                    }
                }
            }
            return instance;
        }
    
        /**
         * 用于fragment中请求权限
         * @param fragment
         * @param permissions
         * @param requestCode
         * @param callBack
         */
        public void request(@NonNull Fragment fragment,@NonNull String[] permissions,@NonNull int requestCode, PermissionResultCallBack callBack) {
            this.mFragment = fragment;
            this.request(fragment.getActivity(), permissions, requestCode, callBack);
        }
    
        /**
         * 用于activity中请求权限
         * @param context
         * @param permissions
         * @param requestCode
         * @param callBack
         */
        public void request(@NonNull Context context,@NonNull String[] permissions,@NonNull int requestCode, PermissionResultCallBack callBack) {
    
            if (Looper.myLooper() != Looper.getMainLooper()) {
                throw new RuntimeException("request permission only can run in MainThread!");
            }
    
            if (permissions.length == 0) {
                return;
            }
    
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                onGranted();
                return;
            }
    
            this.mContext = context;
            this.mPermissions = permissions;
            this.mRequestCode = requestCode;
            this.mPermissionResultCallBack = callBack;
            this.mPermissionListNeedReq = new ArrayList<PermissionInfo>();
    
            if (needToRequest()) {
                requestPermissions();
            } else {
                onGranted();
            }
        }
    
        /**
         * 通过开启一个新的activity作为申请权限的媒介
         */
        private void requestPermissions() {
    
            Intent intent = new Intent(mContext, HelpActivity.class);
            intent.putExtra("permissions", mPermissions);
            intent.putExtra("requestCode", mRequestCode);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        }
    
        /**
         * 检查是否须要申请权限
         * @return
         */
        private boolean needToRequest() {
            for (String permission : mPermissions) {
                int checkRes = ContextCompat.checkSelfPermission(mContext, permission);
                if (checkRes != PackageManager.PERMISSION_GRANTED) {
                    PermissionInfo info = new PermissionInfo(permission);
                    if (mContext instanceof Activity &&
                            ActivityCompat.shouldShowRequestPermissionRationale((Activity) mContext, permission)) {
                        info.setRationalNeed(true);
                    }
                    mPermissionListNeedReq.add(info);
                }
            }
    
            if (mPermissionListNeedReq.size() > 0) {
                mPermissions = new String[mPermissionListNeedReq.size()];
                for (int i = 0; i < mPermissionListNeedReq.size(); i++) {
                    mPermissions[i] = mPermissionListNeedReq.get(i).getName();
                }
                return true;
            }
    
            return false;
        }
    
        /**
         * 申请权限结果返回
         * @param requestCode
         * @param permissions
         * @param grantResults
         */
        @TargetApi(Build.VERSION_CODES.M)
        protected void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
    
            if (requestCode == mRequestCode) {
    
                if (mContext != null && mContext instanceof Activity) {
                    ((Activity) mContext).onRequestPermissionsResult(requestCode, permissions, grantResults);
                }
    
                if (mFragment != null) {
                    mFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
                }
    
                boolean isAllGranted = true;
                List<PermissionInfo> needRationalPermissionList = new ArrayList<PermissionInfo>();
                List<PermissionInfo> deniedPermissionList = new ArrayList<PermissionInfo>();
                for (int i = 0; i < permissions.length; i++) {
                    if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                        if (mPermissionListNeedReq.get(i).isRationalNeed()) {
                            needRationalPermissionList.add(mPermissionListNeedReq.get(i));
                        } else {
                            deniedPermissionList.add(mPermissionListNeedReq.get(i));
                        }
                        isAllGranted = false;
                    }
                }
    
                if (needRationalPermissionList.size() != 0) {
                    showRational(needRationalPermissionList);
                }
    
                if (deniedPermissionList.size() != 0) {
                    onDenied(deniedPermissionList);
                }
    
                if (isAllGranted) {
                    onGranted();
                }
    
            }
        }
    
        /**
         * 权限被用户许可之后回调的方法
         */
        private void onGranted() {
            if (mPermissionResultCallBack != null) {
                mPermissionResultCallBack.onPermissionGranted();
            }
        }
    
        /**
         * 权限申请被用户否定之后的回调方法,这个主要是当用户点击否定的同一时候点击了不在弹出,
         * 那么当再次申请权限,此方法会被调用
         * @param list
         */
        private void onDenied(List<PermissionInfo> list) {
            if(list == null || list.size() == 0) return;
    
            String[] permissions = new String[list.size()];
            for (int i = 0; i < list.size(); i++) {
                permissions[i] = list.get(i).getName();
            }
    
            if (mPermissionResultCallBack != null) {
                mPermissionResultCallBack.onPermissionDenied(permissions);
            }
        }
    
        /**
         * 权限申请被用户否定后的回调方法,这个主要场景是当用户点击了否定,但未点击不在弹出,
         * 那么当再次申请权限的时候,此方法会被调用
         * @param list
         */
        private void showRational(List<PermissionInfo> list) {
            if(list == null || list.size() == 0) return;
    
            String[] permissions = new String[list.size()];
            for (int i = 0; i < list.size(); i++) {
                permissions[i] = list.get(i).getName();
            }
    
            if (mPermissionResultCallBack != null) {
                mPermissionResultCallBack.onRationalShow(permissions);
            }
        }
    
    }

    在PermissionResutCallBack中,要做的是:
    1.返回相应的结果

    public interface PermissionResultCallBack {
    
        /**
         * 当全部权限的申请被用户允许之后,该方法会被调用
         */
        void onPermissionGranted();
    
        /**
         * 当权限申请中的某一个或多个权限,被用户以前否定了,并确认了不再提醒时,也就是权限的申请窗体不能再弹出时,
         * 该方法将会被调用
         * @param permissions
         */
        void onPermissionDenied(String... permissions);
    
        /**
         * 当权限申请中的某一个或多个权限,被用户否定了,但没有确认不再提醒时,也就是权限窗体申请时,但被否定了之后,
         * 该方法将会被调用.
         * @param permissions
         */
        void onRationalShow(String... permissions);
    }

    在HelpActivity中。要做的就是:
    1.申请权限
    2.通过onRequestPermissionUtil返回结果给PermissionUtil
    当然这个activity必须是透明的,并且是没有不论什么的view的。这样看起来才不像是开了一个新的activity。

    public class HelpActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (savedInstanceState == null) {
                handleIntent(getIntent());
            }
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            handleIntent(intent);
        }
    
        // 权限申请
        @TargetApi(Build.VERSION_CODES.M)
        private void handleIntent(Intent intent) {
            String[] permissions = intent.getStringArrayExtra("permissions");
            int requestCode = intent.getIntExtra("requestCode", 42);
            ActivityCompat.requestPermissions(this, permissions, requestCode);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
        }
    
        // 返回结果
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            PermissionUtil.getInstance().onRequestPermissionResult(requestCode, permissions, grantResults);
            finish();
        }
    }

    项目源代码下载以及介绍。请看github。

  • 相关阅读:
    java设计模式----工厂模式
    使用.Net Core Mvc +SqlSugar +Autofac+AutoMapper+....
    使用 Date 和 SimpleDateFormat 类表示时间
    .Net Core 3.0 IdentityServer4 快速入门02
    .Net Core 3.0 IdentityServer4 快速入门
    微信小程序支付
    微信小程序集成腾讯云 IM SDK
    架构杂谈《十》
    架构杂谈《九》
    架构杂谈《八》
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7300667.html
Copyright © 2011-2022 走看看