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
相关产品推荐
相关产品推荐

