ActivityResultContracts by Examples

Since Android came into existence in 2007, Activity has been one of its core components. I of the most common tasks in apps is transferring information between two Activities. Until at present, Intents and onActivityResult were the only selection.

Through the combination of these two parts, developers are able to transfer information from 1 Activity to another and get data back hands.

Let'due south elaborate through an example: your app wants to capture an image and brandish it to the user. You either write your ain custom Camera or delegate the task of fetching an epitome to Android through Intents. In this second scenario, Android system will open the user-preferred Camera app, capture the paradigm and deliver the requested data to your activity by calling onActivityResult() method.

I am working on the video tutorial of this commodity and volition upload information technology on my YouTube channel presently. Delight subscribe to lookout that and more Android tutorials like this.


Subscribe to My YouTube Channel


Traditional Way — The onActivityResult() Method

Whether its an paradigm Bitmap from Photographic camera app or its a Image from the gallery, or mayhap its some custom event from your some other Activeness of app, Android system will call onActivityResult() method in the original requesting Activity or Fragment grade.

If yous 1 example of capturing image or multiple cases like picking images from gallery, requesting gazillion permissions, and handling your ain custom data with app's other screens, all the results of these deportment are handled in only one method onActivityResult() . And this method will wait something similar this in your code.

I take a feeling that yous don't like this kind of code to read / write at all. Neither do I. Considering this kind of lawmaking brings lots of bug and unwanted bugs such every bit:

  • Tight Coupling: There'due south no other place where you tin can put or abstruse this code and business concern logic. Similar if you want to separate each instance of Image Capture or Pick Image etc. Y'all can't do that. Y'all tin consul afterwards, but starting point is this. And this will create a bad cluster like in a higher place lawmaking with nested if-else blocks.

  • Type-Safe: You may get wrong type of data by minor mistakes. You can get your Integer value as String and later spend hours on debugging why app's not working the way its supposed to. This is because you are relying on String keys to put/read from Intent data. Y'all volition have to make certain that you are using correct type for the right key.

  • Unwanted NullPointerException: Who is not bellyaching of NullPointerException ? If yous get a typo in writing key of to either put or recall data in the Intent , yous will get the NullPointerException similar a bombing crash in your app. This tin waste a lot of fourth dimension as you might debug on why your data is zippo. How are you supposed to remember that you can mistakenly miss some letter in your key at that time?

And so, Google brings us a solution which is cleaner in code readability with non much if-else blocks, less coupling and separate places for each instance, type prophylactic to make sure the correct information gets to right method, and admittedly no NullPointerException because of typos.


Introducing Activity Results API — The New Fashion

I'thou not certain what this will be chosen — Activity Results API or Action Event Contracts or both. Simply surely information technology sounds nice.

Starting with Activity 1.ii.0-alpha02 and Fragment i.3.0-alpha02, you now accept a nice abstraction which allows you to handle onActivityResult() method in a very clean and reusable structure.

Permit's see how this new API is used then.


Adding Dependencies

First, yous have to add together the following dependencies in your app's build.gradle file.

Please notation that at the time of writing this article, latest version is one.2.0-alpha04 for activeness-ktx and 1.3.0-alpha04 for fragment-ktx . You can check the latest version from the Google Maven link. These APIs are in the alpha phase yet, then API is not final nonetheless. These can be changed at whatsoever time. The commodity works with alpha04 version just may or may non piece of work with earlier or later versions.


The Procedure for Activity Results API

The process to use this new API looks like this.

Activity Results API process

1. Create Contract

Get-go, you have to either define your contract or use any existing one. A contract is the implementation of ActivityResultContract interface. Taken from the documentation, this is a contract specifying that an activity can exist chosen with an input of blazon I and produce an output of type O.

Here'due south a an case of SimpleContract which takes an Integer as input and returns some String information from the child Activeness.

The createIntent() method is used to create the valid Intent which volition be passed in startActivityForResult() method once this contract is called. And the parseResult() method will deport as a proxy for onActivityResult() method and is parsing the effect Intent and extracting the data from information technology.

You can see that we don't need to put bunch of if-else blocks in onActivityResult() method anymore. Because each case will be handled like this in divide implementation and split parseResult() method. This is the beauty and simplicity of the Activity Results API.

two. Register Contract

The next stride is to register this SimpleContract with the Activity Results API. This is done through calling registerForActivityResult() method.

Please note that in previous versions alpha02 and alpha03 , this method was called as prepareCall() . But in alpha04 , this was renamed to registerForActivityResult() .

You tin can see how easy it to register your contract. And with the simplicity of beloved Kotlin, yous will go the consequence in a nice lambda method. This volition be chosen after the parseResult() method from the contract and volition requite you lot the outcome (in our case a nullable Cord). You can bank check for the Zippo value to encounter if user cancelled the action or the result was RESULT_OK from the child activeness.

iii. Telephone call Contract

Finally, all you have to do is brand the call to this new registration variable which is simpleContractRegistration in the above snippet. Get alee and call it just like whatsoever ordinary method. And all the input you defined in the contract volition exist passed as blazon-safe parameters in your method call.

And voila. No more onActivityResult() now. You can easily use this with your own custom Activity or Fragmentclasses and information technology volition exist very make clean, organized, and reusable code with type-safe parameters.


Pre-Built Contracts

At present that you lot have seen how elementary it is to utilize the Activity Outcome API and create your own contracts. You volition exist super glad to know that Google has provided some very useful pre-built contracts. These can be accessed statically from the ActivityResultContracts class. Permit's explore some examples below.

Capturing Images — ActivityResultContracts.TakePicture()

You tin easily capture the images from Camera without whatsoever hassle of Media Intent.


Option Images — ActivityResultContracts.GetContent

This allows you to pick not only images but you lot tin also select other files from your device. Yous have to provide mimeType of the files yous need in app.


Requesting Permissions — ActivityResultContracts.RequestPermission

Now this is my most favorite one. I remember that I had to write like 100 lines of code to inquire for multiple permissions to handle a very circuitous flow. I had written about it details in this article when there were no Activity Results API yet.

Multiple Runtime Permissions in Android Without Any 3rd-Party Libraries

The Action Results API provides 2 methods — RequestPermission and RequestMultiplePermissions . These two does exactly what their names are. Here's a quick example code.


Demo Code

I have created a unproblematic demo project with some case contracts every bit discussed in this article on the post-obit Github repository. You lot can explore more than and play with information technology.

wajahatkarim3/ActivityResultsDemo


Conclusion

Wrapping it up now, in this commodity nosotros discussed near some bug in the traditional onActivityResult() fashion. And and then we got to learn nigh new Action Results API. And so nosotros created an instance contract to run across how different parts work together. And finally we saw some pre-congenital contracts like epitome capturing, picking images, permission handling etc.

At the terminate, please don't forget to Subscribe to my newsletter to get more tutorials and tips on Android development directly in your inbox.


Thanks to Roberto Orgiu for reviewing and providing feedback on this mail service 🙌