diff options
Diffstat (limited to 'docs/html/training/basics/intents/sending.jd')
-rw-r--r-- | docs/html/training/basics/intents/sending.jd | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd new file mode 100644 index 0000000..a71c8f9 --- /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 + + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#Build">Build an Implicit Intent</a></li> + <li><a href="#Verify">Verify There is an App to Receive the Intent</a></li> + <li><a href="#StartActivity">Start an Activity with the Intent</a></li> +</ol> + +<h2>You should also read</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Sharing Content</a></li> +</ul> + + </div> +</div> + +<p>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.</p> + +<p>As shown in the first class, <a href="{@docRoot}training/basics/firstapp/index.html">Building +Your First App</a>, you must use intents to navigate between activities in your own app. You +generally do so with an <em>explicit intent</em>, 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 <em>implicit intent</em>.</p> + +<p>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.</p> + + + +<h2 id="Build">Build an Implicit Intent</h2> + +<p>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 <em>view</em>, +<em>edit</em>, <em>send</em>, or <em>get</em> 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.</p> + +<p>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.</p> + +<p>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:</p> + +<pre> +Uri number = Uri.parse("tel:5551234"); +Intent callIntent = new Intent(Intent.ACTION_DIAL, number); +</pre> + +<p>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.</p> + +<p>Here are a couple other intents and their action and {@link android.net.Uri} data +pairs:</p> + +<ul> + <li>View a map: +<pre> +// 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); +</pre> + </li> + <li>View a web page: +<pre> +Uri webpage = Uri.parse("http://www.android.com"); +Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage); +</pre> + </li> +</ul> + +<p>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.</p> + +<p>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.</p> + +<p>Here are some more intents that add extra data to specify the desired action:</p> + +<ul> + <li>Send an email with an attachment: +<pre> +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 +</pre> + </li> + <li>Create a calendar event: +<pre> +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"); +</pre> +<p class="note"><strong>Note:</strong> This intent for a calendar event is supported only with API +level 14 and higher.</p> + </li> +</ul> + +<p class="note"><strong>Note:</strong> 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.</p> + + + +<h2 id="Verify">Verify There is an App to Receive the Intent</h2> + +<p>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.</p> + +<p class="caution"><strong>Caution:</strong> If you invoke an intent and there is no app +available on the device that can handle the intent, your app will crash.</p> + +<p>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:</p> + +<pre> +PackageManager packageManager = {@link android.content.Context#getPackageManager()}; +List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); +boolean isIntentSafe = activities.size() > 0; +</pre> + +<p>If <code>isIntentSafe</code> is <code>true</code>, then at least one app will respond to +the intent. If it is <code>false</code>, then there aren't any apps to handle the intent.</p> + +<p class="note"><strong>Note:</strong> 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 <a +href="{@docRoot}guide/publishing/publishing.html#marketintent">link to an app on Google +Play</a>).</p> + + +<h2 id="StartActivity">Start an Activity with the Intent</h2> + +<div class="figure" style="width:200px"> + <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" /> + <p class="img-caption"><strong>Figure 1.</strong> Example of the selection dialog that appears +when more than one app can handle an intent.</p> +</div> + +<p>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.</p> + +<pre> +startActivity(intent); +</pre> + +<p>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:</p> + +<pre> +// 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); +} +</pre> + + + + |