运行时权限 (Permissions)
在 Compose 中处理运行时权限比传统 View 系统简单得多,我们主要使用 rememberLauncherForActivityResult API。
虽然 Accompanist 提供了非常好用的 Permissions 库,但随着 Compose 的发展,使用原生的 ActivityResultContracts 也是完全可行的。不过,为了开发体验,目前最推荐的方案仍然是使用 Accompanist Permissions 库(Google 官方实验室项目)。
1. 依赖配置
kotlin
implementation("com.google.accompanist:accompanist-permissions:0.34.0")2. 单个权限申请
kotlin
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun CameraPermissionSample() {
// 1. 获取权限状态
val cameraPermissionState = rememberPermissionState(
android.Manifest.permission.CAMERA
)
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
if (cameraPermissionState.status.isGranted) {
Text("相机权限已授予!可以拍照了。")
} else {
Column {
val textToShow = if (cameraPermissionState.status.shouldShowRationale) {
// 如果用户之前拒绝过,说明需要解释为什么需要这个权限
"相机权限对于此应用至关重要,请授权。"
} else {
// 第一次请求,或用户选择了“不再询问”
"需要相机权限才能使用此功能。"
}
Text(textToShow)
Spacer(Modifier.height(8.dp))
Button(onClick = { cameraPermissionState.launchPermissionRequest() }) {
Text("请求权限")
}
}
}
}
}3. 多个权限申请
例如同时申请读写存储权限。
kotlin
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun MultiplePermissionsSample() {
val multiplePermissionsState = rememberMultiplePermissionsState(
listOf(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.CAMERA
)
)
if (multiplePermissionsState.allPermissionsGranted) {
Text("所有权限都已搞定!")
} else {
Column {
Text(
getTextToShowGivenPermissions(
multiplePermissionsState.revokedPermissions,
multiplePermissionsState.shouldShowRationale
)
)
Button(onClick = { multiplePermissionsState.launchMultiplePermissionRequest() }) {
Text("请求权限")
}
}
}
}4. 原生方式 (不依赖 Accompanist)
如果你不想引入额外库,可以使用原生的 ActivityResultLauncher。
kotlin
@Composable
fun NativePermissionSample() {
var hasPermission by remember { mutableStateOf(false) }
val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission()
) { isGranted ->
hasPermission = isGranted
}
Button(onClick = { launcher.launch(android.Manifest.permission.CAMERA) }) {
Text(if (hasPermission) "已授权" else "点击授权")
}
}