权限调用两次,当我们有mutableStateOf在Jetpack撰写



我在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中的运行时权限的屏幕截图。或者,尝试伴奏者的权限组合-看到更多关于该库的媒体帖子。

相关内容

最新更新