am 71e8f4c1
: Merge "docs: add 101 class about intents, Interacting with Other Apps" into ics-mr1
* commit '71e8f4c152a84ff420dcf834bc0acd73644f0cb0': docs: add 101 class about intents, Interacting with Other Apps
This commit is contained in:
BIN
docs/html/images/training/basics/intents-choice.png
Normal file
BIN
docs/html/images/training/basics/intents-choice.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
244
docs/html/training/basics/intents/filters.jd
Normal file
244
docs/html/training/basics/intents/filters.jd
Normal file
@ -0,0 +1,244 @@
|
||||
page.title=Allowing Other Apps to Start Your Activity
|
||||
parent.title=Interacting with Other Apps
|
||||
parent.link=index.html
|
||||
|
||||
trainingnavtop=true
|
||||
previous.title=Getting a Result from an Activity
|
||||
previous.link=result.html
|
||||
|
||||
@jd:body
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#AddIntentFilter">Add an Intent Filter</a></li>
|
||||
<li><a href="#HandleIntent">Handle the Intent in Your Activity</a></li>
|
||||
<li><a href="#ReturnResult">Return a Result</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>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.</p>
|
||||
|
||||
<p>To allow other apps to start your activity, you need to add an <a
|
||||
href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a>
|
||||
element in your manifest file for the corresponding <a
|
||||
href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
|
||||
|
||||
<h2 id="AddIntentFilter">Add an Intent Filter</h2>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<dl>
|
||||
<dt>Action</dt>
|
||||
<dd>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}.
|
||||
<p>Specify this in your intent filter with the <a
|
||||
href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a> 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).</p></dd>
|
||||
|
||||
<dt>Data</dt>
|
||||
<dd>A description of the data associated with the intent.
|
||||
<p>Specify this in your intent filter with the <a
|
||||
href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> 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.</p>
|
||||
<p class="note"><strong>Note:</strong> 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}.</p>
|
||||
</dd>
|
||||
<dt>Category</dt>
|
||||
<dd>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.
|
||||
<p>Specify this in your intent filter with the <a
|
||||
href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a>
|
||||
element.</p></dd>
|
||||
</dl>
|
||||
|
||||
<p>In your intent filter, you can declare which criteria your activity accepts
|
||||
by declaring each of them with corresponding XML elements nested in the <a
|
||||
href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a>
|
||||
element.</p>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<pre>
|
||||
<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>
|
||||
</pre>
|
||||
|
||||
<p>Each incoming intent specifies only one action and one data type, but it's OK to declare multiple
|
||||
instances of the <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
|
||||
<action>}</a>, <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
|
||||
<category>}</a>, and <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
|
||||
<data>}</a> elements in each
|
||||
<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
|
||||
<intent-filter>}</a>.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<pre>
|
||||
<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>
|
||||
</pre>
|
||||
|
||||
<p class="note"><strong>Note:</strong> 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.</p>
|
||||
|
||||
<p>For more information about sending and receiving {@link android.content.Intent#ACTION_SEND}
|
||||
intents that perform social sharing behaviors, see the lesson about <a
|
||||
href="{@docRoot}training/sharing/receive.html">Receiving Content from Other Apps</a>.</p>
|
||||
|
||||
|
||||
<h2 id="HandleIntent">Handle the Intent in Your Activity</h2>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>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()}.</p>
|
||||
|
||||
<p>For example:</p>
|
||||
|
||||
<pre>
|
||||
@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 ...
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 id="ReturnResult">Return a Result</h2>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<pre>
|
||||
// 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();
|
||||
</pre>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p class="note"><strong>Note:</strong> The result is set to {@link
|
||||
android.app.Activity#RESULT_CANCELED} by default. So, if the user presses the <em>Back</em>
|
||||
button before completing the action and before you set the result, the original activity receives
|
||||
the "canceled" result.</p>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<pre>
|
||||
setResult(RESULT_COLOR_RED);
|
||||
finish();
|
||||
</pre>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p class="note"><strong>Note:</strong> 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.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
64
docs/html/training/basics/intents/index.jd
Normal file
64
docs/html/training/basics/intents/index.jd
Normal file
@ -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
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>Dependencies and prerequisites</h2>
|
||||
<ul>
|
||||
<li>Basic understanding of the Activity lifecycle (see <a
|
||||
href="{@docRoot}training/basics/activity-lifecycle/index.html">Managing the Activity
|
||||
Lifecycle</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>You should also read</h2>
|
||||
<ul>
|
||||
<li><a href="{@docRoot}training/sharing/index.html">Sharing Content</a></li>
|
||||
<li><a
|
||||
href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">
|
||||
Integrating Application with Intents (blog post)</a></li>
|
||||
<li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent
|
||||
Filters</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>An Android app typically has several <a
|
||||
href="{@docRoot}guide/topics/fundamentals/activities.html">activities</a>. 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.</p>
|
||||
|
||||
<p>An {@link android.content.Intent} can be <em>explicit</em> in order to start a specific component
|
||||
(a specific {@link android.app.Activity} instance) or <em>implicit</em> in order to start any
|
||||
component that can handle the intended action (such as "capture a photo").</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<h2>Lessons</h2>
|
||||
|
||||
<dl>
|
||||
<dt><b><a href="sending.html">Sending the User to Another App</a></b></dt>
|
||||
<dd>Shows how you can create implicit intents to launch other apps that can perform an
|
||||
action.</dd>
|
||||
<dt><b><a href="result.html">Getting a Result from an Activity</a></b></dt>
|
||||
<dd>Shows how to start another activity and receive a result from the activity.</dd>
|
||||
<dt><b><a href="filters.html">Allowing Other Apps to Start Your Activity</a></b></dt>
|
||||
<dd>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.</dd>
|
||||
</dl>
|
||||
|
182
docs/html/training/basics/intents/result.jd
Normal file
182
docs/html/training/basics/intents/result.jd
Normal file
@ -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
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#StartActivity">Start the Activity</a></li>
|
||||
<li><a href="#ReceiveResult">Receive the Result</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>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()}).</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p class="note"><strong>Note:</strong> 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.</p>
|
||||
|
||||
|
||||
<h2 id="StartActivity">Start the Activity</h2>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>For example, here's how to start an activity that allows the user to pick a contact:</p>
|
||||
|
||||
<pre>
|
||||
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);
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 id="ReceiveResult">Receive the Result</h2>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<ul>
|
||||
<li>The request code you passed to {@link
|
||||
android.app.Activity#startActivityForResult startActivityForResult()}.</li>
|
||||
<li>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.</li>
|
||||
<li>An {@link android.content.Intent} that carries the result data.</li>
|
||||
</ul>
|
||||
|
||||
<p>For example, here's how you can handle the result for the "pick a contact" intent:</p>
|
||||
|
||||
<pre>
|
||||
@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)
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>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 <a href="{@docRoot}training/camera/index.html">Capturing Photos</a>).</p>
|
||||
|
||||
|
||||
<h4>Bonus: Read the contact data</h4>
|
||||
|
||||
<p>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 <a href="{@docRoot}guide/topics/providers/content-providers.html">content
|
||||
providers</a>. 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:</p>
|
||||
|
||||
<pre>
|
||||
@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...
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p class="note"><strong>Note:</strong> 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 <a
|
||||
href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>). 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.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
211
docs/html/training/basics/intents/sending.jd
Normal file
211
docs/html/training/basics/intents/sending.jd
Normal file
@ -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>
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user