From ba8f435947c1387a01ee97ea642b3ce7ca6080d6 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Thu, 29 Mar 2012 23:03:13 -0700 Subject: [PATCH] docs: add 101 class about intents, Interacting with Other Apps Change-Id: I3242adafd99c34fcec4e4cece20e8c89d338c8a1 --- .../images/training/basics/intents-choice.png | Bin 0 -> 24450 bytes docs/html/training/basics/intents/filters.jd | 244 ++++++++++++++++++ docs/html/training/basics/intents/index.jd | 64 +++++ docs/html/training/basics/intents/result.jd | 182 +++++++++++++ docs/html/training/basics/intents/sending.jd | 211 +++++++++++++++ 5 files changed, 701 insertions(+) create mode 100644 docs/html/images/training/basics/intents-choice.png create mode 100644 docs/html/training/basics/intents/filters.jd create mode 100644 docs/html/training/basics/intents/index.jd create mode 100644 docs/html/training/basics/intents/result.jd create mode 100644 docs/html/training/basics/intents/sending.jd diff --git a/docs/html/images/training/basics/intents-choice.png b/docs/html/images/training/basics/intents-choice.png new file mode 100644 index 0000000000000000000000000000000000000000..f99596dc5fbbd2f7ca6459a3afaf3a54400af44a GIT binary patch literal 24450 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 f)O+!4|H991v2ys6RUHJ}kB +
+ +

This lesson teaches you to

+
    +
  1. Add an Intent Filter
  2. +
  3. Handle the Intent in Your Activity
  4. +
  5. Return a Result
  6. +
+ +

You should also read

+ +
+ + +

The previous two lessons focused on one side of the story: starting another app's activity from +your app. But if your app can perform an action that might be useful to another app, +your app should be prepared to respond to action requests from other apps. For instance, if you +build a social app that can share messages or photos with the user's friends, it's in your best +interest to support the {@link android.content.Intent#ACTION_SEND} intent so users can initiate a +"share" action from another app and launch your app to perform the action.

+ +

To allow other apps to start your activity, you need to add an {@code <intent-filter>} +element in your manifest file for the corresponding {@code <activity>} element.

+ +

When your app is installed on a device, the system identifies your intent +filters and adds the information to an internal catalog of intents supported by all installed apps. +When an app calls {@link android.app.Activity#startActivity +startActivity()} or {@link android.app.Activity#startActivityForResult startActivityForResult()}, +with an implicit intent, the system finds which activity (or activities) can respond to the +intent.

+ + + +

Add an Intent Filter

+ +

In order to properly define which intents your activity can handle, each intent filter you add +should be as specific as possible in terms of the type of action and data the activity +accepts.

+ +

The system may send a given {@link android.content.Intent} to an activity if that activity has +an intent filter fulfills the following criteria of the {@link android.content.Intent} object:

+ +
+
Action
+
A string naming the action to perform. Usually one of the platform-defined values such +as {@link android.content.Intent#ACTION_SEND} or {@link android.content.Intent#ACTION_VIEW}. +

Specify this in your intent filter with the {@code <action>} element. +The value you specify in this element must be the full string name for the action, instead of the +API constant (see the examples below).

+ +
Data
+
A description of the data associated with the intent. +

Specify this in your intent filter with the {@code <data>} element. Using one +or more attributes in this element, you can specify just the MIME type, just a URI prefix, +just a URI scheme, or a combination of these and others that indicate the data type +accepted.

+

Note: If you don't need to declare specifics about the data +{@link android.net.Uri} (such as when your activity handles to other kind of "extra" data, instead +of a URI), you should specify only the {@code android:mimeType} attribute to declare the type of +data your activity handles, such as {@code text/plain} or {@code image/jpeg}.

+
+
Category
+
Provides an additional way to characterize the activity handling the intent, usually related +to the user gesture or location from which it's started. There are several different categories +supported by the system, but most are rarely used. However, all implicit intents are defined with +{@link android.content.Intent#CATEGORY_DEFAULT} by default. +

Specify this in your intent filter with the {@code <category>} +element.

+
+ +

In your intent filter, you can declare which criteria your activity accepts +by declaring each of them with corresponding XML elements nested in the {@code <intent-filter>} +element.

+ +

For example, here's an activity with an intent filter that handles the {@link +android.content.Intent#ACTION_SEND} intent when the data type is either text or an image:

+ +
+<activity android:name="ShareActivity">
+    <intent-filter>
+        <action android:name="android.intent.action.SEND"/>
+        <category android:name="android.intent.category.DEFAULT"/>
+        <data android:mimeType="text/plain"/>
+        <data android:mimeType="image/*"/>
+    </intent-filter>
+</activity>
+
+ +

Each incoming intent specifies only one action and one data type, but it's OK to declare multiple +instances of the {@code +<action>}, {@code +<category>}, and {@code +<data>} elements in each +{@code +<intent-filter>}.

+ +

If any two pairs of action and data are mutually exclusive in +their behaviors, you should create separate intent filters to specify which actions are acceptable +when paired with which data types.

+ +

For example, suppose your activity handles both text and images for both the {@link +android.content.Intent#ACTION_SEND} and {@link +android.content.Intent#ACTION_SENDTO} intents. In this case, you must define two separate +intent filters for the two actions because a {@link +android.content.Intent#ACTION_SENDTO} intent must use the data {@link android.net.Uri} to specify +the recipient's address using the {@code send} or {@code sendto} URI scheme. For example:

+ +
+<activity android:name="ShareActivity">
+    <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
+    <intent-filter>
+        <action android:name="android.intent.action.SENDTO"/>
+        <category android:name="android.intent.category.DEFAULT"/>
+        <data android:scheme="sms" />
+        <data android:scheme="smsto" />
+    </intent-filter>
+    <!-- filter for sending text or images; accepts SEND action and text or image data -->
+    <intent-filter>
+        <action android:name="android.intent.action.SEND"/>
+        <category android:name="android.intent.category.DEFAULT"/>
+        <data android:mimeType="image/*"/>
+        <data android:mimeType="text/plain"/>
+    </intent-filter>
+</activity>
+
+ +

Note: In order to receive implicit intents, you must include the +{@link android.content.Intent#CATEGORY_DEFAULT} category in the intent filter. The methods {@link +android.app.Activity#startActivity startActivity()} and {@link +android.app.Activity#startActivityForResult startActivityForResult()} treat all intents as if they +contained the {@link android.content.Intent#CATEGORY_DEFAULT} category. If you do not declare it, no +implicit intents will resolve to your activity.

+ +

For more information about sending and receiving {@link android.content.Intent#ACTION_SEND} +intents that perform social sharing behaviors, see the lesson about Receiving Content from Other Apps.

+ + +

Handle the Intent in Your Activity

+ +

In order to decide what action to take in your activity, you can read the {@link +android.content.Intent} that was used to start it.

+ +

As your activity starts, call {@link android.app.Activity#getIntent()} to retrieve the +{@link android.content.Intent} that started the activity. You can do so at any time during the +lifecycle of the activity, but you should generally do so during early callbacks such as +{@link android.app.Activity#onCreate onCreate()} or {@link android.app.Activity#onStart()}.

+ +

For example:

+ +
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+
+    setContentView(R.layout.main);
+
+    // Get the intent that started this activity
+    Intent intent = getIntent();
+    Uri data = intent.getData();
+
+    // Figure out what to do based on the intent type
+    if (intent.getType().indexOf("image/") != -1) {
+        // Handle intents with image data ...
+    } else if (intent.getType().equals("text/plain")) {
+        // Handle intents with text ...
+    }
+}
+
+ + +

Return a Result

+ +

If you want to return a result to the activity that invoked yours, simply call {@link +android.app.Activity#setResult(int,Intent) setResult()} to specify the result code and result {@link +android.content.Intent}. When your operation is done and the user should return to the original +activity, call {@link android.app.Activity#finish()} to close (and destroy) your activity. For +example:

+ +
+// Create intent to deliver some kind of result data
+Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
+setResult(Activity.RESULT_OK, result);
+finish();
+
+ +

You must always specify a result code with the result. Generally, it's either {@link +android.app.Activity#RESULT_OK} or {@link android.app.Activity#RESULT_CANCELED}. You can then +provide additional data with an {@link android.content.Intent}, as necessary.

+ +

Note: The result is set to {@link +android.app.Activity#RESULT_CANCELED} by default. So, if the user presses the Back +button before completing the action and before you set the result, the original activity receives +the "canceled" result.

+ +

If you simply need to return an integer that indicates one of several result options, you can set +the result code to any value higher than 0. If you use the result code to deliver an integer and you +have no need to include the {@link android.content.Intent}, you can call {@link +android.app.Activity#setResult(int) setResult()} and pass only a result code. For example:

+ +
+setResult(RESULT_COLOR_RED);
+finish();
+
+ +

In this case, there might be only a handful of possible results, so the result code is a locally +defined integer (greater than 0). This works well when you're returning a result to an activity +in your own app, because the activity that receives the result can reference the public +constant to determine the value of the result code.

+ +

Note: There's no need to check whether your activity was started +with {@link +android.app.Activity#startActivity startActivity()} or {@link +android.app.Activity#startActivityForResult startActivityForResult()}. Simply call {@link +android.app.Activity#setResult(int,Intent) setResult()} if the intent that started your activity +might expect a result. If the originating activity had called {@link +android.app.Activity#startActivityForResult startActivityForResult()}, then the system delivers it +the result you supply to {@link android.app.Activity#setResult(int,Intent) setResult()}; otherwise, +the result is ignored.

+ + + + + + diff --git a/docs/html/training/basics/intents/index.jd b/docs/html/training/basics/intents/index.jd new file mode 100644 index 0000000000000..c661d98b9b35d --- /dev/null +++ b/docs/html/training/basics/intents/index.jd @@ -0,0 +1,64 @@ +page.title=Interacting with Other Apps + +trainingnavtop=true +startpage=true +next.title=Sending the User to Another App +next.link=sending.html + +@jd:body + +
+
+ +

Dependencies and prerequisites

+ + + +

You should also read

+ + +
+
+ +

An Android app typically has several activities. Each activity displays a +user interface that allows the user to perform a specific task (such as view a map or take a photo). +To take the user from one activity to another, your app must use an {@link +android.content.Intent} to define your app's "intent" to do something. When you pass an +{@link android.content.Intent} to the system with a method such as {@link +android.app.Activity#startActivity startActivity()}, the system uses the {@link +android.content.Intent} to identify and start the appropriate app component. Using intents even +allows your app to start an activity that is contained in a separate app.

+ +

An {@link android.content.Intent} can be explicit in order to start a specific component +(a specific {@link android.app.Activity} instance) or implicit in order to start any +component that can handle the intended action (such as "capture a photo").

+ +

This class shows you how to use an {@link android.content.Intent} to perform some basic +interactions with other apps, such as start another app, receive a result from that app, and +make your app able to respond to intents from other apps.

+ +

Lessons

+ +
+
Sending the User to Another App
+
Shows how you can create implicit intents to launch other apps that can perform an +action.
+
Getting a Result from an Activity
+
Shows how to start another activity and receive a result from the activity.
+
Allowing Other Apps to Start Your Activity
+
Shows how to make activities in your app open for use by other apps by defining +intent filters that declare the implicit intents your app accepts.
+
+ diff --git a/docs/html/training/basics/intents/result.jd b/docs/html/training/basics/intents/result.jd new file mode 100644 index 0000000000000..008691314e5a7 --- /dev/null +++ b/docs/html/training/basics/intents/result.jd @@ -0,0 +1,182 @@ +page.title=Getting a Result from an Activity +parent.title=Interacting with Other Apps +parent.link=index.html + +trainingnavtop=true +previous.title=Sending the User to Another App +previous.link=sending.html +next.title=Allowing Other Apps to Start Your Activity +next.link=filters.html + +@jd:body + +
+
+ +

This lesson teaches you to

+
    +
  1. Start the Activity
  2. +
  3. Receive the Result
  4. +
+ +

You should also read

+ + +
+
+ +

Starting another activity doesn't have to be one-way. You can also start another activity and +receive a result back. To receive a result, call {@link android.app.Activity#startActivityForResult +startActivityForResult()} (instead of {@link android.app.Activity#startActivity +startActivity()}).

+ +

For example, your app can start a camera app and receive the captured photo as a result. Or, you +might start the People app in order for the user to select a +contact and you'll receive the contact details as a result.

+ +

Of course, the activity that responds must be designed to return a result. When it does, it +sends the result as another {@link android.content.Intent} object. Your activity receives it in +the {@link android.app.Activity#onActivityResult onActivityResult()} callback.

+ +

Note: You can use explicit or implicit intents when you call +{@link android.app.Activity#startActivityForResult startActivityForResult()}. When starting one of +your own activities to receive a result, you should use an explicit intent to ensure that you +receive the expected result.

+ + +

Start the Activity

+ +

There's nothing special about the {@link android.content.Intent} object you use when starting +an activity for a result, but you do need to pass an additional integer argument to the {@link +android.app.Activity#startActivityForResult startActivityForResult()} method.

+ +

The integer argument is a "request code" that identifies your request. When you receive the +result {@link android.content.Intent}, the callback provides the same request code so that your +app can properly identify the result and determine how to handle it.

+ +

For example, here's how to start an activity that allows the user to pick a contact:

+ +
+static final int PICK_CONTACT_REQUEST = 1;  // The request code
+...
+private void pickContact() {
+    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, new Uri("content://contacts"));
+    pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
+    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
+}
+
+ + +

Receive the Result

+ +

When the user is done with the subsequent activity and returns, the system calls your activity's +{@link android.app.Activity#onActivityResult onActivityResult()} method. This method includes three +arguments:

+ +
    +
  • The request code you passed to {@link +android.app.Activity#startActivityForResult startActivityForResult()}.
  • +
  • A result code specified by the second activity. This is either {@link +android.app.Activity#RESULT_OK} if the operation was successful or {@link +android.app.Activity#RESULT_CANCELED} if the user backed out or the operation failed for some +reason.
  • +
  • An {@link android.content.Intent} that carries the result data.
  • +
+ +

For example, here's how you can handle the result for the "pick a contact" intent:

+ +
+@Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    // Check which request we're responding to
+    if (requestCode == PICK_CONTACT_REQUEST) {
+        // Make sure the request was successful
+        if (resultCode == RESULT_OK) {
+            // The user picked a contact.
+            // The Intent's data Uri identifies which contact was selected.
+
+            // Do something with the contact here (bigger example below)
+        }
+    }
+}
+
+ +

In this example, the result {@link android.content.Intent} returned by +Android's Contacts or People app provides a content {@link android.net.Uri} that identifies the +contact the user selected.

+ +

In order to successfully handle the result, you must understand what the format of the result +{@link android.content.Intent} will be. Doing so is easy when the activity returning a result is +one of your own activities. Apps included with the Android platform offer their own APIs that +you can count on for specific result data. For instance, the People app (Contacts app on some older +versions) always returns a result with the content URI that identifies the selected contact, and the +Camera app returns a {@link android.graphics.Bitmap} in the {@code "data"} extra (see the class +about Capturing Photos).

+ + +

Bonus: Read the contact data

+ +

The code above showing how to get a result from the People app doesn't go into +details about how to actually read the data from the result, because it requires more advanced +discussion about content +providers. However, if you're curious, here's some more code that shows how to query the +result data to get the phone number from the selected contact:

+ +
+@Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    // Check which request it is that we're responding to
+    if (requestCode == PICK_CONTACT_REQUEST) {
+        // Make sure the request was successful
+        if (resultCode == RESULT_OK) {
+            // Get the URI that points to the selected contact
+            Uri contactUri = data.getData();
+            // We only need the NUMBER column, because there will be only one row in the result
+            String[] projection = {Phone.NUMBER};
+
+            // Perform the query on the contact to get the NUMBER column
+            // We don't need a selection or sort order (there's only one result for the given URI)
+            // CAUTION: The query() method should be called from a separate thread to avoid blocking
+            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
+            // Consider using {@link android.content.CursorLoader} to perform the query.
+            Cursor cursor = getContentResolver()
+                    .query(contactUri, projection, null, null, null);
+            cursor.moveToFirst();
+
+            // Retrieve the phone number from the NUMBER column
+            int column = cursor.getColumnIndex(Phone.NUMBER);
+            String number = cursor.getString(column);
+
+            // Do something with the phone number...
+        }
+    }
+}
+
+ +

Note: Before Android 2.3 (API level 9), performing a query +on the {@link android.provider.ContactsContract.Contacts Contacts Provider} (like the one shown +above) requires that your app declare the {@link +android.Manifest.permission#READ_CONTACTS} permission (see Security and Permissions). However, +beginning with Android 2.3, the Contacts/People app grants your app a temporary +permission to read from the Contacts Provider when it returns you a result. The temporary permission +applies only to the specific contact requested, so you cannot query a contact other than the one +specified by the intent's {@link android.net.Uri}, unless you do declare the {@link +android.Manifest.permission#READ_CONTACTS} permission.

+ + + + + + + + + + + + + + + diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd new file mode 100644 index 0000000000000..a71c8f94340a9 --- /dev/null +++ b/docs/html/training/basics/intents/sending.jd @@ -0,0 +1,211 @@ +page.title=Sending the User to Another App +parent.title=Interacting with Other Apps +parent.link=index.html + +trainingnavtop=true +next.title=Getting a Result from an Activity +next.link=result.html + +@jd:body + + +
+
+ +

This lesson teaches you to

+
    +
  1. Build an Implicit Intent
  2. +
  3. Verify There is an App to Receive the Intent
  4. +
  5. Start an Activity with the Intent
  6. +
+ +

You should also read

+ + +
+
+ +

One of Android's most important features is an app's ability to send the user to another app +based on an "action" it would like to perform. For example, if +your app has the address of a business that you'd like to show on a map, you don't have to build +an activity in your app that shows a map. Instead, you can send a out a request to view the address +using an {@link android.content.Intent}. The Android system then starts an app that's able to view +the address on a map.

+ +

As shown in the first class, Building +Your First App, you must use intents to navigate between activities in your own app. You +generally do so with an explicit intent, which defines the exact class name of the +component you want to start. However, when you want to have a separate app perform an action, such +as "view a map," you must use an implicit intent.

+ +

This lesson shows you how to create an implicit intent for a particular action, and how to use it +to start an activity that performs the action in another app.

+ + + +

Build an Implicit Intent

+ +

Implicit intents do not declare the class name of the component to start, but instead declare an +action to perform. The action specifies the thing you want to do, such as view, +edit, send, or get something. Intents often also include data associated +with the action, such as the address you want to view, or the email message you want to send. +Depending on the intent you want to create, the data might be a {@link android.net.Uri}, +one of several other data types, or the intent might not need data at all.

+ +

If your data is a {@link android.net.Uri}, there's a simple {@link +android.content.Intent#Intent(String,Uri) Intent()} constructor you can use define the action and +data.

+ +

For example, here's how to create an intent to initiate a phone call using the {@link +android.net.Uri} data to specify the telephone number:

+ +
+Uri number = Uri.parse("tel:5551234");
+Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
+
+ +

When your app invokes this intent by calling {@link android.app.Activity#startActivity +startActivity()}, the Phone app initiates a call to the given phone number.

+ +

Here are a couple other intents and their action and {@link android.net.Uri} data +pairs:

+ +
    +
  • View a map: +
    +// Map point based on address
    +Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
    +// Or map point based on latitude/longitude
    +// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
    +Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
    +
    +
  • +
  • View a web page: +
    +Uri webpage = Uri.parse("http://www.android.com");
    +Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
    +
    +
  • +
+ +

Other kinds of implicit intents require "extra" data that provide different data types, +such as a string. You can add one or more pieces of extra data using the various {@link +android.content.Intent#putExtra(String,String) putExtra()} methods.

+ +

By default, the system determines the appropriate MIME type required by an intent based on the +{@link android.net.Uri} data that's included. If you don't include a {@link android.net.Uri} in the +intent, you should usually use {@link android.content.Intent#setType setType()} to specify the type +of data associated with the intent. Setting the MIME type further specifies which kinds of +activities should receive the intent.

+ +

Here are some more intents that add extra data to specify the desired action:

+ +
    +
  • Send an email with an attachment: +
    +Intent emailIntent = new Intent(Intent.ACTION_SEND);
    +// The intent does not have a URI, so declare the "text/plain" MIME type
    +emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
    +emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
    +emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
    +emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
    +emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment");
    +// You can also attach multiple items by passing an ArrayList of Uris
    +
    +
  • +
  • Create a calendar event: +
    +Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
    +Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
    +Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
    +calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
    +calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
    +calendarIntent.putExtra(Events.TITLE, "Ninja class");
    +calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
    +
    +

    Note: This intent for a calendar event is supported only with API +level 14 and higher.

    +
  • +
+ +

Note: It's important that you define your {@link +android.content.Intent} to be as specific as possible. For example, if you want to display an image +using the {@link android.content.Intent#ACTION_VIEW} intent, you should specify a MIME type of +{@code image/*}. This prevents apps that can "view" other types of data (like a map app) from being +triggered by the intent.

+ + + +

Verify There is an App to Receive the Intent

+ +

Although the Android platform guarantees that certain intents will resolve to one of the +built-in apps (such as the Phone, Email, or Calendar app), you should always include a +verification step before invoking an intent.

+ +

Caution: If you invoke an intent and there is no app +available on the device that can handle the intent, your app will crash.

+ +

To verify there is an activity available that can respond to the intent, call {@link +android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} to get a list +of activities capable of handling your {@link android.content.Intent}. If the returned {@link +java.util.List} is not empty, you can safely use the intent. For example:

+ +
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
+boolean isIntentSafe = activities.size() > 0;
+
+ +

If isIntentSafe is true, then at least one app will respond to +the intent. If it is false, then there aren't any apps to handle the intent.

+ +

Note: You should perform this check when your activity first +starts in case you need to disable the feature that uses the intent before the user attempts to use +it. If you know of a specific app that can handle the intent, you can also provide a link for the +user to download the app (see how to link to an app on Google +Play).

+ + +

Start an Activity with the Intent

+ +
+ +

Figure 1. Example of the selection dialog that appears +when more than one app can handle an intent.

+
+ +

Once you have created your {@link android.content.Intent} and set the extra info, call {@link +android.app.Activity#startActivity startActivity()} to send it to the system. If the system +identifies more than one activity that can handle the intent, it displays a dialog for the user to +select which app to use, as shown in figure 1. If there is only one activity that handles the +intent, the system immediately starts it.

+ +
+startActivity(intent);
+
+ +

Here's a complete example that shows how to create an intent to view a map, verify that an +app exists to handle the intent, then start it:

+ +
+// Build the intent
+Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
+Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
+
+// Verify it resolves
+PackageManager packageManager = {@link android.content.Context#getPackageManager()};
+List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
+boolean isIntentSafe = activities.size() > 0;
+  
+// Start an activity if it's safe
+if (isIntentSafe) {
+    startActivity(mapIntent);
+}
+
+ + + +