Jetpack Compose中蓝牙运行时权限仅弹出单个请求的问题求助
问题描述
我需要请求蓝牙相关运行时权限,但调用权限请求后仅弹出单个权限弹窗。当前使用Jetpack Compose 1.1.1版本,搭配accompanist-permissions 0.23.1版本,已按官方文档在Manifest.xml中声明相关蓝牙权限,代码实现如下:
Manifest.xml
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> <!-- Request legacy Bluetooth permissions on older devices. --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" tools:targetApi="s" /> <!-- Needed only if your app makes the device discoverable to Bluetooth devices. --> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <!-- Needed only if your app communicates with already-paired Bluetooth devices. --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
相关Compose代码
BluetoothRequestActivity.kt
class BluetoothRequestActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Theme { val multiplePermissionsState = rememberMultiplePermissionsState( listOf( Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_ADVERTISE, Manifest.permission.BLUETOOTH_ADMIN ) ) AppBarScaffold(abc = true) { BluetoothRequest(multiplePermissionsState, onCancelClick = { finish() }) } } } } }
BluetoothRequest.kt
@Composable fun BluetoothRequest( multiplePermissionsState: MultiplePermissionsState, onCancelClick: () -> Unit ) { Column { BluetoothRequestItem() BluetoothRequestContinue(multiplePermissionsState) BluetoothRequestCancel(onCancelClick) } }
BluetoothRequestContinue.kt
@Composable fun BluetoothRequestContinue(multiplePermissionsState: MultiplePermissionsState) { MaterialButton( text = stringResource(R.string.continue_text), spacerHeight = dimensionResource(10.dp) ) { multiplePermissionsState.launchMultiplePermissionRequest() } }
弹出的权限弹窗截图:
希望有人指导解决这个问题。
解决方案
出现单个弹窗是系统的正常行为,原因和优化方式如下:
蓝牙权限组合并请求
Android 12(API 31)及以上版本中,BLUETOOTH_SCAN、BLUETOOTH_CONNECT、BLUETOOTH_ADVERTISE属于同一权限组,系统会自动将同组权限合并为一次弹窗请求,用户同意后该组内所有权限都会被授予,因此只会看到一个弹窗。旧版本权限无需运行时请求
你声明的BLUETOOTH和BLUETOOTH_ADMIN权限设置了android:maxSdkVersion="30",仅在Android 11及以下版本生效。而在这些版本中,蓝牙权限属于正常权限,系统会自动授予,不需要运行时弹窗请求,因此不会触发额外弹窗。优化权限请求列表
可以精简权限请求列表,只保留需要运行时请求的权限,减少无用处理:val multiplePermissionsState = rememberMultiplePermissionsState( listOf( Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_ADVERTISE ) )验证权限授予状态
调用权限请求后,可以通过multiplePermissionsState.permissions逐个检查权限状态,确保所需权限全部授予:// 示例:检查BLUETOOTH_CONNECT权限是否授予 val connectGranted = multiplePermissionsState.permissions.any { it.permission == Manifest.permission.BLUETOOTH_CONNECT && it.status.isGranted }
内容的提问来源于stack exchange,提问作者Compose Learner
相关产品推荐
相关产品推荐

