The Android platform prescribes a number of patterns for putting together an application that plays well with the platform and feels familiar to users.

One of those patterns is the hierarchical use of Activities to segregate the application, and to provide re-usable chunks of application that can service certain requirements.

The higher design goal is to create an eco-system of separable Activities that fulfil Intents that can be re-used by other applications - for example: if my application needs an image, it can request one by invoking an Intent to use an image, and all Activities that can fulfil that Intent will be offered as a choice to the user.

Lets see what that looks like with a code example.

Invoking an Activity with an Intent

First of all, lets look at how to invoke an activity with an Intent. Lets say we want to explicitly open the Gallery app to select an image to use in our application. Its very simple:

private static final int PICK_IMAGE_REQUEST = 1;

public void selectImageFromGallery() {
    Intent _intent = new Intent();
    _intent.setType("image/*");
    _intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(
        Intent.createChooser(_intent, "Select Picture"), 
        PICK_IMAGE_REQUEST
    );
}

This will open the gallery app and allow the user to select an image. Notice that in the call to startActivityForResult we provided an int value in the form of PICK_IMAGE_REQUEST - this tells the system what return-code to use when the invoked Activity completes, so that we can respond correctly.

Lets see how we do that ..

@Override
protected void onActivityResult(
    int aRequestCode, int aResultCode, Intent aData
) {
    switch (aRequestCode) {
        case PICK_IMAGE_REQUEST:
            handleUserPickedImage(aData);
            break;
        case SOME_OTHER_REQUEST:
            handleSomethingElse(aData);
            break;
    }
    super.onActivityResult(aRequestCode, aResultCode, aData);
}

Here we're overriding a method of Activity to handle results being passed back from invoked activities.

The value of aRequestCode is the value passed to the startActivityForResult method (so for us its PICK_IMAGE_REQUEST), and is how we distinguish which activity is returning a result.

aResultCode will contain the value set by the invoked Activity's setResult(int), while aData Intent contains any data returned by the Activity. In our example the Intent contains the Uri of the selected image, which we can access like this:

private void handleUserPickedImage(Intent aData) {
    if ((aData != null) && (aData.getData() != null)) {
        Uri _imageUri = aData.getData();
        // Do something neat with the image...
    } else {
        // We didn't receive an image...
    }
}

Returning values from an Activity

Great, we can invoke existing Activity's and collect results. What does it look like from the other side? - How does the Activity return its results to us?

Uri _resultUri = .. // Some uri we want to return  
Intent _result = new Intent();              
_result.setData(_resultUri);
setResult(Activity.RESULT_OK, _result);
finish();

Its a simple as that:

  1. Create an Intent (the result object)
  2. Set the result data (you don't have to return a Uri - you can use the putExtra methods to set any values you want)
  3. Call setResult on your Activity, giving it the result Intent
  4. Call finish on your Activity
blog comments powered by Disqus