Skip to content Skip to sidebar Skip to footer

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. fun showPhoneNumberHint(activity: Activity) { val hin

Solution 1:

I ended up using rememberLauncherForActivityResult in combination with the ActivityResultContracts.StartIntentSenderForResult() contract to listen for the result. This returns a launcher that can be used to start the intent.

Instead of Auth.CredentialsApi, which requires the deprecated GoogleApiClient, I'm now using the Credentials.getClient. For this I still needed an Activity which I got using LocalContext.current.

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()
    )
}

Solution 2:

Activity.onActivityResult() is deprecated and you shouldn't use it even without compose. You should use the Activity Result APIs introduced in AndroidX Activity and Fragment.

The Activity Result APIs provide a registerForActivityResult() API for registering the result callback. registerForActivityResult() takes an ActivityResultContract and an ActivityResultCallback and returns an ActivityResultLauncher which you’ll use to launch the other activity.

Example without compose:

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

overridefunonCreate(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:

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. So, you have no other option but to use it. Try opening an issue on github requesting to update their API.

Post a Comment for "How To Handle Activity.onactivityresult() With Jetpack Compose?"