23 July 2020
Posted by Yacine Rezgui, Developer Advocate
Whether you're requesting a permission, selecting a file from the system file manager, or expecting data from a 3rd party app, passing data between activities is a core element in inter-process communication on Android. We’ve recently released the new ActivityResult
APIs to help handle these activity results.
Previously, to get results from started activities, apps needed to implement an onActivityResult()
method in their activities and fragments, check which requestCode
a result is referring to, verify that the requestCode
is OK, and finally inspect its result data or extended data.
This leads to complicated code, and it doesn’t provide a type-safe interface for expected arguments when sending or receiving data from an activity.
The ActivityResult APIs
were added to the Jetpack activity
and fragment
libraries, making it easier to get results from activities by providing type-safe contracts. These contracts define expected input and result types for common actions like taking a picture or requesting a permission, while also providing a way to create your own contracts.
The ActivityResult
APIs provide components for registering for an activity result, launching a request, and handling its result once it is returned by the system. You can also receive the activity result in a separate class from where the activity is launched and still rely on the type-safe contracts.
To demonstrate how to use the ActivityResult
APIs, let’s go over an example where we’re opening a document.
First, you need to add the following dependencies to your gradle file:
repositories { google() maven() } dependencies { implementation "androidx.activity:activity:1.2.0-alpha02" implementation "androidx.fragment:fragment:1.3.0-alpha02" }
You need to register a callback along with the contract that defines its input and output types.
In this context, GetContent()
refers to the ACTION_GET_DOCUMENT
intent, and is one of the default contracts already defined in the Activity library. You can find the complete list of contracts here.
val getContent = registerForActivityResult(GetContent()) { uri: Uri? -> // Handle the returned Uri }
Now we need to launch our activity using the returned launcher. As you can set a mime type filter when listing the selectable files, GetContent.launch()
will accept a string as a parameter:
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/*") } }
Once an image has been selected and you return to your activity, your registered callback will be executed with the expected results.
As you saw through the code snippets, ActivityResult brings an easier developer experience when dealing with results from activities.
Start using Activity 1.2.0-alpha02
and Fragment 1.3.0-alpha02
for a type-safe way to handle your intent results with the new ActivityResult
APIs.
Let us know what you think and how we can make it better by providing feedback on the issue tracker.