权限申请库:AndPermission(一)

Quibbler 2022-5-27 812

权限申请库:AndPermission(一)


        在Android 6.0(也就是Android M)之前,权限在安装时全部授予,在保护隐私方面起到的作用有限;于是在Android 6.0及之后对权限进行了分类,涉及隐私等重要权限需要在运行时动态申请。另外,随着Android版本的更新迭代,有新的权限加入,也有旧的权限废弃。

        关于权限的申请,之前就了解过一些优秀的库:通过注解申请权限的PermissionsDispatcher、阿里巴巴严振杰所写的AndPermission、以及集大成者RxPermission



1、AndPermission介绍

        本篇之所以选择AndPermission展开,因为看完源码后,发现其中有不少值得学习的地方。

        GitHub:github.com/yanzhenjie/AndPermission

        GitBook:yanzhenjie.com/AndPermission


1.1、简介

        AndPermission是一个非常好用的权限申请开源库,至今一晃竟然有6年了,也算是安卓开源库中的元老,其类似Glide简洁的链式调用极大的简化了权限申请和回调。

        此库已经近三年没有维护更新,issue多的离谱,所以不建议在项目中使用此库。尽管年久失修,但此库中的设计模式、权限管理、版本兼容做的都非常好。值得我们去阅读,学习源码中优秀的设计思路,对Android权限的理解很有帮助。

                

1.2、引入

        使用AndPermission,在build.gradle中加入如下依赖即可:

    dependencies {
        
        implementation 'com.yanzhenjie:permission:2.0.2'
        ...
    }

        


2、AndPermission使用

        通常在Activity中通过requestPermissions()方法申请权限,然后在onRequestPermissionsResult()方法中处理权限申请结果,关于权限申请,另见Android权限检测申请源码流程分析一文。

        有了AndPermission,申请权限操作一气呵成,通过设计良好的链式调用完成。后面详细阅读源码会知道,其实是借助BridgeActivity完成的。


2.1、申请权限

        只需要下面几个简单的链式调用,即可完成权限申请、回调处理。with()方法的设计类似Glide库中的with(),可以在FragmentActivity中调用。

    AndPermission.with(this)
        .runtime()
        .permission(Permission.READ_CONTACTS)
        //权限申请允许,或有权限时的回调
        .onGranted(new Action<List<String>>() {
            @Override
            public void onAction(List<String> data) {
                
            }
        })
        //权限申请被拒绝时
        .onDenied(new Action<List<String>>() {
            @Override
            public void onAction(List<String> data) {
                
            }
        })
        //无权限时,先回调这里。开发者进行下一步处理。
        .rationale(new Rationale<List<String>>() {
            @Override
            public void showRationale(Context context, List<String> data, RequestExecutor executor) {
                //可以调用executor.execute()申请权限,根据权限申请结果回调onDranted()或者onDenied()
                //或者executor.cancel()放弃操作,会直接回调onDenied
            }
        })
        //启动权限申请操作,最终通过BridgeActivity完成操作
        .start();


2.2、权限判断

        通过AndPermissionhasPermissions()方法判断应用有无某个权限:

    /**
     * Judgment already has the target permission.
     *
     * @param activity    {@link Activity}.
     * @param permissions one or more permissions.
     * @return true, other wise is false.
     */
    public static boolean hasPermissions(Activity activity, String... permissions) {
        return PERMISSION_CHECKER.hasPermission(activity, permissions);
    }

        内部则是通过PermissionChecker检查权限, PermissionChecker有三种实现,分别是StandardCheckerStrictChecker以及DoubleChecker

    /**
     * Classic permission checker.
     */
    private static final PermissionChecker PERMISSION_CHECKER = new DoubleChecker();

        而最后一种DoubleChecker则是前面标准权限检查严格权限检查的双重检测:

    public final class DoubleChecker implements PermissionChecker {
    
        private static final PermissionChecker STANDARD_CHECKER = new StandardChecker();
        private static final PermissionChecker STRICT_CHECKER = new StrictChecker();
        
        @Override
        public boolean hasPermission(Context context, String... permissions) {
            return STRICT_CHECKER.hasPermission(context, permissions) &&
                STANDARD_CHECKER.hasPermission(context, permissions);
        }
        
        @Override
        public boolean hasPermission(Context context, List<String> permissions) {
            return STRICT_CHECKER.hasPermission(context, permissions) &&
                STANDARD_CHECKER.hasPermission(context, permissions);
        }
    }



3、其它用法

        除了在权限方面的使用,AndPermission还有其它一些用法:install()overlay()notification()setting()。它们的接口设计大都相似。


3.1、安装Apk

        借助install(),可以执行安装apk文件。

    /**
     * 请求安装Apk文件
     */
    AndPermission.with(this)
            .install()
            .file(apkFile)
            .onDenied(new Action<File>() {
                @Override
                public void onAction(File data) {
                    //
                }
            })
            .onGranted(new Action<File>() {
                @Override
                public void onAction(File data) {
                    //
                }
            })
            .rationale(new Rationale<File>() {
                @Override
                public void showRationale(Context context, File data, RequestExecutor executor) {
                    //
                }
            })
            .start();

        使用该方法,必须要在AndroidManifest.xml中加上REQUEST_INSTALL_PACKAGES权限:

    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

        而且,不是直接安装,需要用户授权后,才能调用PackageInstaller界面安装。

        关于Apk的安装,另见Apk的安装过程探究一文。


3.2、系统设置

        借助setting(),尝试执行写入系统设置的操作。似乎已经无法正常使用了。

    /**
     * 写入系统设置
     */
    AndPermission.with(this)
            .setting()
            .write()
            .onDenied(new Action<Void>() {
                @Override
                public void onAction(Void data) {
                    
                }
            })
            .onGranted(new Action<Void>() {
                @Override
                public void onAction(Void data) {
                    
                }
            })
            .rationale(new Rationale<Void>() {
                @Override
                public void showRationale(Context context, Void data, RequestExecutor executor) {
                    
                }
            })
            .start();

        除了以上提到的三种用法,AndPermission还有其它一些用法, 这里没有一一尝试。


        不推荐在项目上使用这个开源库,issue堆积如山,不少项目已经踩坑。Android原生的标准接口已经足够规范,使用原生方法即可。



不忘初心的阿甘
最新回复 (0)
    • 安卓笔记本
      2
        登录 注册 QQ
返回
仅供学习交流,切勿用于商业用途。如有错误欢迎指出:fluent0418@gmail.com