In the ever-evolving world of Android development, it’s important to be aware of new tools and techniques. The startActivityForResult() method has been officially deprecated starting from Android 11 (API level 30), it has Deprecated startActivityForResult in favor of RegisterForActivityResult.
First, when the application needs to start another Activity and get the results from it, the developers need to use the startActivityForResult() method which involves managing the application code and handling the result of the onActivityResult() method.
When is ActivityForResultLuncher called?
ActivityForResultLuncher simplifies the work to get the result from another activity by removing the requestcode and the onActivityResult() method which was used earlier with onActivityresult().
private ActivityResultLauncher<Intent> launcher
= registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK) {
Intent data = result.getData();
tvResult.setText(data.getStringExtra("result"));
}
}
);
Here we see that registerForActivityResult takes two parameters. The first defines the type of action/interaction needed (ActivityResultContracts) and the second is a callback function where we receive the result.
registerForActivityResult() is safe to call before your fragment or activity is created, letting it be used directly when declaring member variables for the returned ActivityResultLauncher instances.
Note: You must call registerForActivityResult() before the fragment or activity is created, but you can’t launch the ActivityResultLauncher until the fragment or activity’s Lifecycle has reached CREATED
The ActivityForResultLauncher is called when we call the launch() method on the activity. This method is used to start the other activity to receive a result back from the other activity. It simplifies the process of starting an activity and handling the result, as compared to the traditional approach i.e., startActivityForResult().
Steps:
1. Initialize ActivityForResultLauncher: This is typically done in the calling activity’s onCreate() method or any other appropriate initialization method.
2. Launching an Activity for Result: Whenever you want to start another activity and receive a result from it, you call the launch() method. You pass an intent that describes the activity you want to start.
3. The launched activity (NextActivity) is displayed to the user: The user interacts with this activity according to its functionality.Once the user completes the interaction with the launched activity send a result back to the calling activity, you set the result in the NextActivity and finish the activity.
4. Then the callback defined during the initialization of the ActivityResultLauncher is triggered automatically when the NextActivity finishes. This callback receives the result data, and you can use it as needed.
Activity A calls Activity B for the result:
MainActivity XML
XML
<? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" tools:context = ".MainActivity" > < TextView android:layout_width = "match_parent" android:layout_height = "wrap_content" android:text = "Geeks For Geeks" android:textSize = "50dp" android:textColor = "@color/black" android:layout_marginTop = "20dp" android:gravity = "center" /> < TextView android:id = "@+id/tvResult" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:textSize = "30dp" android:gravity = "center" android:layout_marginTop = "200dp" android:text = "Result will show" /> < Button android:id = "@+id/btnResult" android:layout_width = "250dp" android:layout_gravity = "center" android:layout_marginTop = "20dp" android:textSize = "20dp" android:layout_height = "wrap_content" android:text = "Get Result" /> </ LinearLayout > |
MainActivity:
Java
package com.example.gfg; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private ActivityResultLauncher<Intent> launcher; Button btnResult ; TextView tvResult; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnResult = findViewById(R.id.btnResult); tvResult = findViewById(R.id.tvResult); launcher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == RESULT_OK) { Intent data = result.getData(); tvResult.setText(data.getStringExtra( "result" )); } } ); btnResult.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // This is same as we go one activity to another Intent intent = new Intent(MainActivity. this ,SecondActivity. class ); // Rathher than calling startActivity(intent) we use this code launcher.launch(intent); } }); } } |
SecondActivity XML:
XML
<? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" tools:context = ".SecondActivity" > < TextView android:id = "@+id/textView" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:textSize = "25dp" android:textColor = "@color/black" android:gravity = "center" android:layout_gravity = "center" android:layout_marginTop = "200dp" android:text = "GFG" /> < Button android:id = "@+id/button" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_margin = "20dp" android:textSize = "25dp" android:text = "Button" /> </ LinearLayout > |
SecondActivity:
Java
package com.example.gfg; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; public class SecondActivity extends AppCompatActivity { Button btnSend; TextView text; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_second); btnSend = findViewById(R.id.button); text = findViewById(R.id.textView); btnSend.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(SecondActivity. this ,MainActivity. class ); intent.putExtra( "result" ,text.getText().toString()); setResult(RESULT_OK,intent); finish(); } }); } } |
Output:
Here is the few points why we should use ActivityForResultLauncher:
- Simplicity: It simplifies the code by removing the need of request codes and handling results in a separate method.
- Type Safety: It leverages Java generics, providing better safety compared to the older approach.
- Readability: The code becomes more readable and understandable, making it easier for developers.
- Consistency: It aligns with the direction Android development is taking, promoting consistent and modern coding practices.
Some common use of this:
- User Profile Editing: When a user wants to edit their profile information, you can use ActivityForResultLauncher to launch an activity where they can make changes. Once they’re done, the edited data can be returned to the calling activity using the result callback.
- Image Selection and Capture: If your app requires users to pick images from their gallery or capture new images using the camera, ActivityForResultLauncher can be used to start the image selection or capture activity and receive the chosen/captured image as a result.
- Payment Processing: In apps that handle payments, you might need to start an activity to process payments. After the payment is completed (or canceled), the result can be returned to the calling activity using the launcher.