美文网首页Android开发Android开发我爱编程
EasyPermissions Android权限适配(带流程图

EasyPermissions Android权限适配(带流程图

作者: 爱抖腿的飞飞 | 来源:发表于2018-05-26 14:55 被阅读109次

    前言

    阅读前说明:

    • 所有系统均为Android原生系统,其他国产ROM最后再讨论。
    • 所有的申请都为主动触发,即主动点击申请按钮。
    • 申请时,默认是没有权限的。
    • 流程图中长方形中为方法名。

    流程图

    申请单个权限流程图

    img

    申请权限组流程图

    img

    申请混合权限(单个权限+权限组)流程图

    具体流程=单个权限流程图+权限组流程图
    代码中有例子,就不详细说明了。

    EasyPermissions使用

    easypermissions

    1. 依赖
    dependencies {
        implementation 'pub.devrel:easypermissions:1.2.0'
    }
    
    1. 检查权限并申请权限
        public static final int PERMISSION_STORAGE_CODE = 10001;
        public static final String PERMISSION_STORAGE_MSG = "此app需要获取SD卡读取权限";
        public static final String[] PERMISSION_STORAGE = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};
    
        public static boolean hasPermissions(Context context, String... permissions) {
            return EasyPermissions.hasPermissions(context, permissions);
        }
    
    
        /**
         * 是否有SD卡权限
         *
         * @param context
         * @return
         */
        public static boolean hasStoragePermission(Context context) {
            return hasPermissions(context, PERMISSION_STORAGE);
        }
    
        @AfterPermissionGranted(PERMISSION_STORAGE_CODE)
         public void initSimple() {
              if (hasStoragePermission(context)) {
                 //有权限
             } else {
                 //申请权限
                 EasyPermissions.requestPermissions(context, PERMISSION_STORAGE_MSG, PERMISSION_STORAGE_CODE, PERMISSION_STORAGE);
             }
         }
    
    
    1. 实现EasyPermissions.PermissionCallbacks接口,直接处理权限是否成功申请
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
            // Forward results to EasyPermissions
            EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
        }
    
        //成功
        @Override
        public void onPermissionsGranted(int requestCode, List<String> list) {
            // Some permissions have been granted
            // ...
        }
    
        //失败
        @Override
        public void onPermissionsDenied(int requestCode, List<String> list) {
            // Some permissions have been denied
            // ...
        }
    

    Dailog说明

    1. RationaleDialog:申请权限的说明。

    [图片上传失败...(image-7e5dd6-1527317700795)]

    EasyPermissions.requestPermissions(context, PERMISSION_STORAGE_MSG, PERMISSION_STORAGE_CODE, PERMISSION_STORAGE);
    

    或者

    EasyPermissions.requestPermissions(
            new PermissionRequest.Builder(this, RC_CAMERA_AND_LOCATION, perms)
                    .setRationale(R.string.camera_and_location_rationale)
                    .setPositiveButtonText(R.string.rationale_ask_ok)
                    .setNegativeButtonText(R.string.rationale_ask_cancel)
                    .setTheme(R.style.my_fancy_style)
                    .build());
    

    方法回调实现EasyPermissions.RationaleCallbacks接口:

       /**
         * dialog提醒点击“确定”
         *
         * @param requestCode
         */
        @Override
        public void onRationaleAccepted(int requestCode) {
        }
    
        /**
         * dialog提醒点击“取消”
         *
         * @param requestCode
         */
        @Override
        public void onRationaleDenied(int requestCode) {
        }
    

    详细使用参考:easypermissions

    1. AppSettingsDialog:跳转setting页,申请被拒绝时使用。
    AppSettingsDialog
     /**
         * 拒绝权限
         *
         * @param requestCode
         * @param perms
         */
        @Override
        public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
            if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
                new AppSettingsDialog.Builder(this)
                        .setTitle("提醒")
                        .setRationale("此app需要这些权限才能正常使用")
                        .build()
                        .show();
            }
        }
    

    方法回调

    /**
           /**
             * 设置页面回调
             *
             * @param requestCode
             * @param resultCode
             * @param data
             */
            @Override
            public void onActivityResult(int requestCode, int resultCode, Intent data) {
                super.onActivityResult(requestCode, resultCode, data);
                if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
                    if (PermissionUtils.hasStoragePermission(context)){
                        //有权限
                    }else{
                        //没有权限
                    }
                }
            }
    

    国产ROM适配

    国产ROM问题一直是最多的,申请权限的弹窗不按Android原生来,有时候允许权限了,回调却是走失败。
    如果想适配国产ROM,我推荐 AndPermission

    AndPermission概述

    AndPermission可以简化在Android上请求权限的流程。

    • 在Android6.0或者更高版本的系统中请求运行时权限。
    • 在Android7.0或者更高版本的系统中分享私有文件。
    • 在Android8.0或者更高版本的系统中安装Apk文件。

    请求流程

    为了兼容一些特殊中国产手机,AndPermission请求权限的流程是这样的:

                          发起请求
                             │
                  调用SDK Api判断是否有权限
                             │
               ┌─────────────┴─────────────┐
             有权限                      没权限
               │                           │
               │                  使用SDK Api请求权限
               │                           │
               │                    用户授权或者拒绝
               └─────────────┬─────────────┘
                      执行权限相关代码
                     ┌───────┴───────┐
                    正常            异常
                     │               │
                 onGranted()      onDenied()
              ┌──────┴──────┐        │
             正常          异常───────┘
    

    申请流程的释义

    可以看出AndPermission的申请流程和标准的申请流程大相径庭,这样做主要是因为以下几点原因。

    • 兼容Android5.0的系统判断是否有权限。
    • 部分设备上使用SDK的Api判断是否有权限时,无论是否有权限都返回true。
    • 部分设备上无论用户点击同意还是拒绝都返回true。
    • 部分设备在申请权限时并不会弹出授权Dialog,而是在执行权限相关代码时才会弹出授权Dialog。
    特特特别注意:

    因为部分权限(例如发送短信、打电话、接听/挂断电话等),AndPermission不能执行权限相关代码做测试,所以对于这一类权限在执行权限相关代码步骤仅仅使用了AppOpsManager做检测。因为极少部分国产机总是返回true,因此直接回调到onGranted()中让开发者执行相关代码来辅助AndPermission的整个流程,如果onGranted()方法发生异常,那么则认为是没有权限,所以重新回调到onDenied()方法中,如果onGranted()方法正常执行那么则认为有权限。这样一来刚好是一个完整的流程,也可以最大限度的兼容到更多异常的手机。

    回调onGranted()时AndPermission对onGranted()方法做了try catch。这样做可以保证两点,第一点是防止部分手机返回错误状态时回调了onGranted()后的崩溃,第二点是防止部分手机需要真正执行权限相关代码时触发授权Dialog后被用户拒绝后的崩溃。而这两点都是没有权限,因此会重新回调到onDenied()中让开发者处理没权限的情况。

    综上所述,如果onGranted()和onDenied()方法都被调用了,说明开发者的onGranted()方法发生了异常。

    AndPermission详细说明文档

    GitHub

    GitHub

    相关文章

      网友评论

      • 孤尘枫:看了一下,突然觉得为啥国产ROM不按原生来,非得乱改?这么一改就得成千上万的App去适配ROM;厂商如果自觉的把ROM按着标准来不是就达到修改一个(指ROM)适配了成千上万的App?
      • 005c11b46da3:不错 写的很好 来一起喝可乐啊

      本文标题:EasyPermissions Android权限适配(带流程图

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