我在Jetpack Compose中有以下权限检查:
val launcher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
if (permissions.values.first { true }) {
log.info("Permission is granted")
shouldDisplayQuestionDialog.value = true
} else {
log.info("Permission is not granted")
}
}
当我拒绝权限时,权限不被授予日志被调用一次。
现在我把代码改成:
val displayEmptyScreen = remember { mutableStateOf(false) }
val launcher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
if (permissions.values.first { true }) {
log.info("Permission is granted")
shouldDisplayQuestionDialog.value = true
} else {
log.info("Permission is not granted")
displayEmptyScreen.value = true
}
}
现在权限未被授予添加mutableStateOf
. log后调用两次。为什么呢?怎么让它叫一次?
附录
@Composable
private fun DisplayPermissionDialog(shouldDisplayQuestionDialog: MutableState<Boolean>) {
val displayEmptyScreen = remember { mutableStateOf(false) }
val launcher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
if (permissions.values.first { true }) {
log.info("Permission is granted")
shouldDisplayQuestionDialog.value = true
} else {
log.info("Permission is not granted")
displayEmptyScreen.value = true
}
}
DisplayQuestionAlertDialog(shouldDisplayQuestionDialog)
if (displayEmptyScreen.value) {
Box {
// This box works as background
Box(
modifier = Modifier
.matchParentSize()
.background(Color.White)
)
}
}
val context = LocalContext.current
when (PackageManager.PERMISSION_GRANTED) {
ContextCompat.checkSelfPermission(
context,
Manifest.permission.READ_EXTERNAL_STORAGE
) -> {
LaunchedEffect(Unit) {
log.info("Set State for mutableStateFlow")
viewModel.setState()
}
DisplayQuestionAlertDialog(shouldDisplayQuestionDialog)
}
else -> {
Handler(Looper.getMainLooper()).post {
// Asking for permission
launcher.launch(
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
)
}
}
}
}
您的代码保证DisplayPermissionDialog()
将被调用至少两次,如果您在最初调用DisplayPermissionDialog()
时没有权限。
第一次通过时,如果您没有权限,您将进入when()
的else
分支,并使用launcher
打开系统权限对话框。这将最终触发launcher
上的lambda,无论您是否被授予权限,它都会改变状态。
由于DisplayPermissionDialog()
读取相同的状态,DisplayPermissionDialog()
将被第二次调用(该函数被"重组")。并且,在第二次执行时,如果您没有权限,您将进入when()
的else
分支,并且您将使用launcher
来打开系统权限对话框。这将最终触发launcher
上的lambda,无论您是否被授予权限,它都会改变状态。
坦率地说,一旦你达到Android停止显示系统权限对话框的地步,我预计会出现无限的重组链。
:
-
当用户拒绝您的权限请求时,不要改变该函数读取的状态,或者
-
安排这样,当您不持有权限时,每次调用此函数时,您不会在
launcher
上调用launch()
我不能给你更具体的建议,因为这不是我的职责,我不完全明白你在这里想做什么。
要了解更多信息,您可能需要观看有关撰写UI中的运行时权限的屏幕截图。或者,尝试伴奏者的权限组合-看到更多关于该库的媒体帖子。