[安卓开发基础] 权限的开源库 PermissionsDispatcher使用

2018年01月11日 15:33:35 Android小码农 阅读数:4452

https://blog.csdn.net/s13383754499/article/details/79034758

PermissionsDispatcher是一个基于注解、帮助开发者简单处理Android 6.0系统中的运行时权限的开源库。避免了开发者编写大量繁琐的样板代码。

开源地址:https://github.com/hotchemi/PermissionsDispatcher

文档介绍:http://hotchemi.github.io/PermissionsDispatcher/

下面详细介绍一下如何在Android Studio上使用该开源库。

1、添加依赖

首先在项目工程下的build.gradle文件中加入对maven仓库依赖引入的支持。

allprojects {
    repositories {
        jcenter()
        mavenCentral()
    }
}

之后在module下的build.gradle文件中添加两项依赖:

compile 'com.github.hotchemi:permissionsdispatcher:2.3.1'
annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.1'

并将targetSdkVersion设为23,即:targetSdkVersion 23

2、在Activity或Fragment中使用

注解列表:

Annotation Required Description
@RuntimePermissions 注解在其内部需要使用运行时权限的Activity或Fragment上
@NeedsPermission 注解在需要调用运行时权限的方法上,当用户给予权限时会执行该方法
@OnShowRationale   注解在用于向用户解释为什么需要调用该权限的方法上,只有当第一次请求权限被用户拒绝,下次请求权限之前会调用
@OnPermissionDenied   注解在当用户拒绝了权限请求时需要调用的方法上
@OnNeverAskAgain   注解在当用户选中了授权窗口中的不再询问复选框后并拒绝了权限请求时需要调用的方法,一般可以向用户解释为何申请此权限,并根据实际需求决定是否再次弹出权限请求对话框

注意:被注解的方法不能是私有方法。

  • @RuntimePermissions注解:这是必须使用的注解,用于标注在你想要申请权限的Activity或者Fragment上,如demo里面的PermissionsDispatcherActivity:
@RuntimePermissions
public class PermissionsDispatcherActivity extends AppCompatActivity implements View.OnClickListener {
}
  • @NeedsPermission注解:这也是必须使用的注解,用于标注在你要获取权限的方法,注解括号里面有参数,传入想要申请的权限。也就是说你获取了相应的权限之后就会执行这个方法
    //获取单个权限
    @NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    public void getSingle() {
        Toast.makeText(this, "getSingle", Toast.LENGTH_SHORT).show();
    }

    //获取多个权限
    @NeedsPermission({Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO})
    public void getMulti() {
        Toast.makeText(this, "getMulti", Toast.LENGTH_SHORT).show();
    }
  • @OnShowRationale注解:这个不是必须的注解,用于标注申请权限前需要执行的方法,注解
    括号里面有参数,传入想要申请的权限,而且这个方法还要传入一个PermissionRequest对象,这个对象有两种方法:proceed()让权限请求继续,cancel()让请求中断。也就是说,这个方法会拦截你发出的请求,这个方法用于告诉用户你接下来申请的权限是干嘛的,说服用户给你权限。
 @OnShowRationale({Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO})
    //给用户解释要请求什么权限,为什么需要此权限
    void showRationale(final PermissionRequest request) {
        new AlertDialog.Builder(this)
                .setMessage("使用此功能需要WRITE_EXTERNAL_STORAGE和RECORD_AUDIO权限,下一步将继续请求权限")
                .setPositiveButton("下一步", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.proceed();//继续执行请求
                    }
                }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.cancel();//取消执行请求
                    }
                })
                .show();
    }

    @OnShowRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        //给用户解释要请求什么权限,为什么需要此权限
    void showSingleRationale(final PermissionRequest request) {
        new AlertDialog.Builder(this)
                .setMessage("使用此功能需要WRITE_EXTERNAL_STORAGE,下一步将继续请求权限")
                .setPositiveButton("下一步", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.proceed();//继续执行请求
                    }
                }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                request.cancel();//取消执行请求
            }
        })
                .show();
    }
  • @OnPermissionDenied注解:这个也不是必须的注解,用于标注如果权限请求失败,但是用户没有勾选不再询问的时候执行的方法,注解括号里面有参数,传入想要申请的权限。也就是说,我们可以在这个方法做申请权限失败之后的处理,如像用户解释为什么要申请,或者重新申请操作等。
    @OnPermissionDenied({Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO})//一旦用户拒绝了
    public void multiDenied() {
        Toast.makeText(this, "已拒绝一个或以上权限", Toast.LENGTH_SHORT).show();
    }


    @OnPermissionDenied(Manifest.permission.WRITE_EXTERNAL_STORAGE)//一旦用户拒绝了
    public void StorageDenied() {
        Toast.makeText(this, "已拒绝WRITE_EXTERNAL_STORAGE权限", Toast.LENGTH_SHORT).show();
    }
  • @OnNeverAskAgain注解:这个也不是必须的注解,用于标注如果权限请求失败,而且用户勾选不再询问的时候执行的方法,注解括号里面有参数,传入想要申请的权限。也就是说,我们可以在这个方法做申请权限失败并选择不再询问之后的处理。例如,可以告诉作者想开启权限的就从手机设置里面开启。

    注意,有些系统的不再询问勾选项是要用户拒绝授权一次才显示出来的。


    @OnNeverAskAgain({Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO})//用户选择的不再询问
    public void multiNeverAsk() {
        Toast.makeText(this, "已拒绝一个或以上权限,并不再询问", Toast.LENGTH_SHORT).show();
    }
    @OnNeverAskAgain(Manifest.permission.WRITE_EXTERNAL_STORAGE)//用户选择的不再询问
    public void StorageNeverAsk() {
        Toast.makeText(this, "已拒绝WRITE_EXTERNAL_STORAGE权限,并不再询问", Toast.LENGTH_SHORT).show();
    }

