Blog AndroidX ActivityResultContracts
Blog
Cancel

AndroidX ActivityResultContracts

Starting with the AndroidX Activity 1.2.0-alpha02 and AndroidX Fragment 1.3.0-alpha02 artifacts the Activity result ceremony will never be the same.

Let’s forget about startActivityForResult() and onActivityResult(), they really need some rest after being available since day 0 on the Android SDK.

What are ActivityResultContracts

An ActivityResultContract defines the input type needed to produce a result along with the output type of the result.

The ActivityResultContracts class contains many contracts for basic actions like taking a picture and requesting permissions, and most likely that list will grow, but there’s more: you can create custom contracts to better fulfill your needs.

Custom contracts

Let’s go straight to the point. Here’s an example of a custom one I needed in order to open the media gallery to pick some content…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.activity.result.contract.ActivityResultContract

class PickPhotoActivityContract : ActivityResultContract<String, Uri?>() {

    override fun createIntent(context: Context, input: String) =
        Intent(
            Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        ).apply { type = input }

    override fun parseResult(resultCode: Int, intent: Intent?) =
        intent?.data?.takeIf { resultCode == Activity.RESULT_OK }
}

…and this is how to use it on a Fragment or Activity, for instance I’d like to pick an image from the gallery:

1
2
3
4
5
6
7
8
9
private val pickPhotoLauncher = registerForActivityResult(PickPhotoActivityContract()) { uri ->
    uri?.let {
      // Do anything with it
    }
}
...
viewBinding.button.setOnClickListener {
    pickPhotoLauncher.launch("image/*")
}

As you can see a contract has to implement two methods:

  • createIntent(…) to create a well-formed Intent with any extras needed starting from the specified type (String in the example above)
  • parseResult(…) to map the result to an appropriate data model (Uri in the example above, it’s nullable to handle failures and cancellations)

References

The official documentation is the way to go to get a lot more context and see many examples of the expected usage.

This post is licensed under CC BY 4.0 by the author.
Trending Tags
Contents

Trending Tags