archive log list权限不足_开源项目:使用 Activity Result API + Kotlin 扩展函数 封装权限请求库...

前言

市面上权限请求的库很多,而前段时间官方刚刚将 requestPermissions() + onRequestPermissionsResult() API 弃用,那么官方的替代方案是什么呢?本文将介绍 Activity Result API 进行权限请求的使用以及如何借助 Kotlin 扩展函数自己封装一个权限请求库

Activity Result API

在 Android Jetpack Activity 1.2.0-alpha02Fragment 1.3.0-alpha02 中,Google 提供了全新的 Activity Result API 来替换 startActivityForResult() + onActivityResult()requestPermissions() + onRequestPermissionsResult()。详情可移步 官方文档[1],中文可以参考 秉心说[2] 的 是时候丢掉 onActivityResult 了 ![3],有些 API 的名字发生了变化,请留意

requestPermissions() / onRequestPermissionsResult() 被弃用

紧接着在 Activity 1.2.0-alpha04Fragment 1.3.0-alpha04 版本中,

startActivityForResult()+onActivityResult()requestPermissions()+onRequestPermissionsResult()被标记为弃用,而在Fragment 1.3.0-alpha05 这些标记弃用的方法内部已改为使用 ActivityResultRegistry 实现

23a3545e09df025017ee26b7ad21bc1f.png
f4c7f6e25ce483f586881dba8e5ad62c.png

新 API 的使用

新的 API 使用非常简单,分为单一权限请求,和多权限请求,Activity 和 Fragment 使用方法相同

单一权限请求

val permission = Manifest.permission.WRITE_EXTERNAL_STORAGE
registerForActivityResult(ActivityResultContracts.RequestPermission()) { result ->
// 请求结果,result 为 boolean true 代表已授权,false 代表未授权
}.launch(permission)

多权限请求

val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)

registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result: MutableMapBoolean> ->// 请求结果,返回一个map ,其中 key 为权限名称,value 为是否权限是否赋予
}.launch(permissions)

配合 Kotlin 扩展函数进行封装

配合 Kotlin 的扩展函数,我们可以将权限请求的逻辑进行封装。

开发过程中,我们申请权限时关注的就是权限是否申请成功,如果未申请成功是否勾选了不再询问

因此我们可以加入「权限申请成功」,「权限申请失败且未勾选不再询问」,「权限申请失败且已勾选不再询问」三种状态的回调

/**
 * [permission] 权限名称
 * [granted] 申请成功
 * [denied] 被拒绝且未勾选不再询问
 * [explained] 被拒绝且勾选不再询问
 */
inline fun Fragment.requestPermission(
    permission: String,crossinline granted: (permission: String) -> Unit = {},crossinline denied: (permission: String) -> Unit = {},crossinline explained: (permission: String) -> Unit = {}
) {
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { result ->
        when {
            result -> granted.invoke(permission)
            shouldShowRequestPermissionRationale(permission) -> denied.invoke(permission)
            else -> explained.invoke(permission)
        }
    }.launch(permission)
}

/**
 * [permissions] 权限数组
 * [allGranted] 所有权限均申请成功
 * [denied] 被拒绝且未勾选不再询问,同时被拒绝且未勾选不再询问的权限列表
 * [explained] 被拒绝且勾选不再询问,同时被拒绝且勾选不再询问的权限列表
 */
inline fun Fragment.requestMultiplePermissions(vararg permissions: String,crossinline allGranted: () -> Unit = {},crossinline denied: (List<String>) -> Unit = {},crossinline explained: (List<String>) -> Unit = {}
) {
    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result: MutableMapBoolean> ->//过滤 value 为 false 的元素并转换为 listval deniedList = result.filter { !it.value }.map { it.key }when {
            deniedList.isNotEmpty() -> {//对被拒绝全选列表进行分组,分组条件为是否勾选不再询问val map = deniedList.groupBy { permission ->if (shouldShowRequestPermissionRationale(permission)) DENIED else EXPLAINED
                }//被拒接且没勾选不再询问
                map[DENIED]?.let { denied.invoke(it) }//被拒接且勾选不再询问
                map[EXPLAINED]?.let { explained.invoke(it) }
            }else -> allGranted.invoke()
        }
    }.launch(permissions)
}

使用起来是这样的

单一权限申请

requestPermission(Manifest.permission.RECORD_AUDIO,
    granted = { permission ->
        //权限申请成功
        },
    denied = { permission ->
       //权限申请失败且未勾选不再询问,下次可继续申请
    },
    explained = { permission ->
        //权限申请失败且已勾选不再询问,需要向用户解释原因并引导用户开启权限
    })

多权限申请

requestMultiplePermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA,
    allGranted = {
        //全部权限均已申请成功
    },
    denied = {list->
        //权限申请失败且未勾选不再询问,下次可继续申请
    },
    explained = {list->
        //权限申请失败且已勾选不再询问,需要向用户解释原因并引导用户开启权限
    })

Java 版本

Java 是可以调用 Kotlin 的扩展函数的,为了更方便地调用,可以在此基础上再封装一层

单一权限请求

PermissionUtils.requestPermission(this, permission, new PermissionResultListener() {
    @Override
    public void granted(String permission) {
        Log.i(TAG, "granted: ");
    }
    @Override
    public void denied(String permission) {
        Log.i(TAG, "denied: ");
    }
    @Override
    public void explained(String permission) {
        Log.i(TAG, "explained: ");
    }
});

多权限请求

PermissionUtils.requestMultiplePermissions(this, new MultiPermissionResultListener() {
    @Override
    public void allGranted() {
        Log.i(TAG, "allGranted: ");
    }
    @Override
    public void denied(List list) {
        Log.i(TAG, "denied: " + list.toString());
    }
    @Override
    public void explained(List list) {
        Log.i(TAG, "explained: " + list.toString());
    }
}, permissions);

项目地址

demo 在这里[4],如果感觉这个思路对你有帮助的话,点一颗小星星吧~ ?

另外我还将它传到了 JitPack 上,现已支持 Kotlin DSL 写法,引入姿势如下:

  1. 在项目根目录的 build.gradle 加入

    allprojects {
      repositories {
        //...
        maven { url 'https://jitpack.io' }
      }
    }
  1. 添加依赖

    dependencies {
      implementation 'com.github.Flywith24:Flywith24-Permission:$version'
    }

关于我

我是 Flywith24[5],我的博客内容已经分类整理 在这里[6],点击右上角的 Watch 可以及时获取我的文章更新哦 ?

  • 掘金[7]

  • 简书[8]

  • Github[9]

a3993c5e73e6d03589a6c23acbb6b9da.png

参考资料

[1]

官方文档: https://developer.android.com/training/basics/intents/result

[2]

秉心说: https://juejin.im/user/586eff908d6d81005879507d

[3]

是时候丢掉 onActivityResult 了 !: https://juejin.im/post/5e80cb1ee51d45471654fae7

[4]

demo 在这里: https://github.com/Flywith24/Flywith24-Permission

[5]

Flywith24: https://flywith24.gitee.io/

[6]

在这里: https://github.com/Flywith24/BlogList

[7]

掘金: https://juejin.im/user/57c7f6870a2b58006b1cfd6c

[8]

简书: https://www.jianshu.com/u/3d5ad6043d66

[9]

Github: https://github.com/Flywith24

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值