Android: implicit intents

We’ve seen how to use an explicit intent to start a second Activity from within an existing Activity by giving the name of the second Activity’s class explicitly. It is also possible to start another Activity without naming it. The rationale behind this idea is that one or more activities might exist on a given device that can perform the required action. For example, if we want to view a web page, there could be several different browsers which can do this, and the user might like to select different ones for different pages. We can use an implicit intent to do this.

To use an implicit intent, an Activity that can handle a given type of request must contain an intent-filter that specifies the type(s) of actions that Activity can perform. The intent-filter can be specified in the Java code, but it’s more usual to include it in the AndroidManifest.xml file for the app. There are many predefined action types for an intent-filter, but to keep things local, we’ll show an example in which we define our own action type which is used by two alternative Activities within the same app.

The example app we’ll use is just a copy of the explicit intent app we used before with another Activity called OtherTextActivity added to it. The layout of OtherTextActivity is the same as that of GetTextActivity, so the user can enter some text and press a button to send the text back to StartActivity.

Before we look at the Java code for creating an implicit Intent, we need to define the intent-filters for  the Activities. Up to now, we’ve let Eclipse generate the AndroidManifest.xml file and haven’t altered it. To insert an intent-filter we do need to edit it. This can be done in Eclipse either by using the GUI in the Application tab or by directly writing the XML code. Let’s see how to use the Application editor to add it.

First, find the Activity (we’ll select GetTextActivity first) to which you want to add the intent-filter in the box at the lower left. Click on it and then click on Add… to get the dialog in which you can double-click on Intent filter. Now click on the new Intent filter, then click Add… again. We’ll need to add an action and a category to the intent-filter. Double-click on Action first, and you’ll see a Name field with a drop-down menu appear. If you open this menu, you’ll see a list of all the built-in action names you can give this intent-filter. However, we’re going to create our own custom action, so just enter GET_TEXT_ACTION in the Name box.

[As a side note, we cannot use a string resource to specify an action’s name. This is a bit of a pain, since it means we need to hard-code these strings both in the XML and in the Java code.]

Now add a category to the intent-filter and this time select android.intent.category.DEFAULT from the drop-down list. Have a look at the XML code file to see the code that has been added. You should see something like this:

        <activity
            android:name="com.example.ex03implicitintent.GetTextActivity"
            android:label="@string/title_activity_get_text" >
            <intent-filter>
                <action android:name="GET_TEXT_ACTION"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

Now repeat the process for OtherTextActivity. That completes the definition of the intent-filters. Now over to the Java code. We won’t need to change the code in either GetTextActivity or OtherTextActivity, but we do need to change how the Intent defined in StartActivity is created. We do this by changing the event handler for the getTextButton as follows:

	public void onClickGetText(View view) {
		Intent getTextIntent = new Intent();
		getTextIntent.setAction("GET_TEXT_ACTION");
		List<ResolveInfo> activities = getPackageManager().
				queryIntentActivities(getTextIntent, PackageManager.MATCH_DEFAULT_ONLY);
		boolean isIntentSafe = activities.size() > 0;
		if (isIntentSafe)
		{
			startActivityForResult(getTextIntent, GET_TEXT_ACTIVITY);
		}
	}

We create the Intent with an empty constructor. Then we set the action that the Activity to which this Intent is to be sent must support. Next, we retrieve a List of Activities that support the action requested in getTextIntent. The second argument in queryIntentActivities() says we’re looking only for Activities that have a DEFAULT category.

If there are any Activities that support the requested action, the size of this list will be greater than zero, so we test for that and then call startActivityForResult() only if there are some eligible Activities. If there is only one such Activity, it is started immediately. If there are more than one (as is the case here), Android will display a chooser dialog asking the user to select which Activity should be used.

One cautionary note here: using an implicit intent to start an Activity that returns data is fine, but if you’re doing this with Activities that you didn’t write, beware that often different Activities that support a given action might return different types of data (or none at all). In such a case, it’s better to use an explicit intent and start up an Activity whose behaviour you know, so you can handle the returned data properly.

Advertisements
Post a comment or leave a trackback: Trackback URL.

Trackbacks

  • By Android: explicit intents | Programming tutorials on February 20, 2014 at 1:57 PM

    […] Intent, which is an Intent that creates a specifically named Activity. (There are also implicit Intents). Here we want a GetTextActivity to start in response to the button press, so we name this class […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: