How to Use startActivityForResult() in Android – A Step-by-Step Guide

Posted byreaderavskh Posted onMarch 3, 2025 Comments0

Introduction

In Android development, it’s very common to pass data between activities. Activities are the building blocks of an Android application, and often you need to move from one activity to another while sending and receiving information. The most popular way to achieve this is by using Intent and methods like startActivityForResult() and onActivityResult().

In this detailed tutorial, we will walk through the process of:

  1. Sending data from one activity to another.
  2. Receiving the data back from the second activity to the first.

We will demonstrate this by creating two activities:

  • MainActivity: The primary screen where users can click a button to open another activity.
  • SecondActivity: A secondary screen where users can input some data, which will be sent back to the first activity.

This tutorial will give you a clear understanding of how to pass data between Android activities and handle the result. By the end of this, you’ll be able to use this technique in your own Android projects when you need to pass data between activities.

Let’s begin by explaining the concept and the workflow step-by-step.

What Are Intent and startActivityForResult()?

  • Intent: An Intent in Android is used to communicate between different components of the app, like activities, services, or broadcast receivers. You can think of an Intent as a message that tells the system to perform a particular action, such as opening another activity or passing data.
  • startActivityForResult(): This method is used when you want to start a new activity and get a result back from it. Unlike startActivity(), which simply opens another activity, startActivityForResult() allows the launched activity to return data to the calling activity once it’s finished.
  • onActivityResult(): This is the method where you handle the data that is returned from the launched activity. Once the second activity finishes, it returns the result (such as some user input) through this method.

The core idea behind this pattern is that the first activity sends data to the second activity, and the second activity sends some result back. This communication is essential in scenarios like collecting user input, selecting items from a list, or confirming a decision.

Step 2: Setting Up MainActivity to Send Data to SecondActivity

In this part of the tutorial, we will set up the MainActivity. This activity will contain a button that, when clicked, opens SecondActivity and expects a result back. Let’s walk through the code and explain how everything works.

2.1: Create the Layout for MainActivity

First, we need to define the layout for MainActivity. The layout will consist of:

  • A TextView to display the data received from SecondActivity.
  • A Button that, when clicked, opens SecondActivity.

Here’s how you can define the layout in XML:

<!-- activity_main.xml -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- TextView to display data received from SecondActivity -->
    <TextView
        android:id="@+id/display"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Data will appear here"
        android:layout_centerInParent="true"/>

    <!-- Button to open SecondActivity -->
    <Button
        android:id="@+id/gotosecond"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go to Second Activity"
        android:layout_below="@id/display"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"/>

</RelativeLayout>

In this layout:

  • The TextView is used to display the result coming back from SecondActivity.
  • The Button will trigger the transition to SecondActivity.

2.2: Implement the Code for MainActivity

Now let’s implement the logic in MainActivity. The steps are as follows:

  1. Find Views: We will find the TextView and Button using findViewById().
  2. Set Click Listener for the Button: When the button is clicked, we’ll create an Intent to open SecondActivity.
  3. Use startActivityForResult(): This method will allow us to launch SecondActivity and expect a result back.
  4. Handle the Result in onActivityResult(): Once SecondActivity finishes, we will get the result back in this method.

Here’s the Java code for MainActivity:

package com.developeravsk.intentwithresult;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    TextView tv; // TextView to display the data received
    Button go;  // Button to trigger the opening of SecondActivity

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); // Set the layout for this activity

        // Find the views
        tv = findViewById(R.id.display);
        go = findViewById(R.id.gotosecond);

        // Set an OnClickListener for the button
        go.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Create an Intent to open SecondActivity
                Intent i = new Intent(MainActivity.this, SecondActivity.class);
                
                // Start SecondActivity and expect a result back
                startActivityForResult(i, 1); // 1 is the requestCode
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Check if the result is from the expected requestCode
        if (requestCode == 1 && resultCode == RESULT_OK) {
            // Get the data sent back from SecondActivity
            String myData = data.getStringExtra("data");
            
            // Update the TextView with the received data
            tv.setText(myData);
        }
    }
}

