Discuz! BBS

 找回密码
 新用户注册
搜索
热搜: 活动 交友 discuz
查看: 148|回复: 1

找到 super.onRequestPermissionsResult方法 的替代方法,避免弃用

[复制链接]

519

主题

723

帖子

4266

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4266
发表于 2026-7-29 06:36:37 | 显示全部楼层 |阅读模式
我想找到 super.onRequestPermissionsResult(requestCode, permissions, grantResults)  这个方法 的替代方法,可以避免使用已经废弃的该方法,也就避免了@Deprecated("Deprecated in Java")  这个声明,请详解
已完成分析,参考了10篇资料
替代 onRequestPermissionsResult 的现代方案:Activity Result API
从 AndroidX Activity 1.2.0 和 Fragment 1.3.0 开始,Google 官方推荐使用 Activity Result API 来替代已废弃的 onRequestPermissionsResult 回调方式。下面详细讲解替代方案。
为什么被废弃
传统的 onRequestPermissionsResult 存在以下问题:
需要手动管理 requestCode,容易出错
回调分散,代码可读性差
与 Activity/Fragment 的生命周期耦合紧密
多个权限请求时代码臃肿
新的 Activity Result API 提供了类型安全、生命周期感知、模块化的解决方案。
核心替代方案:registerForActivityResult()
添加依赖
gradle

编辑



implementation "androidx.activity:activity-ktx:1.8.0"
implementation "androidx.fragment:fragment-ktx:1.6.0"
单个权限请求
kotlin

编辑



class MainActivity : AppCompatActivity() {
   
    // 在类成员位置注册(必须在 onCreate 之前执行)
    private val cameraPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted: Boolean ->
        // 这里是回调,直接拿到结果
        if (isGranted) {
            // 权限已授予
            openCamera()
        } else {
            // 权限被拒绝
            showPermissionDeniedDialog()
        }
    }
   
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
   
    private fun checkCameraPermission() {
        when {
            // 已拥有权限
            ContextCompat.checkSelfPermission(
                this, Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED -> {
                openCamera()
            }
            // 需要显示解释说明(用户之前拒绝过但未勾选"不再询问")
            shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> {
                showRationaleDialog {
                    cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
                }
            }
            // 直接请求权限
            else -> {
                cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
            }
        }
    }
}
多个权限批量请求
kotlin

编辑



private val multiPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestMultiplePermissions()
) { permissions: Map<String, Boolean> ->
    // permissions 是一个 Map,key 是权限名,value 是是否授予
    val allGranted = permissions.values.all { it }
    if (allGranted) {
        startFeature()
    } else {
        val denied = permissions.filter { !it.value }.keys
        Snackbar.make(binding.root, "被拒绝: $denied", Snackbar.LENGTH_LONG)
            .setAction("去设置") { openAppSettings() }
            .show()
    }
}

private fun requestPermissions() {
    multiPermissionLauncher.launch(
        arrayOf(
            Manifest.permission.CAMERA,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
    )
}
新旧方式对比
表格
对比项        旧方式onRequestPermissionsResult        新方式registerForActivityResult
请求码管理        手动定义 requestCode 常量        无需管理,系统自动处理
结果处理        在统一回调中通过 switch/case 分发        每个 launcher 有独立回调
类型安全        String[] 和 int[],易出错        Boolean 或 Map<String, Boolean>
生命周期        容易在配置变更后丢失状态        生命周期感知,自动处理
代码位置        分散在回调中        与请求逻辑紧密相邻
处理"不再询问"场景
当用户勾选"不再询问"并拒绝后,shouldShowRequestPermissionRationale() 返回 false,此时需要引导用户手动前往设置页:
kotlin

编辑



private fun openAppSettings() {
    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
        data = Uri.parse("packagepackageName")
    }
    startActivity(intent)
}
封装为可复用的工具类
如果多个页面都需要权限请求,可以封装一个工具类:
kotlin

编辑



class PermissionHelper(private val activity: FragmentActivity) {
   
    private val launcher = activity.registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { grantResults ->
        handleResult(grantResults)
    }
   
    private var onAllGranted: (() -> Unit)? = null
   
    private val permissionsMap = mapOf(
        Manifest.permission.CAMERA to "摄像头",
        Manifest.permission.READ_EXTERNAL_STORAGE to "存储",
    )
   
    fun requestPermissions(onAllGranted: () -> Unit) {
        this.onAllGranted = onAllGranted
        val permissions = permissionsMap.keys.toTypedArray()
        launcher.launch(permissions)
    }
   
    private fun handleResult(results: Map<String, Boolean>) {
        val denied = results.filter { !it.value }.keys
        if (denied.isEmpty()) {
            onAllGranted?.invoke()
        } else {
            // 处理被拒绝的权限
            showPermissionDeniedDialog(denied)
        }
    }
}
关键注意事项
注册时机:registerForActivityResult() 必须在 onCreate() 中或之前调用,不能在按钮点击等懒加载场景中创建,否则会抛出 IllegalStateException
生命周期安全:launcher 会自动感知生命周期,在 Activity/Fragment 销毁时自动清理
配置变更:屏幕旋转等配置变更后,回调仍然能正确触发
Fragment 中同样适用:在 Fragment 中使用方式完全一致
总结
用 registerForActivityResult(ActivityResultContracts.RequestPermission()) 或 RequestMultiplePermissions() 替代旧的 requestPermissions() + onRequestPermissionsResult() 组合,可以获得更简洁、类型安全、生命周期感知的权限请求体验。不再需要 super.onRequestPermissionsResult(),也彻底告别了 @Deprecated 警告。
回复

使用道具 举报

519

主题

723

帖子

4266

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4266
 楼主| 发表于 2026-7-29 06:37:36 | 显示全部楼层
  :$
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 新用户注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2026-8-15 17:37 , Processed in 0.009574 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表