You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Jetpack Compose中PermissionHandler的onRequestPermissionsResult不触发

问题根源分析

你的代码中PermissionHandler继承AppCompatActivity但未被系统作为Activity实例管理,且权限请求使用的是宿主Activity的context,导致权限回调只会发送给宿主Activity,而不是PermissionHandler中的onRequestPermissionsResult方法。此外,旧的onRequestPermissionsResult机制已被Jetpack官方弃用,Compose环境下更推荐使用Activity Result API处理权限请求,它能自动适配Composable生命周期,无需手动处理回调转发。

解决方案:改用Activity Result API重构权限逻辑

方案1:直接在Composable中实现权限处理

@Composable
fun CheckBluetoothPermission(context: Activity) {
    val permissionValue = remember { mutableStateOf(false) }
    val permission = AppPermission.ACCESS_FINE_LOCATION.permission
    val permissionLabel = permission.split('.')[2]

    // 创建权限请求Launcher,自动处理回调
    val permissionLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.RequestPermission(),
        onResult = { isGranted ->
            permissionValue.value = isGranted
            Log.d("permission result", "权限是否授予:$isGranted")
            // 这里添加权限结果的后续处理逻辑
        }
    )

    // 权限检查流程,绑定Composable生命周期
    LaunchedEffect(Unit) {
        when {
            // 权限已授予
            ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED -> {
                permissionValue.value = true
            }
            // 需要显示权限说明弹窗
            ActivityCompat.shouldShowRequestPermissionRationale(context, permission) -> {
                val showDialog = remember { mutableStateOf(true) }
                if (showDialog.value) {
                    AlertDialog(
                        onDismissRequest = { showDialog.value = false },
                        title = { Text("Permission Needed") },
                        text = { Text("应用需要$permissionLabel权限才能正常使用对应功能") },
                        confirmButton = {
                            Button(onClick = {
                                showDialog.value = false
                                permissionLauncher.launch(permission)
                            }) {
                                Text("确定")
                            }
                        }
                    )
                }
            }
            // 直接发起权限请求
            else -> {
                permissionLauncher.launch(permission)
                Toast.makeText(context, "请允许应用获取$permissionLabel权限", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

方案2:封装成独立工具类(保留类似原PermissionHandler的结构)

class PermissionHandler(private val context: Activity) {
    // 检查权限状态
    fun checkPermission(permission: String): Boolean {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
    }

    // 判断是否需要显示权限说明
    fun shouldShowRationale(permission: String): Boolean {
        return ActivityCompat.shouldShowRequestPermissionRationale(context, permission)
    }

    @Composable
    fun CheckAndRequestPermission(
        permission: String,
        onPermissionResult: (Boolean) -> Unit
    ) {
        val permissionLabel = permission.split('.')[2]
        // 内部创建权限请求Launcher
        val launcher = rememberLauncherForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted ->
            onPermissionResult(isGranted)
        }

        LaunchedEffect(permission) {
            when {
                checkPermission(permission) -> onPermissionResult(true)
                shouldShowRationale(permission) -> {
                    val showDialog = remember { mutableStateOf(true) }
                    if (showDialog.value) {
                        AlertDialog(
                            onDismissRequest = { showDialog.value = false },
                            title = { Text("Permission Needed") },
                            text = { Text("应用需要$permissionLabel权限才能正常使用对应功能") },
                            confirmButton = {
                                Button(onClick = {
                                    showDialog.value = false
                                    launcher.launch(permission)
                                }) {
                                    Text("确定")
                                }
                            }
                        )
                    }
                }
                else -> {
                    launcher.launch(permission)
                    Toast.makeText(context, "请允许应用获取$permissionLabel权限", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}

调用方式:

@Composable
fun CheckBluetoothPermission(context: Activity) {
    val permissionValue = remember { mutableStateOf(false) }
    val permissionHandler = PermissionHandler(context)
    
    permissionHandler.CheckAndRequestPermission(AppPermission.ACCESS_FINE_LOCATION.permission) { isGranted ->
        permissionValue.value = isGranted
    }
}

内容的提问来源于stack exchange,提问作者Karthik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:35:19