AOP 动态权限申请

为了保护用户隐私,Google在Android 6.0 添加了危险权限申请,这个对于开发来说是真的烦。

每次申请权限都需要进行大量的重复代码,对于我来说根本没有必要做这些多余的工作,在查阅一些资料后写了这个AOP权限申请框架,AOP是什么请自行百度。

源码地址:https://github.com/Chen-Xi-g/PermissionAOP

一、导入

  1. 首先你需要下载 Permission-lib 导入项目

  2. Settings.gradle 中添加 ':permission-lib'

    include ':app', ':permission-lib'
    
  3. build.gradle 添加 aspectjx

    dependencies {
        ...
        /*
            如果出现这个错误
            Cannot cast object 'com.android.build.gradle.internal.pipeline.TransformTask$2$1@590ffd3a' with class 'com.android.build.gradle.internal.pipeline.TransformTask$2$1' to class 'com.android.build.gradle.internal.pipeline.TransformTask'
            更新aspectjx版本
         */
        classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10'
        ...
      }
    
  4. app-build.gradle 中添加 apply plugin: 'android-aspectjx' 和 implementation project(path: ':permission-lib')

    apply plugin: 'android-aspectjx'
    ...
    dependencies {
      ...
      implementation project(path: ':permission-lib')
      ...
    }
    
  5. Sync Now

二、使用

  1. 初始化权限申请失败的监听

    PermissionUtil.init(new PermissionUtil.PermissionGlobalConfigCallback() {
    
          //直接申请权限
          @Override public void shouldShowRational(String permission, int ration) {
            ...
          }
    
          //跳转到设置申请权限
          @Override public void onPermissionReject(String permission, int reject) {
            ...
          }
        });
    
  2. 定义全局Dialog提示权限申请失败信息。

    showRationaleDialog()是没有勾选不再提示被拒绝的Dialog。
    showRejectDialog()是被勾选不再提示的Dialog,需要手动跳转到设置页开启权限。

    //直接申请权限的Dialog
      private void showRationaleDialog(int ration) {
        new AlertDialog.Builder(this).setTitle("权限申请").setMessage(getString(ration)).setNegativeButton("取消", null).show();
      }
    
      //需要跳转到设置的Dialog
      private void showRejectDialog(int reject) {
        new AlertDialog.Builder(this).setTitle("权限申请")
            .setMessage(getString(reject))
            .setPositiveButton("跳转到设置页", new DialogInterface.OnClickListener() {
              @Override public void onClick(DialogInterface dialog, int which) {
                //手动跳转到设置同意权限
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.setData(Uri.fromParts("package", BuildConfig.APPLICATION_ID, null));
                startActivity(intent);
                dialog.dismiss();
              }
            })
            .setNegativeButton("取消", null)
            .show();
      }
    
  3. 在PermissionUtil中定义申请权限的失败时提示的常量值

      public static final int READ_EXTERNAL_STORAGE_RATIONALE = 100;//允许应用程序从外部存储读取被拒绝
      public static final int READ_EXTERNAL_STORAGE_REJECT = 1000;//允许应用程序从外部存储读取勾选不再提示被拒绝提
    
      public static final int WRITE_EXTERNAL_STORAGE_RATIONALE = 101;//允许应用程序写入外部存储被拒绝
      public static final int WRITE_EXTERNAL_STORAGE_REJECT = 1010;//允许应用程序写入外部存储勾选不再提示被拒绝提
    
  1. 在需要申请权限的方法上添加注解@Permission,这个方法只有所有权限同意后才会执行。

    @Permission(
        permissions = { Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE },
        rationales = { PermissionUtil.READ_EXTERNAL_STORAGE_RATIONALE,PermissionUtil.WRITE_EXTERNAL_STORAGE_RATIONALE },
        rejects = {PermissionUtil.READ_EXTERNAL_STORAGE_REJECT, PermissionUtil.WRITE_EXTERNAL_STORAGE_REJECT })
    private void getStorage(){
      //只有获取全部权限才会执行
      Toast.makeText(this,"获取存储权限成功",Toast.LENGTH_LONG).show();
    }
    
  1. 在PermissionUtil.init(PermissionGlobalConfigCallback)重写的两个方法会在权限被拒绝后返回@Permission中rationales和rejects传入的常量值,获取到常量值后可以通过常量值进行匹配提示权限申请失败的信息。

    private void permissionInit() {
        //初始化权限申请监听
        PermissionUtil.init(new PermissionUtil.PermissionGlobalConfigCallback() {
    
          //直接申请权限被拒绝
          @Override public void shouldShowRational(String permission, int ration) {
             //通过@Permission传入的ration判断要提示的信息,如果没有匹配到ration就使用默认的提示信息。
            switch (ration) {
              //获取写入权限失败      
              case PermissionUtil.WRITE_EXTERNAL_STORAGE_RATIONALE:
                //显示Dialog提示权限被拒绝  图2    
                showRationaleDialog(R.string.write_external_storage_permission_rationale);
                break;
              case PermissionUtil.READ_EXTERNAL_STORAGE_RATIONALE:
                showRationaleDialog(R.string.read_external_storage_permission_rationale);
                break;
              case PermissionUtil.CAMERA_RATIONALE:
                showRationaleDialog(R.string.camera_permission_rationale);
                break;
              case PermissionUtil.READ_PHONE_STATE_RATIONALE:
                showRationaleDialog(R.string.read_phone_state_permission_rationale);
                break;
              case PermissionUtil.CALL_PHONE_RATIONALE:
                showRationaleDialog(R.string.call_phone_permission_rationale);
                break;
              default://如果没有设置RATIONALE就使用默认提示
                showRationaleDialog(R.string.permission_rationale);
                break;
            }
          }
    
          //跳转到设置申请权限
          @Override public void onPermissionReject(String permission, int reject) {
            //通过@Permission传入的ration判断要提示的信息,如果没有匹配到reject就使用默认的提示信息。
            switch (reject) {
              //获取写入权限失败      
              case PermissionUtil.WRITE_EXTERNAL_STORAGE_REJECT:
                //显示Dialog提示权限被拒绝  图3
                showRejectDialog(R.string.write_external_storage_permission_reject);
                break;
              case PermissionUtil.READ_EXTERNAL_STORAGE_REJECT:
                showRejectDialog(R.string.read_external_storage_permission_reject);
                break;
              case PermissionUtil.CAMERA_REJECT:
                showRejectDialog(R.string.camera_permission_reject);
                break;
              case PermissionUtil.READ_PHONE_STATE_REJECT:
                showRejectDialog(R.string.read_phone_state_permission_reject);
                break;
              case PermissionUtil.CALL_PHONE_REJECT:
                showRejectDialog(R.string.call_phone_permission_reject);
                break;
              default://如果没有设置REJECT就使用默认提示
                showRejectDialog(R.string.permission_reject);
                break;
            }
          }
        });
      }
    
图1
图2
图3

如何联系我(How to contact me)

QQ: 1217056667

WeChat:Alvin-_-G

邮箱(Email): a912816369@gmail.com

GitHub:https://github.com/Chen-Xi-g

小站: www.minlukj.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容