注意,这些注解的方法都不能是private,原因看下面。

  使用PermissionsDispatcher除了要实现注解之外,还要重写Activity的onRequestPermissionsResult()方法,在里面让一个PermissionsDispatcher执行回调。这个PermissionsDispatcher是什么来的呢?
  原来只要我们实现了@RuntimePermissions@NeedsPermission这两个必须的注解之后,再build一次project之后,编译器就会在在app\build\intermediates\classes\debug目录下与被注解的Activity同一个包下生成一个辅助类,名称为 “被注解的Activity的名称+PermissionsDispatcher” 的辅助类,用来调用被注解的Activity的方法(就是因为这个所以被注解的方法不能private,private方法的作用域不在其他的类)。所以,第一次用的话,要注解好之后,build一次,下面的方法里面的PermissionsDispatcherActivityPermissionsDispatcher才不会令AS报红。

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionsDispatcherActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }

  最后,申请权限的时候,调用辅助类的方法(名字从下面可以看出是被@OnPermissionDenied注解的方法加上WithCheck,参数是这个Activity或者Fragment)就行了:

    //申请单个权限
    PermissionsDispatcherActivityPermissionsDispatcher.getSingleWithCheck(this);
    //申请多个权限
    PermissionsDispatcherActivityPermissionsDispatcher.getMultiWithCheck(this);

插件

  觉得这么多注解要自己一个一个弄不够方便,PermissionsDispatcher还在AndroidStudio做了插件,只要在setting设置里的plugins界面里搜索PermissionsDispatcher就可以安装了,安装完重启一下就能使用: 
- 在所需的Activity或者Fragment的代码里面右键,选择Generate,然后就可以选择Generate Runtime Permissions…(生成动态权限的生成)或者下面的Add PermissionsDispatcher dependencies(添加PermissionsDispatcher依赖)

  • 点击Generate Runtime Permissions…出现如下界面,输入方法名字就能生成,很简单粗暴:

生成了这个,如果你没onRequestPermissionsResult和@RuntimePermissions的话也会帮你加上:

    @NeedsPermission(Manifest.permission.CALL_PHONE)
    void call() {
    }

    @OnShowRationale(Manifest.permission.CALL_PHONE)
    void callshow(final PermissionRequest request) {
    }

 遇到问题 :

1.Error:Gradle: failed to create directory

解决方法:

Android Studio 3.0预览版本 Error:Gradle: failed to create directory 解决方案

解决方案
1、网上的解决方案不好找,最后在 twitter 上的 android studio 发布的推文中找到了答案 ,意思是说如果在使用预览版碰到问题,还想继续使用,可以在 gradle.properties 文件中禁止 Aapt2

2、只要在项目的 gradle.properties 中添加 android.enableAapt2=false 即可

总结
1、问题的解决方案很简单,在项目的 gradle.properties 中添加 android.enableAapt2=false 即可


--------------------- 
作者:shenshizhong 
来源:CSDN 
原文:https://blog.csdn.net/shenshizhong/article/details/77540459 
版权声明:本文为博主原创文章,转载请附上博文链接!

----------------------------------------------------------------------------------------------------------------------------------

2. onRequestPermissionsResult     显示波浪线:

解决方法:点击  方法 开头 灯泡   添加  suppotlint:重新build.

@SuppressLint("NeedOnRequestPermissionsResult")
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    CActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}

 遇到错误:  mavenCentral()  放在 buildscript  导致 编译报错Error:Execution failed for task ':app:compileDebugJavaWithJavac'. > permissions.dispatcher.processor

 2.

PermissionRequest;报错

导入错误包

import permissions.dispatcher.PermissionRequest;

重新   rebuild

猜你喜欢

转载自blog.csdn.net/oDianZi1234567/article/details/86250298