Implicit Intents and Late Runtime Binding

An implicit Intent is a mechanism that lets anonymous application components service action requests. That means you can ask the system to start an Activity to perform an action without knowing which application, or Activity, will be started.

For example, to let users make calls from your application, you could implement a new dialer, or you could use an implicit Intent that requests the action (dialing) be performed on a phone number (represented as a URI).

if (somethingWeird && itDontLookGood) {
 Intent intent = 
 new Intent(Intent.ACTION_DIAL, Uri.parse(“tel:555-2368”));
 startActivity(intent);
}

Android resolves this Intent and starts an Activity that provides the dial action on a telephone number — in this case, typically the Phone Dialer.

When constructing a new implicit Intent, you specify an action to perform and, optionally, supply the URI of the data on which to perform that action. You can send additional data to the target Activity by adding extras to the Intent.

Extras are a mechanism used to attach primitive values to an Intent. You can use the overloaded putExtra method on any Intent to attach a new name / value pair (NVP) that can then be retrieved using the corresponding get[type]Extra method in the started Activity

The extras are stored within the Intent as a Bundle object that can be retrieved using the getExtras method.

When you use an implicit Intent to start an Activity, Android will — at run time — resolve it into the Activity class best suited to performing the required action on the type of data specified. This means you can create projects that use functionality from other applications without knowing exactly which application you’re borrowing functionality from ahead of time.

Determining If an Intent Will Resolve

Incorporating the Activities and Services of a third-party application into your own is incredibly powerful; however, there is no guarantee that any particular application will be installed on a device, or that any application capable of handling your request is available.

Implicitly starting an Activity

if (somethingWeird && itDontLookGood) {
 // Create the impliciy Intent to use to start a new Activity.
 Intent intent = 
 new Intent(Intent.ACTION_DIAL, Uri.parse(“tel:555-2368”));
 // Check if an Activity exists to perform this action.
 PackageManager pm = getPackageManager();
ComponentName cn = intent.resolveActivity(pm);
 if (cn == null) {
 // If there is no Activity available to perform the action
 // Check to see if the Google Play Store is available.
 Uri marketUri =
 Uri.parse(“market://search?q=pname:com.myapp.packagename”);
 Intent marketIntent = new 
 Intent(Intent.ACTION_VIEW).setData(marketUri);
 // If the Google Play Store is available, use it to download an application
 // capable of performing the required action. Otherwise log an
 // error.
 if (marketIntent.resolveActivity(pm) != null)
 startActivity(marketIntent);
 else
 Log.d(TAG, “Market client not available.”);
 } 
 else 
 startActivity(intent);
}

Returning Results from Activities

An Activity started via startActivity is independent of its parent and will not provide any feedback when it closes.

Where feedback is required, you can start an Activity as a sub-Activity that can pass results back to its parent. Sub-Activities are actually just Activities opened in a different way. As such, you must register them in the application manifest in the same way as any other Activity. Any manifest-registered Activity can be opened as a sub-Activity, including those provided by the system or third-party applications.

When a sub-Activity is finished, it triggers the onActivityResult event handler within the calling Activity. Sub-Activities are particularly useful in situations in which one Activity is providing data input for another, such as a user selecting an item from a list.

Launching Sub-Activities

The startActivityForResult method works much like startActivity, but with one important difference. In addition to passing in the explicit or implicit Intent used to determine which Activity to launch, you also pass in a request code. This value will later be used to uniquely identify the subActivity that has returned a result.

Explicitly starting a sub-Activity for a result

private static final int SHOW_SUBACTIVITY = 1;
private void startSubActivity() {
 Intent intent = new Intent(this, MyOtherActivity.class);
 startActivityForResult(intent, SHOW_SUBACTIVITY);
}

Implicitly starting a sub-Activity for a result

private static final int PICK_CONTACT_SUBACTIVITY = 2;
private void startSubActivityImplicitly() {
 Uri uri = Uri.parse(“content://contacts/people”);
 Intent intent = new Intent(Intent.ACTION_PICK, uri);
 startActivityForResult(intent, PICK_CONTACT_SUBACTIVITY);
}

Returning a result from a sub-Activity

Button okButton = (Button) findViewById(R.id.ok_button);
okButton.setOnClickListener(new View.OnClickListener() {
 public void onClick(View view) {
 long selected_horse_id = listView.getSelectedItemId();
 
 Uri selectedHorse = Uri.parse(“content://horses/” + 
 selected_horse_id);
 Intent result = new Intent(Intent.ACTION_PICK, selectedHorse);
 setResult(RESULT_OK, result);
 finish();
 }
});
Button cancelButton = (Button) findViewById(R.id.cancel_button);
cancelButton.setOnClickListener(new View.OnClickListener() {
 public void onClick(View view) {
 setResult(RESULT_CANCELED);
 finish();
 }
});

If the Activity is closed by the user pressing the hardware back key, or finish is called without a prior call to setResult, the result code will be set to RESULT_CANCELED and the result Intent set to null.

Handling Sub-Activity Results

The onActivityResult handler receives a number of parameters:

Request code — The request code that was used to launch the returning sub-Activity.

Result code — The result code set by the sub-Activity to indicate its result. It can be any integer value, but typically will be either Activity.RESULT_OK or Activity.RESULT_CANCELED

Data — An Intent used to package returned data. Depending on the purpose of the sub-Activity, it may include a URI that represents a selected piece of content. The sub-Activity can also return information as an extra within the returned data Intent

Leave a Comment