androidandroid-jetpackandroid-jetpack-composeregisterforactivityresult

Jetpack Compose: Launch ActivityResultContract request from Composable function


As of 1.2.0-beta01 of androidx.activity:activity-ktx, one can no longer launch the request created using Activity.registerForActivityResult(), as highlighted in the above link under "Behavior Changes" and seen in the Google issue here.

How should an application launch this request via a @Composable function now? Previously, an app could pass the instance of the MainActivity down the chain via using an Ambient and then launch the request easily.

The new behavior can be worked around by, for example, passing a class registering for the activity result down the chain after being instantiated outside of the Activity's onCreate function, and then launch the request in a Composable. However, registering the a callback to be executed after completion cannot be done this way.

One could get around this by creating custom ActivityResultContract, which, at launch, take a callback. However, this would mean that virtually none of the built-in ActivityResultContracts could be used with Jetpack Compose.

TL;DR

How would an app launch an ActivityResultsContract request from a @Composable function?


Solution

  • As of androidx.activity:activity-compose:1.3.0-alpha06, the registerForActivityResult() API has been renamed to rememberLauncherForActivityResult() to better indicate the returned ActivityResultLauncher is a managed object that is remembered on your behalf.

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