Explanation of Code:

  1. Finding Views:
    • We use findViewById() to get references to the TextView and Button. The TextView is where we will display the data from the second activity, and the Button will trigger the opening of the second activity.
  2. Button OnClickListener:
    • We set an OnClickListener for the button. When the button is clicked, an Intent is created to open SecondActivity.
  3. startActivityForResult():
    • startActivityForResult(i, 1) is called to open SecondActivity. The 1 is a request code that identifies the request. It allows us to distinguish between different activity results if we have multiple activities that could return data.
  4. onActivityResult():
    • After SecondActivity completes, the data sent back is received in onActivityResult(). We check if the requestCode is 1 (which matches our startActivityForResult() request) and if the resultCode is RESULT_OK. Then we retrieve the data sent back using data.getStringExtra("data") and update the TextView.

Step 3: Setting Up SecondActivity to Send Data Back to MainActivity

In this part of the tutorial, we will implement SecondActivity. This activity will allow the user to input some data, and when the user presses the “Go Back” button, the data will be sent back to MainActivity.

3.1: Create the Layout for SecondActivity

We need to design the layout for SecondActivity. The layout will include:

  • An EditText field where users can type in some data.
  • A Button to send the data back to MainActivity.

Here’s how you can define the layout in XML:

<!-- activity_second.xml -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- EditText for user input -->
    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter some data"
        android:layout_centerInParent="true"
        android:padding="16dp"/>

    <!-- Button to send data back to MainActivity -->
    <Button
        android:id="@+id/goback"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go Back"
        android:layout_below="@id/et"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"/>

</RelativeLayout>

In this layout:

  • The EditText is where the user will type some data.
  • The Button will allow the user to return to MainActivity and send the input data back.

3.2: Implement the Code for SecondActivity

Now let’s implement the logic in SecondActivity. The steps are as follows:

  1. Find Views: We will find the EditText and Button using findViewById().
  2. Set Click Listener for the Button: When the button is clicked, we will gather the data from the EditText and send it back to MainActivity.
  3. Use setResult(): This method will send the result back to the calling activity.
  4. Finish the Activity: After sending the data back, we will call finish() to close SecondActivity and return to MainActivity.

Here’s the Java code for SecondActivity:

package com.developeravsk.intentwithresult;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import androidx.appcompat.app.AppCompatActivity;

public class SecondActivity extends AppCompatActivity {

    EditText data;  // EditText to take user input
    Button goback;  // Button to send data back to MainActivity

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second); // Set the layout for this activity

        // Find the views
        data = findViewById(R.id.et);
        goback = findViewById(R.id.goback);

        // Set an OnClickListener for the button
        goback.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Get the data entered by the user
                String userData = data.getText().toString();
                
                // Create an Intent to send data back to MainActivity
                Intent i = new Intent();
                i.putExtra("data", userData); // Attach the data to the Intent
                
                // Set the result with the data
                setResult(RESULT_OK, i);  // RESULT_OK indicates success
                
                // Finish the activity and go back to MainActivity
                finish();
            }
        });
    }
}

Explanation of Code:

  1. Finding Views:
    • We use findViewById() to get references to the EditText and Button. The EditText is where the user will type the data to send back, and the Button will trigger sending the data.
  2. Button OnClickListener:
    • We set an OnClickListener for the button. When the button is clicked, we retrieve the text entered in the EditText using data.getText().toString().
  3. Creating the Intent:
    • We create an Intent object that will be used to send the data back to MainActivity.
    • i.putExtra("data", userData) attaches the user input to the intent. The key "data" will be used to retrieve the data in MainActivity.
  4. Sending the Result:
    • We use setResult(RESULT_OK, i) to send the result back to the calling activity (MainActivity). The RESULT_OK indicates that the result was successful. If you wanted to indicate failure, you would use RESULT_CANCELED instead.
  5. Finish the Activity:
    • Finally, finish() is called to close SecondActivity and return to MainActivity. When this happens, MainActivity will receive the result in onActivityResult().

