简体   繁体   English

如何使用 Jetpack Compose 处理 Activity.onActivityResult()?

[英]How to handle Activity.onActivityResult() with Jetpack Compose?

I am trying to implement sign-in hints in my Android app using Jetpack Compose, but this API requires an Activity to work.我正在尝试使用 Jetpack Compose 在我的 Android 应用程序中实现登录提示,但是这个 API 需要一个Activity才能工作。

fun showPhoneNumberHint(activity: Activity) {
    val hintRequest: HintRequest = HintRequest.Builder()
        .setPhoneNumberIdentifierSupported(true)
        .build()

    val intent = Auth.CredentialsApi.getHintPickerIntent(apiClient, hintRequest)
    val requestCode = 12345

    try {
        startIntentSenderForResult(activity, intent.intentSender, requestCode, null, 0, 0, 0, null)
    } catch (exception: SendIntentException) {
        // Error handling
    }
}

So I guess that I'll have to pass the Activity object all the way down to the Composable where it's needed, which doesn't seem very clean but it should work.所以我想我必须将 Activity object 一直传递到需要它的 Composable ,这看起来不是很干净,但它应该可以工作。

But now the result of the hint will be received in the Activity's onActivityResult() and I'm not sure what the right way is to get it back to the Composable where it's needed.但是现在提示的结果将在 Activity 的onActivityResult()中收到,我不确定将它返回到需要它的 Composable 的正确方法是什么。

Is there some clean/standard/alternative way to do this?有没有一些干净/标准/替代的方法来做到这一点? Preferably I'd just keep all of this logic contained inside the Composable.最好我只是将所有这些逻辑包含在 Composable 中。

I ended up using rememberLauncherForActivityResult in combination with the ActivityResultContracts.StartIntentSenderForResult() contract to listen for the result.我最终将rememberLauncherForActivityResultActivityResultContracts.StartIntentSenderForResult()合同结合使用来监听结果。 This returns a launcher that can be used to start the intent.这将返回一个可用于启动意图的launcher

Instead of Auth.CredentialsApi , which requires the deprecated GoogleApiClient , I'm now using the Credentials.getClient .我现在使用的是Credentials.getClient而不是Auth.CredentialsApi ,它需要已弃用的GoogleApiClient For this I still needed an Activity which I got using LocalContext.current .为此,我仍然需要使用LocalContext.current获得的Activity

val phoneNumberHintLauncher = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.StartIntentSenderForResult()
) {
    if (it.resultCode != RESULT_OK) {
        return@rememberLauncherForActivityResult
    }

    val credential: Credential? = it.data?.getParcelableExtra(Credential.EXTRA_KEY)
    val hintResult = credential?.id

    if (hintResult !== null) {
        phoneNumber = hintResult
    }
}

val context = LocalContext.current

LaunchedEffect(Unit) {
    val hintRequest: HintRequest = HintRequest.Builder()
        .setPhoneNumberIdentifierSupported(true)
        .build()

    val phoneNumberHintIntent = Credentials.getClient(context)
        .getHintPickerIntent(hintRequest)

    phoneNumberHintLauncher.launch(
        IntentSenderRequest.Builder(phoneNumberHintIntent)
            .build()
    )
}

Activity.onActivityResult() is deprecated and you shouldn't use it even without compose. Activity.onActivityResult()已被弃用,即使没有 compose,也不应使用它。 You should use the Activity Result APIs introduced in AndroidX Activity and Fragment.您应该使用 AndroidX Activity 和 Fragment 中介绍的 Activity Result API。

The Activity Result APIs provide a registerForActivityResult() API for registering the result callback.活动结果 API 提供registerForActivityResult() API 用于注册结果回调。 registerForActivityResult() takes an ActivityResultContract and an ActivityResultCallback and returns an ActivityResultLauncher which you'll use to launch the other activity. registerForActivityResult()接受一个ActivityResultContract和一个ActivityResultCallback并返回一个ActivityResultLauncher ,您将使用它来启动其他活动。

Example without compose:没有撰写的示例:

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    val selectButton = findViewById<Button>(R.id.select_button)

    selectButton.setOnClickListener {
        // Pass in the mime type you'd like to allow the user to select
        // as the input
        getContent.launch("image/*")
    }
}

In compose use rememberLauncherForActivityResult() instead of registerForActivityResult :在撰写中使用rememberLauncherForActivityResult()而不是registerForActivityResult

val result = remember { mutableStateOf<Bitmap?>(null) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.TakePicturePreview()) {
    result.value = it
}

Button(onClick = { launcher.launch() }) {
    Text(text = "Take a picture")
}

result.value?.let { image ->
    Image(image.asImageBitmap(), null, modifier = Modifier.fillMaxWidth())
}

The problem with the API you're trying to use is it requires the use of onActivityResult.您尝试使用的 API 的问题是它需要使用 onActivityResult。 So, you have no other option but to use it.因此,您别无选择,只能使用它。 Try opening an issue on github requesting to update their API.尝试在 github 上打开一个问题,请求更新他们的 API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 结果代码始终为 0,请求始终为 -1,。 Activity.onActivityResult(); - resultCode is always 0 and request is always -1, . Activity.onActivityResult(); 如何在 Jetpack Compose 中处理 Mapbox Map 的活动生命周期事件? - How to handle activity lifecycle events for Mapbox Map in Jetpack Compose? Uri on Activity.onActivityResult(int requestCode,int resultCode,Intent数据) - Uri on Activity.onActivityResult(int requestCode, int resultCode, Intent data) "如何处理 Jetpack Compose 中的导航?" - How to handle navigation in Jetpack Compose? 如何在撰写导航中处理类似于 onActivityResult 的行为? - How to handle behavior similar to onActivityResult in compose navigation? 如何在 Jetpack Compose 中获取 Activity 的标签? - How to get Activity's Label in Jetpack Compose? 如何在 Jetpack Compose 中处理 State? - How Can I Handle State In Jetpack Compose? 如何处理 Jetpack Compose 的 TextField 中的 doOnTextChanged 和 doBeforeTextChanged? - How to handle doOnTextChanged and doBeforeTextChanged in TextField of Jetpack Compose? 如何处理 Jetpack Compose 中文本的可见性? - How to handle visibility of a Text in Jetpack Compose? 如何处理 Jetpack Compose 中被拒绝的权限 - How to handle permission denied in jetpack compose
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM