1page.title=Sending the User to Another App 2parent.title=Interacting with Other Apps 3parent.link=index.html 4 5trainingnavtop=true 6next.title=Getting a Result from an Activity 7next.link=result.html 8 9@jd:body 10 11 12<div id="tb-wrapper"> 13 <div id="tb"> 14 15<h2>This lesson teaches you to</h2> 16<ol> 17 <li><a href="#Build">Build an Implicit Intent</a></li> 18 <li><a href="#Verify">Verify There is an App to Receive the Intent</a></li> 19 <li><a href="#StartActivity">Start an Activity with the Intent</a></li> 20 <li><a href="#AppChooser">Show an App Chooser</a></li> 21</ol> 22 23<h2>You should also read</h2> 24<ul> 25 <li><a href="{@docRoot}training/sharing/index.html">Sharing Simple Data</a></li> 26</ul> 27 28 </div> 29</div> 30 31<p>One of Android's most important features is an app's ability to send the user to another app 32based on an "action" it would like to perform. For example, if 33your app has the address of a business that you'd like to show on a map, you don't have to build 34an activity in your app that shows a map. Instead, you can create a request to view the address 35using an {@link android.content.Intent}. The Android system then starts an app that's able to show 36the address on a map.</p> 37 38<p>As explained in the first class, <a href="{@docRoot}training/basics/firstapp/index.html">Building 39Your First App</a>, you must use intents to navigate between activities in your own app. You 40generally do so with an <em>explicit intent</em>, which defines the exact class name of the 41component you want to start. However, when you want to have a separate app perform an action, such 42as "view a map," you must use an <em>implicit intent</em>.</p> 43 44<p>This lesson shows you how to create an implicit intent for a particular action, and how to use it 45to start an activity that performs the action in another app.</p> 46 47 48 49<h2 id="Build">Build an Implicit Intent</h2> 50 51<p>Implicit intents do not declare the class name of the component to start, but instead declare an 52action to perform. The action specifies the thing you want to do, such as <em>view</em>, 53<em>edit</em>, <em>send</em>, or <em>get</em> something. Intents often also include data associated 54with the action, such as the address you want to view, or the email message you want to send. 55Depending on the intent you want to create, the data might be a {@link android.net.Uri}, 56one of several other data types, or the intent might not need data at all.</p> 57 58<p>If your data is a {@link android.net.Uri}, there's a simple {@link 59android.content.Intent#Intent(String,Uri) Intent()} constructor you can use define the action and 60data.</p> 61 62<p>For example, here's how to create an intent to initiate a phone call using the {@link 63android.net.Uri} data to specify the telephone number:</p> 64 65<pre> 66Uri number = Uri.parse("tel:5551234"); 67Intent callIntent = new Intent(Intent.ACTION_DIAL, number); 68</pre> 69 70<p>When your app invokes this intent by calling {@link android.app.Activity#startActivity 71startActivity()}, the Phone app initiates a call to the given phone number.</p> 72 73<p>Here are a couple other intents and their action and {@link android.net.Uri} data 74pairs:</p> 75 76<ul> 77 <li>View a map: 78<pre> 79// Map point based on address 80Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); 81// Or map point based on latitude/longitude 82// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level 83Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); 84</pre> 85 </li> 86 <li>View a web page: 87<pre> 88Uri webpage = Uri.parse("http://www.android.com"); 89Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage); 90</pre> 91 </li> 92</ul> 93 94<p>Other kinds of implicit intents require "extra" data that provide different data types, 95such as a string. You can add one or more pieces of extra data using the various {@link 96android.content.Intent#putExtra(String,String) putExtra()} methods.</p> 97 98<p>By default, the system determines the appropriate MIME type required by an intent based on the 99{@link android.net.Uri} data that's included. If you don't include a {@link android.net.Uri} in the 100intent, you should usually use {@link android.content.Intent#setType setType()} to specify the type 101of data associated with the intent. Setting the MIME type further specifies which kinds of 102activities should receive the intent.</p> 103 104<p>Here are some more intents that add extra data to specify the desired action:</p> 105 106<ul> 107 <li>Send an email with an attachment: 108<pre> 109Intent emailIntent = new Intent(Intent.ACTION_SEND); 110// The intent does not have a URI, so declare the "text/plain" MIME type 111emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); 112emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients 113emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject"); 114emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text"); 115emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment")); 116// You can also attach multiple items by passing an ArrayList of Uris 117</pre> 118 </li> 119 <li>Create a calendar event: 120<pre> 121Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI); 122Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30); 123Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30); 124calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()); 125calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()); 126calendarIntent.putExtra(Events.TITLE, "Ninja class"); 127calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo"); 128</pre> 129<p class="note"><strong>Note:</strong> This intent for a calendar event is supported only with API 130level 14 and higher.</p> 131 </li> 132</ul> 133 134<p class="note"><strong>Note:</strong> It's important that you define your {@link 135android.content.Intent} to be as specific as possible. For example, if you want to display an image 136using the {@link android.content.Intent#ACTION_VIEW} intent, you should specify a MIME type of 137{@code image/*}. This prevents apps that can "view" other types of data (like a map app) from being 138triggered by the intent.</p> 139 140 141 142<h2 id="Verify">Verify There is an App to Receive the Intent</h2> 143 144<p>Although the Android platform guarantees that certain intents will resolve to one of the 145built-in apps (such as the Phone, Email, or Calendar app), you should always include a 146verification step before invoking an intent.</p> 147 148<p class="caution"><strong>Caution:</strong> If you invoke an intent and there is no app 149available on the device that can handle the intent, your app will crash.</p> 150 151<p>To verify there is an activity available that can respond to the intent, call {@link 152android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} to get a list 153of activities capable of handling your {@link android.content.Intent}. If the returned {@link 154java.util.List} is not empty, you can safely use the intent. For example:</p> 155 156<pre> 157PackageManager packageManager = {@link android.content.Context#getPackageManager()}; 158List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); 159boolean isIntentSafe = activities.size() > 0; 160</pre> 161 162<p>If <code>isIntentSafe</code> is <code>true</code>, then at least one app will respond to 163the intent. If it is <code>false</code>, then there aren't any apps to handle the intent.</p> 164 165<p class="note"><strong>Note:</strong> You should perform this check when your activity first 166starts in case you need to disable the feature that uses the intent before the user attempts to use 167it. If you know of a specific app that can handle the intent, you can also provide a link for the 168user to download the app (see how to <a 169href="{@docRoot}distribute/tools/promote/linking.html">link to your product on Google 170Play</a>).</p> 171 172 173<h2 id="StartActivity">Start an Activity with the Intent</h2> 174 175<div class="figure" style="width:200px;margin-top:-10px"> 176 <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" /> 177 <p class="img-caption"><strong>Figure 1.</strong> Example of the selection dialog that appears 178when more than one app can handle an intent.</p> 179</div> 180 181<p>Once you have created your {@link android.content.Intent} and set the extra info, call {@link 182android.app.Activity#startActivity startActivity()} to send it to the system. If the system 183identifies more than one activity that can handle the intent, it displays a dialog for the user to 184select which app to use, as shown in figure 1. If there is only one activity that handles the 185intent, the system immediately starts it.</p> 186 187<pre> 188startActivity(intent); 189</pre> 190 191<p>Here's a complete example that shows how to create an intent to view a map, verify that an 192app exists to handle the intent, then start it:</p> 193 194<pre> 195// Build the intent 196Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); 197Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); 198 199// Verify it resolves 200PackageManager packageManager = {@link android.content.Context#getPackageManager()}; 201List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0); 202boolean isIntentSafe = activities.size() > 0; 203 204// Start an activity if it's safe 205if (isIntentSafe) { 206 startActivity(mapIntent); 207} 208</pre> 209 210 211 212<h2 id="AppChooser">Show an App Chooser</h2> 213 214<div class="figure" style="width:200px;margin-top:-10px"> 215 <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" /> 216 <p class="img-caption"><strong>Figure 2.</strong> A chooser dialog.</p> 217</div> 218 219<p>Notice that when you start an activity by passing your {@link android.content.Intent} to {@link 220android.app.Activity#startActivity startActivity()} and there is more than one app that responds to 221the intent, the user can select which app to use by default (by selecting a checkbox at the bottom 222of the dialog; see figure 1). This is nice when performing an action for which the user 223generally wants to use the same app every time, such as when opening a web page (users 224likely use just one web browser) or taking a photo (users likely prefer one camera).</p> 225 226<p>However, if the action to be performed could be handled by multiple apps and the user might 227prefer a different app each time—such as a "share" action, for which users might have several 228apps through which they might share an item—you should explicitly show a chooser dialog 229as shown in figure 2. The chooser dialog 230forces the user to select which app to use for the action every time (the user cannot select a 231default app for the action).</p> 232 233<p>To show the chooser, create an {@link android.content.Intent} using {@link 234android.content.Intent#createChooser createChooser()} and pass it to {@link 235android.app.Activity#startActivity startActivity()}. For example:</p> 236 237<pre> 238Intent intent = new Intent(Intent.ACTION_SEND); 239... 240 241// Always use string resources for UI text. 242// This says something like "Share this photo with" 243String title = getResources().getString(R.string.chooser_title); 244// Create intent to show chooser 245Intent chooser = Intent.createChooser(intent, title); 246 247// Verify the intent will resolve to at least one activity 248if (intent.resolveActivity(getPackageManager()) != null) { 249 startActivity(chooser); 250} 251</pre> 252 253<p>This displays a dialog with a list of apps that respond to the intent passed to the {@link 254android.content.Intent#createChooser createChooser()} method and uses the supplied text as the 255dialog title.</p> 256 257 258 259