Remove startActivityForResult, use the Activity Result APIs

Tram Ho

When you start another activity, whether it’s an activity in your app or from another application, it doesn’t need to be a one-way activity. You can also start an acitivty and get the result again. For example, your application can launch the camera application and receive the captured image as a result. Or, you can start the Contacts app so the user selects a contact and as a result you will get contact details.

Although the basic startActivityForResult () and onActivityResult () APIs are available in the Activity class on all API levels, I recommend using the Activity Result APIs introduced in Activity AndroidX 1.2.0-alpha02 and Fragment. 1.3.0-alpha02.

The Activity Result APIs provide components to register results, launch the results, and process the results after the system sends them.

To be more specific about how to use the Activity Result APIs , I will introduce the following two cases using the Activity Result APIs . (Note there are many other similar cases for using API result)

1. Request Runtime Permissions

Recently, Android stopped using the old ActivityResult API and introduced new APIs with AndroidX Activity 1.2.0-alpha02. This makes request runtime permissions easier. With the new APIs available, developers can register results, launch for results, and then process the results generated by the system.

But Why?

When we start activity for a result, there is a possibility that your process and activity will be destroyed due to lack of memory, for activities that require a lot of memory like using the camera. Hence, the result APIs work separating the result callback from the location in your code where the other activity is launched.

Hence, unfortunately when the process or activity is re-created, the callback has to register it all the time, even if another start Activity logic just happens based on user input or other business logic.

What is different?

Previously, we had to manage request code while requesting permission by passing it to requestPermissions () method . And then use that request code while fetching result in the OnRequestPermissionResult () method as shown below.

With the new Activity Result API, we won’t have to manually manage the request codes because the system handles it internally.

The new Activity Result API provides the registerForActivityResult () API to register the result callback command. It needs an ActivityResultContract and an ActivityResultCallback and returns an ActivityResultLauncher , using them we can launch another activity as shown below.

  • ActivityResultContract: specifies the type of input needed to generate result. In the example above ActivityResultContracts.RequestPermission () is used which means the acticity launcher will require android permissions as input input.
  • ActivityResultCallback: specifies how we will treat the user’s response to the authorization request.
  • When the launch () method is called with CAMERA permission as input, the permission dialog (appears in request permison dialog) asking for CAMERA permission will be displayed. Based on the user’s response to the permission, the system calls activityResultCallback .

Similarly, many other permissions can be requested at the same time by passing a permissions array instead of a single permissions as input and then we get a MutableMap with the permission key and grant result as value in activityResultCallback .

2. Launching an activity for get content result

While registerForActivityResult () registers your callback, it doesn’t start another activity and starts asking for result. Instead, it is the responsibility of the ActivityResultLauncher instance that is returned.

If the input for the launch () method exists, the launcher will take input matching the ActivityResultContract type. Calling the launch () method will initiate the result generation process. When the user completes the next activity and returns the activity, onActivityResult () from ActivityResultCallback will then be executed, as shown in the following example:

Above, we call launch (“image /”) , the parameter is a string mime type image, the launcher will take input matching ActivityResultContract here is GetContent () and will return the results. Conforming to the GetContent ResultContact is the Uri itself. There are also many other similar input types.

Receiving an activity result in a separate class

Get the result activity in a separate class.

While the ComponentActivity and Fragment classes implement the ActivityResultCaller interface to allow you to use the registerForActivityResult () APIs, you can also get the result activity in a separate class without implementing ActivityResultCaller directly using ActivityResultRegistry.

For example, you might want to deploy LifecycleObserver which handles contract signing along with launching the launcher:

When using ActivityResultRegistry APIs, you should use APIs that use LifecycleOwner, since LifecycleOwner will automatically delete your registered launcher when lifecycle onDestroy is destroyed. However, in the event that LifecycleOwner is not available, each ActivityResultLauncher class still allows you to manually call unregister () instead.

Creating a custom contract

Updating….

For more details, you can see the official documentation here:

Reference source: https://medium.com/codex/android-runtime-permissions-using-registerforactivityresult-68c4eb3c0b61

Share the news now

Source : Viblo