Step 4: Receiving Data in MainActivity and Displaying It

Now that we’ve successfully set up SecondActivity to send data back, the next step is to handle the returned data in MainActivity and display it on the screen.

4.1: Handling the Returned Data

When SecondActivity finishes and sends data back to MainActivity, we need to catch the result and handle it appropriately. This is done by overriding the onActivityResult() method in MainActivity.

Here’s how the data flow works:

  • MainActivity sends an intent to SecondActivity to gather data.
  • SecondActivity lets the user input data, and once they click the button, it sends the data back using setResult() and finish().
  • MainActivity receives the result in onActivityResult() and displays it on the screen.

4.2: Implementing onActivityResult() in MainActivity

In MainActivity, we need to override the onActivityResult() method to capture the data sent back from SecondActivity.

Here’s how the updated code for MainActivity looks:

package com.developeravsk.intentwithresult;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    TextView tv;  // TextView to display the data returned
    Button go;   // Button to open SecondActivity

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);  // Set the layout for this activity

        // Find the views
        tv = findViewById(R.id.display);  // The TextView to display returned data
        go = findViewById(R.id.gotosecond); // Button to go to SecondActivity

        // Set an OnClickListener for the button
        go.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Create an Intent to open SecondActivity
                Intent i = new Intent(MainActivity.this, SecondActivity.class);
                startActivityForResult(i, 1);  // Start SecondActivity and expect a result
            }
        });
    }

    // This method is called when SecondActivity finishes and sends back the result
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        
        // Check if the requestCode matches and the result was OK
        if (requestCode == 1 && resultCode == RESULT_OK) {
            // Retrieve the data sent back from SecondActivity
            String myData = data.getStringExtra("data");
            
            // Display the data on the TextView
            tv.setText(myData);
        }
    }
}

Explanation of Code:

  1. Finding Views:
    • We find the TextView (tv) and the Button (go) using findViewById(). The TextView will be used to display the data received from SecondActivity.
  2. Sending Data to SecondActivity:
    • When the button is clicked, we create an Intent to launch SecondActivity and use startActivityForResult() to initiate the intent. This method allows us to specify a request code (in this case, 1) to identify the result when it returns.
  3. Receiving the Data:
    • The onActivityResult() method is automatically called when SecondActivity finishes and sends data back. The requestCode parameter lets us confirm which activity is returning the result (in case we have multiple activities sending results).
    • If the requestCode is 1 and the resultCode is RESULT_OK, we retrieve the data using data.getStringExtra("data"). This is the data that was sent back from SecondActivity.
  4. Displaying the Data:
    • Finally, we set the returned data (myData) into the TextView (tv) using tv.setText(myData).

4.3: Running the App

  1. When you run the app, MainActivity will be displayed with a button labeled “Go to Second Activity.”
  2. When the user clicks the button, SecondActivity opens with an EditText for input and a “Go Back” button.
  3. The user types something in the EditText and clicks the “Go Back” button.
  4. The data is sent back to MainActivity, and it will be displayed in the TextView.

Recap of Data Flow

  1. MainActivity starts SecondActivity and expects a result (using startActivityForResult()).
  2. SecondActivity lets the user enter data, and when the “Go Back” button is clicked, it sends the data back to MainActivity using setResult() and finish().
  3. MainActivity receives the data in onActivityResult() and displays it on the screen.

Step 5: Best Practices and Summary

In this final section, we’ll cover some best practices for using startActivityForResult() and onActivityResult() effectively, and then we’ll summarize the entire process.

5.1: Best Practices for Using startActivityForResult() and onActivityResult()

While working with intents and results in Android, it’s important to follow certain best practices to make your app more efficient, maintainable, and user-friendly:

