Exercising the Actionpick

So far we have exercised intents or actions that mainly invoke another activity without expecting any results back. Now let's look at an action that is a bit more involved in that it returns a value after being invoked. ACTION_PICK is one such generic action.

The idea of ACTION_PICK is to start an activity that displays a list of items. The activity then should allow a user to pick one item from that list. Once the user picks the item, the activity should return the URI of the picked item to the caller. This allows reuse of the UI's functionality to select items of a certain type.

You should indicate the collection of items to choose from using a MIME type that points to an Android content cursor. The actual MIME type of this URI should look similar to the following:

vnd.android.cursor.dir/vnd.google.note

It is the responsibility of the activity to retrieve the data from the content provider based on the URI. This is also the reason that data should be encapsulated into content providers where possible.

For all actions that return data like this, we cannot use startActivity() because startActivity() does not return any result. startActivity() cannot return a result because it opens the new activity as a modal dialog in a separate thread and leaves the main thread for attending events. In other words, startActivity() is an asynchronous call with no callbacks to indicate what happened in the invoked activity. But if you want to return data, you can use a variation on startActivity() called startActivityForResult(), which comes with a callback.

Let us look at the signature of the startActivityForResult() method from the Activity class:

public void startActivityForResult(Intent intent, int requestCode)

This method launches an activity from which you would like a result. When this activity exits, the source activity's onActivityResult() method will be called with the given requestCode. The signature of this callback method is protected void onActivityResult(int requestCode, int resultCode, Intent data)

The requestCode is what you passed in to the startActivityForResult() method. The resultCode can be RESULT_OK, RESULT_CANCELED, or a custom code. The custom codes should start at RESULT_FIRST_USER. The Intent parameter contains any additional data that the invoked activity wants to return. In the case of ACTION_PICK, the returned data in the intent points to the data URI of a single item (see Listing 3-34).

Listing 3-34. Returning Data After Invoking an Action public static void invokePick(Activity activity) {

Intent pickIntent = new Intent(Intent.ACTION_PICK); int requestCode = 1; pickIntent.setData(Uri.parse(

"content://com.google.provider.NotePad/notes")); activity.startActivityForResult(pickIntent, requestCode);

protected void onActivityResult(int requestCode ,int resultCode ,Intent outputIntent)

super.onActivityResult(requestCode, resultCode, outputIntent); parseResult(this, requestCode, resultCode, outputIntent);

public static void parseResult(Activity activity , int requestCode , int resultCode , Intent outputIntent)

Log.d("Test", "Some one else called this. not us"); return;

if (resultCode != Activity.RESULT_OK) {

Log.d("Result code is not ok:" + resultCode); return;

Log.d("Test", "Result code is ok:" + resultCode);

Uri selectedUri = outputIntent.getData();

Log.d("Test", "The output uri:" + selectedUri.toString());

//Proceed to display the note outputIntent.setAction(Intent.VIEW);

startActivity(outputIntent);

The constants RESULT_OK, RESULT_CANCEL, and RESULT_FIRST_USER are all defined in the Activity class. The numerical values of these constants are

RESULT_OK = -1; RESULT_CANCEL = 0; RESULT_FIRST_USER = 1;

To make this work, the implementer should have code that explicitly addresses the needs of a PICK. Let's look at how this is done in the Google sample Notepad application. When the item is selected in the list of items, the intent that invoked the activity is checked to see whether it's a PICK intent. If it is, the data URI is set in a new intent and returned through setResult():

^Override protected void onListItemClick(ListView l, View v, int position, long id) { Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);

String action = getIntent().getAction(); if (Intent.ACTION_PICK.equals(action) ||

Intent.ACTION_GET_CONTENT.equals(action))

// The caller is waiting for us to return a note selected by // the user. They have clicked on one, so return it now. setResult(RESULT_OK, new Intent().setData(uri)); } else {

// Launch activity to view/edit the currently selected item startActivity(new Intent(Intent.ACTION_EDIT, uri));

0 0

Post a comment