Passing Data Between Activities with startActivityForResult

Passing Data Between Activities with startActivityForResult

Android applications often require navigating between different screens (Activities) and passing data between them. startActivityForResult is a powerful mechanism designed for this purpose, allowing one Activity to launch another and receive a result (and associated data) upon its completion. This tutorial will guide you through the entire process, from launching the secondary Activity to handling the returned data.

Understanding the Workflow

The startActivityForResult workflow consists of these steps:

  1. Launching Activity: The initiating Activity uses startActivityForResult() to launch the target Activity. A unique requestCode is passed to identify the launched Activity.
  2. Target Activity Completion: The target Activity performs its task. Upon completion (either successfully or canceled), it sets a resultCode and optionally includes data within an Intent. It then calls setResult() and finish().
  3. Receiving the Result: The initiating Activity’s onActivityResult() method is called when the target Activity finishes. This method receives the requestCode, resultCode, and the Intent containing any returned data.

Launching an Activity with startActivityForResult

To launch a secondary Activity and expect a result, use the startActivityForResult() method.

int REQUEST_CODE = 1; // Define a unique request code
Intent intent = new Intent(this, SecondActivity.class);
startActivityForResult(intent, REQUEST_CODE);

Here:

  • REQUEST_CODE is an integer that uniquely identifies this specific request. It’s crucial for distinguishing between multiple calls to startActivityForResult().
  • intent is the Intent that specifies the target Activity.
  • startActivityForResult() initiates the launch and prepares your Activity to receive a result.

Setting the Result in the Target Activity

Within the target Activity, after completing its task, you need to set the result using setResult() before calling finish().

Intent returnIntent = new Intent();
returnIntent.putExtra("result", "Some data"); // Add data if needed
setResult(RESULT_OK, returnIntent);
finish();

Here:

  • RESULT_OK is a standard constant indicating successful completion. Other constants like RESULT_CANCELED can be used for different outcomes.
  • returnIntent is an Intent that carries any data you want to pass back to the initiating Activity. Use putExtra() to add key-value pairs to the Intent.
  • finish() closes the target Activity and returns control to the initiating Activity.

If the target activity doesn’t need to return any data, you can use:

setResult(RESULT_CANCELED);
finish();

Handling the Result in the Initiating Activity

The initiating Activity must override the onActivityResult() method to handle the result from the target Activity.

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

    if (requestCode == REQUEST_CODE) { // Check the request code
        if (resultCode == RESULT_OK) { // Check the result code
            String result = data.getStringExtra("result"); // Retrieve data
            // Process the result
        } else if (resultCode == RESULT_CANCELED) {
            // Handle cancellation
        }
    }
}

Here:

  • requestCode matches the REQUEST_CODE used when launching the target Activity. This ensures you’re handling the result from the correct Activity.
  • resultCode indicates the outcome of the target Activity. Check for RESULT_OK, RESULT_CANCELED, or any other relevant codes.
  • data is the Intent that carries the returned data. Use getStringExtra(), getIntExtra(), and other getExtra() methods to retrieve the data.

Example Scenario: Camera Feature Check

Let’s illustrate with a scenario where you launch an Activity to check if a device has a camera.

MainActivity (Initiating Activity):

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CAMERA_CHECK = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ... Launch the camera check Activity ...
        Intent intent = new Intent(this, CameraCheckActivity.class);
        startActivityForResult(intent, REQUEST_CAMERA_CHECK);
    }

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

        if (requestCode == REQUEST_CAMERA_CHECK) {
            if (resultCode == RESULT_OK) {
                // Camera is present
                // ... Proceed with camera-related functionality ...
            } else {
                // Camera is not present
                // ... Handle the case where the camera is missing ...
            }
        }
    }
}

CameraCheckActivity (Target Activity):

public class CameraCheckActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Check if the device has a camera
        if (hasCamera()) {
            setResult(RESULT_OK);
        } else {
            setResult(RESULT_CANCELED);
        }

        finish();
    }

    private boolean hasCamera() {
        // Implement your camera check logic here
        return true; // Replace with actual check
    }
}

Modern Alternatives: ActivityResultContracts (Android X)

For newer Android development with AndroidX, consider using ActivityResultContracts and registerForActivityResult() as a more streamlined approach. This removes the need to override onActivityResult() directly. The key benefit is simplifying the code when dealing with results from fragments or from other activities.

ActivityResultLauncher<Intent> launchSomeActivity = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Activity.RESULT_OK) {
            Intent data = result.getData();
            // your operation...
        }
    });

// ... Launch the activity ...
launchSomeActivity.launch(new Intent(this, SomeActivity.class));

Leave a Reply

Your email address will not be published. Required fields are marked *