Android解决EasyPermissions弹窗两次的问题

本文探讨了在Android应用中使用EasyPermissions库时遇到的二次弹窗问题,详细解析了EasyPermissions的权限申请流程,并提出了解决方案:通过手动构建PermissionRequest对象并直接调用directRequestPermissions()方法,跳过不必要的rationale弹窗,直接进入系统权限申请,以简化用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

EasyPermissions是Google为了方便开发者为App申请权限而推出的开源库。帮助开发者极大的精简了权限申请的过程。申请权限的时候也非常简单

/**
* @params host Activity或者Fragment
* @params rationale String字符串,用于描述需要申请权限的说明
* @params requestCode 用于标识权限申请的回调
* @params perms 需要申请的权限组
*/
EasyPermissions.requestPermissions(this, rationale, 0, perms);

然而当真正进行权限申请的时候,却发现多了个弹窗。
在这里插入图片描述
This app may not work correctly without the requested permissions 是rationale为null时展示的文案,不为null展示的是传入的rationale。当用户点击确定之后才是系统的权限申请弹窗。无疑使得权限的申请过程变得复杂了,产品也不会同意这样的申请流程。因此,需要去掉这个弹窗,直接弹出系统的权限申请。追踪其调用过程发现流程如下。

1.开发者调用EasyPermissions.requestPermissions()方法, EasyPermissions.requestPermissions()将传入的参数封装成PermissionRequest。
2.然后调用PermissionRequest.getHelper().requestPermissions()申请权限
3.PermissionHelper.requestPermissions()会通过shouldShowRationale()方法对传入的perms中的权限进行判断。
4.如果有权限要申请,就调用showRequestPermissionRationale()方法,即弹出上边原因说明弹窗,用户点击确定之后再进行权限申请,此时才会弹出真正的权限申请弹窗。
5.如果没有权限需要申请,就调用directRequestPermissions方法进行权限申请。

可能你会觉得奇怪了,第5步是不是有问题呀?权限已经不需要申请了这里为啥还要调用呢?其实EasyPermissions这么做当然不是为了去帮我们申请权限,而是为了能够执行权限申请成功之后的回调。如此保证了带有@AfterPermissionGranted注解的方法能够得到执行。

核心代码:第3步中的判断过程

    public void requestPermissions(@NonNull String rationale, @NonNull String positiveButton,
                                   @NonNull String negativeButton, @StyleRes int theme,
                                   int requestCode, @NonNull String... perms) {
        if (shouldShowRationale(perms)) {
            showRequestPermissionRationale(rationale, positiveButton, negativeButton, theme, requestCode, perms);
        } else {
            directRequestPermissions(requestCode, perms);
        }
    }

步骤清晰了,解决的思路也就有了:
在第1步中手动构建一个PermissionRequest对象,构建的过程可以参考EasyPermissions中对参数的处理
在第2步中直接调用PermissionRequest.getHelper().directRequestPermissions()进行权限申请

这是封装之后的调用方法,可以直接复制使用

    public static void requestPermissions(@NonNull Activity host, String rationale,
                                          int requestCode, @Size(min = 1) @NonNull String... perms) {
        // 需要原因说明弹窗的依然交给EasyPermission处理
        if (!TextUtils.isEmpty(rationale)) {
            EasyPermissions.requestPermissions(host, rationale, requestCode, perms);
        } else {
            // rational的值为空时,直接调用权限申请,绕过EasyPermission的判断
            PermissionRequest request = new PermissionRequest.Builder(host, requestCode, perms).build();
            request.getHelper().directRequestPermissions(requestCode, perms);
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值