今天大概会聊到的范围
- rememberLauncherForActivityResult
上一篇我学到可以透过 AndroidView 中将 CameraX 的 PreviewView 加入 Compose 中,要显示相机的画面,还需要取得 User 的 Permission。所今天想来研究一下如果我的 Compose 元素想要与 Permission 互动应该怎麽处理。
首先,取得 permission 并不会太复杂:
// checkPermission
private fun checkPermissionsGranted(context: Context) = REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
取得 permission 时会需要 Context,而在 Compose 中要取得 Context 可以透过 LocalContext.current 取得
@Composable
fun CameraScreen() {
// 取得 context
val context = LocalContext.current
// 检查完 permission 後将答案存在 remember 中
var hasPermission by remember {
mutableStateOf(checkPermissionsGranted(context))
}
if (hasPermission) {
CameraView()
} else {
LoadingView()
}
}
startActivityForResult in Compose
接下来,我们需要透过 startActivityForResult 向 User 请求 permission。在 Compose 中,可以透过 rememberLauncherForActivityResult 建立一个 launcher。这个 launcher 中的 callback 我们可以对 result 做处理(这边我们将 result 存放回 state )
var hasPermission by remember { // ...
val permissionRequester = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
hasPermission = isGranted
}
permissionRequester 并不会立刻起作用,而是要在需要取得的时候触发:
if (hasPermission) {
CameraView()
} else {
LoadingView(modifier = Modifier.clickable { permissionRequester.launch(Manifest.permission.CAMERA) })
}
使用rememberLauncherForActivityResult 时,需要提供一个 contract 和一个 callback
@Composable
public fun <I, O> rememberLauncherForActivityResult(
contract: ActivityResultContract<I, O>,
onResult: (O) -> Unit
): ManagedActivityResultLauncher<I, O> {
ActivityResultContract 各种 startActivityForResult 的流程,例如 ActivityResultContract.RequestPermission 可以取得一个 Permission ,另外还有 ActivityResultContract.RequestMultiplePermissions 可以一次请求多种权限。当今天内建的流程不符合需求时,还可以使用 ActivityResultContract.StartIntentSenderForResult 自订
class RequestPermission extends ActivityResultContract<String, Boolean>
ActivityResultContract 会需要一个 input 和一个 output 的 type,以 RequestMultiplePermissions 为例, input 就是一个 String ( permission key),output 则是 Boolean 代表是否接受权限。output 的资料会在 callback ( onResult ) 中出现,input 则是在 launch 时提供
完成以上,就可以在 user 点击 LoadingView 後跳出权限取得的 Dialog。但是如果今天要自动 launch 则会出现 Launcher has not been initialized 的错误。这个原因会需要提到 SideEffect,主题满大的,之後再独立一篇分享吧!
>>: 30天学会C语言: Day 16-你可能会用到的函式
讲到团队(Team),就会先讲到团体(Group)这个字,谈团队之前,其实要先这样想:根本没有团队这...
函式没办法使用其他函式中的变数 #include <stdio.h> #include ...
Web 应用程序选单多样化,早期最常见的多半树状选单,直至手机问世後汉堡选单(hamburger m...
前面介绍许多 State Machine 及 XState 的功能,由於篇幅不多了,今天想跟大家先快...
在上一章中介绍了如何建立客制化的 attribute directive 与使用,而本章将会介绍如何...