Use Clear and Meaningful Request Codes:

  • It’s important to use request codes that are meaningful to avoid confusion. Instead of using 1 for all requests, you could define constants with descriptive names, like REQUEST_CODE_GET_USER_INPUT. This will make your code more readable and easier to debug.
Example:

    private static final int REQUEST_CODE_GET_USER_INPUT = 1001;
    

    Handle Edge Cases in onActivityResult():

    • Always check for null values in the data object in onActivityResult(). Sometimes, the result may not contain the expected data, and handling such cases gracefully can prevent crashes.

    Example:

    if (data != null) {
        String myData = data.getStringExtra("data");
        if (myData != null) {
            tv.setText(myData);
        } else {
            tv.setText("No data returned.");
        }
    }
    

    Use ActivityResultContracts in Newer Android Versions:

    • Starting from Android API level 23 (Android 6.0, Marshmallow), startActivityForResult() is deprecated in favor of ActivityResultContracts. This new API provides a more modern and flexible approach to handling results and improves readability.

    Here’s a basic example using ActivityResultContracts:

    ActivityResultLauncher<Intent> resultLauncher =
        registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result.getResultCode() == RESULT_OK) {
                String data = result.getData().getStringExtra("data");
                tv.setText(data);
            }
        });
    
    go.setOnClickListener(v -> {
        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        resultLauncher.launch(intent);
    });
    

    Using this approach eliminates the need for onActivityResult() and makes the code easier to understand and manage.

    Respect User Privacy:

    • When collecting data from users, always ensure that you’re following best practices for privacy and data protection. For example, if you’re collecting sensitive information, make sure that it’s stored securely and inform users of what the data will be used for.

    Avoid Using onActivityResult() for Long-Term Communication:

    • For more complex data passing or long-term interactions between activities, consider using a more robust solution, like ViewModels with LiveData or shared preferences, rather than relying solely on onActivityResult(). This approach can help decouple the logic between activities.

    Always Set a Result:

    • Ensure that every time you call setResult(), you are properly setting a result (e.g., RESULT_OK or RESULT_CANCELED) in SecondActivity. Otherwise, MainActivity may not know if the activity ended successfully or if there was an issue.

    Example:

    setResult(RESULT_OK, intent); // Ensure you send back a result code
    
    1. Handle Different Activity States:
      • Be aware that onActivityResult() may be called when your activity is paused or stopped (e.g., if the user navigates away from the activity temporarily). Make sure to handle these cases properly by updating the UI in a way that doesn’t rely on the activity being fully resumed.

    5.2: Summary of the Process

    In this tutorial, we demonstrated how to pass data between two activities using intents, handle the data in MainActivity, and display it on the UI. Here’s a recap of the main steps involved:

    1. Sending Data from MainActivity to SecondActivity:
      • We used an Intent to open SecondActivity and started it for a result with startActivityForResult().
    2. Collecting Data in SecondActivity:
      • SecondActivity allowed the user to input data and then sent the data back to MainActivity using setResult() and finish().
    3. Receiving Data in MainActivity:
      • We overrode onActivityResult() in MainActivity to capture the result and display the returned data in a TextView.
    4. Best Practices:
      • We covered best practices, such as handling null data, using meaningful request codes, and exploring the newer ActivityResultContracts for improved result handling.

    By following these steps, you can efficiently pass data between activities, making your app interactive and dynamic. The approach shown here is fundamental to creating multi-activity applications where activities communicate with each other.

    Conclusion

    In this tutorial, we’ve explored how to send and receive data between activities using intents in Android. This is a crucial concept for Android developers, especially when building apps with multiple screens or steps in the user flow. By using startActivityForResult() and onActivityResult(), you can easily share data and create a smooth user experience.

    As your apps become more complex, consider using ActivityResultContracts to handle results in a more modern and cleaner way. Always follow the best practices to maintain code readability, security, and user privacy.

    Category

    Leave a Comment