1page.title=Allowing Other Apps to Start Your Activity
2page.tags=intents
3helpoutsWidget=true
4
5trainingnavtop=true
6
7@jd:body
8
9<div id="tb-wrapper">
10  <div id="tb">
11
12<h2>This lesson teaches you to</h2>
13<ol>
14  <li><a href="#AddIntentFilter">Add an Intent Filter</a></li>
15  <li><a href="#HandleIntent">Handle the Intent in Your Activity</a></li>
16  <li><a href="#ReturnResult">Return a Result</a></li>
17</ol>
18
19<h2>You should also read</h2>
20<ul>
21    <li><a href="{@docRoot}training/sharing/index.html">Sharing Simple Data</a></li>
22    <li><a href="{@docRoot}training/secure-file-sharing/index.html">Sharing Files</a>
23</ul>
24  </div>
25</div>
26
27<p>The previous two lessons focused on one side of the story: starting another app's activity from
28your app. But if your app can perform an action that might be useful to another app,
29your app should be prepared to respond to action requests from other apps. For instance, if you
30build a social app that can share messages or photos with the user's friends, it's in your best
31interest to support the {@link android.content.Intent#ACTION_SEND} intent so users can initiate a
32"share" action from another app and launch your app to perform the action.</p>
33
34<p>To allow other apps to start your activity, you need to add an <a
35href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter>}</a>
36element in your manifest file for the corresponding <a
37href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity>}</a> element.</p>
38
39<p>When your app is installed on a device, the system identifies your intent
40filters and adds the information to an internal catalog of intents supported by all installed apps.
41When an app calls {@link android.app.Activity#startActivity
42startActivity()} or {@link android.app.Activity#startActivityForResult startActivityForResult()},
43with an implicit intent, the system finds which activity (or activities) can respond to the
44intent.</p>
45
46
47
48<h2 id="AddIntentFilter">Add an Intent Filter</h2>
49
50<p>In order to properly define which intents your activity can handle, each intent filter you add
51should be as specific as possible in terms of the type of action and data the activity
52accepts.</p>
53
54<p>The system may send a given {@link android.content.Intent} to an activity if that activity has
55an intent filter fulfills the following criteria of the {@link android.content.Intent} object:</p>
56
57<dl>
58  <dt>Action</dt>
59    <dd>A string naming the action to perform. Usually one of the platform-defined values such
60as {@link android.content.Intent#ACTION_SEND} or {@link android.content.Intent#ACTION_VIEW}.
61    <p>Specify this in your intent filter with the <a
62href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action>}</a> element.
63The value you specify in this element must be the full string name for the action, instead of the
64API constant (see the examples below).</p></dd>
65
66  <dt>Data</dt>
67    <dd>A description of the data associated with the intent.
68    <p>Specify this in your intent filter with the <a
69href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data>}</a> element. Using one
70or more attributes in this element, you can specify just the MIME type, just a URI prefix,
71just a URI scheme, or a combination of these and others that indicate the data type
72accepted.</p>
73    <p class="note"><strong>Note:</strong> If you don't need to declare specifics about the data
74{@link android.net.Uri} (such as when your activity handles to other kind of "extra" data, instead
75of a URI), you should specify only the {@code android:mimeType} attribute to declare the type of
76data your activity handles, such as {@code text/plain} or {@code image/jpeg}.</p>
77</dd>
78  <dt>Category</dt>
79    <dd>Provides an additional way to characterize the activity handling the intent, usually related
80to the user gesture or location from which it's started. There are several different categories
81supported by the system, but most are rarely used. However, all implicit intents are defined with
82{@link android.content.Intent#CATEGORY_DEFAULT} by default.
83    <p>Specify this in your intent filter with the <a
84href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category>}</a>
85element.</p></dd>
86</dl>
87
88<p>In your intent filter, you can declare which criteria your activity accepts
89by declaring each of them with corresponding XML elements nested in the <a
90href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter>}</a>
91element.</p>
92
93<p>For example, here's an activity with an intent filter that handles the {@link
94android.content.Intent#ACTION_SEND} intent when the data type is either text or an image:</p>
95
96<pre>
97&lt;activity android:name="ShareActivity">
98    &lt;intent-filter>
99        &lt;action android:name="android.intent.action.SEND"/>
100        &lt;category android:name="android.intent.category.DEFAULT"/>
101        &lt;data android:mimeType="text/plain"/>
102        &lt;data android:mimeType="image/*"/>
103    &lt;/intent-filter>
104&lt;/activity>
105</pre>
106
107<p>Each incoming intent specifies only one action and one data type, but it's OK to declare multiple
108instances of the <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
109&lt;action>}</a>, <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
110&lt;category>}</a>, and <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
111&lt;data>}</a> elements in each
112<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
113&lt;intent-filter>}</a>.</p>
114
115<p>If any two pairs of action and data are mutually exclusive in
116their behaviors, you should create separate intent filters to specify which actions are acceptable
117when paired with which data types.</p>
118
119<p>For example, suppose your activity handles both text and images for both the {@link
120android.content.Intent#ACTION_SEND} and {@link
121android.content.Intent#ACTION_SENDTO} intents. In this case, you must define two separate
122intent filters for the two actions because a {@link
123android.content.Intent#ACTION_SENDTO} intent must use the data {@link android.net.Uri} to specify
124the recipient's address using the {@code send} or {@code sendto} URI scheme. For example:</p>
125
126<pre>
127&lt;activity android:name="ShareActivity">
128    &lt;!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
129    &lt;intent-filter>
130        &lt;action android:name="android.intent.action.SENDTO"/>
131        &lt;category android:name="android.intent.category.DEFAULT"/>
132        &lt;data android:scheme="sms" />
133        &lt;data android:scheme="smsto" />
134    &lt;/intent-filter>
135    &lt;!-- filter for sending text or images; accepts SEND action and text or image data -->
136    &lt;intent-filter>
137        &lt;action android:name="android.intent.action.SEND"/>
138        &lt;category android:name="android.intent.category.DEFAULT"/>
139        &lt;data android:mimeType="image/*"/>
140        &lt;data android:mimeType="text/plain"/>
141    &lt;/intent-filter>
142&lt;/activity>
143</pre>
144
145<p class="note"><strong>Note:</strong> In order to receive implicit intents, you must include the
146{@link android.content.Intent#CATEGORY_DEFAULT} category in the intent filter. The methods {@link
147android.app.Activity#startActivity startActivity()} and {@link
148android.app.Activity#startActivityForResult startActivityForResult()} treat all intents as if they
149declared the {@link android.content.Intent#CATEGORY_DEFAULT} category. If you do not declare it
150in your intent filter, no implicit intents will resolve to your activity.</p>
151
152<p>For more information about sending and receiving {@link android.content.Intent#ACTION_SEND}
153intents that perform social sharing behaviors, see the lesson about <a
154href="{@docRoot}training/sharing/receive.html">Receiving Simple Data from Other Apps</a>.</p>
155
156
157<h2 id="HandleIntent">Handle the Intent in Your Activity</h2>
158
159<p>In order to decide what action to take in your activity, you can read the {@link
160android.content.Intent} that was used to start it.</p>
161
162<p>As your activity starts, call {@link android.app.Activity#getIntent()} to retrieve the
163{@link android.content.Intent} that started the activity. You can do so at any time during the
164lifecycle of the activity, but you should generally do so during early callbacks such as
165{@link android.app.Activity#onCreate onCreate()} or {@link android.app.Activity#onStart()}.</p>
166
167<p>For example:</p>
168
169<pre>
170&#64;Override
171protected void onCreate(Bundle savedInstanceState) {
172    super.onCreate(savedInstanceState);
173
174    setContentView(R.layout.main);
175
176    // Get the intent that started this activity
177    Intent intent = getIntent();
178    Uri data = intent.getData();
179
180    // Figure out what to do based on the intent type
181    if (intent.getType().indexOf("image/") != -1) {
182        // Handle intents with image data ...
183    } else if (intent.getType().equals("text/plain")) {
184        // Handle intents with text ...
185    }
186}
187</pre>
188
189
190<h2 id="ReturnResult">Return a Result</h2>
191
192<p>If you want to return a result to the activity that invoked yours, simply call {@link
193android.app.Activity#setResult(int,Intent) setResult()} to specify the result code and result {@link
194android.content.Intent}. When your operation is done and the user should return to the original
195activity, call {@link android.app.Activity#finish()} to close (and destroy) your activity. For
196example:</p>
197
198<pre>
199// Create intent to deliver some kind of result data
200Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
201setResult(Activity.RESULT_OK, result);
202finish();
203</pre>
204
205<p>You must always specify a result code with the result. Generally, it's either {@link
206android.app.Activity#RESULT_OK} or {@link android.app.Activity#RESULT_CANCELED}. You can then
207provide additional data with an {@link android.content.Intent}, as necessary.</p>
208
209<p class="note"><strong>Note:</strong> The result is set to {@link
210android.app.Activity#RESULT_CANCELED} by default. So, if the user presses the <em>Back</em>
211button before completing the action and before you set the result, the original activity receives
212the "canceled" result.</p>
213
214<p>If you simply need to return an integer that indicates one of several result options, you can set
215the result code to any value higher than 0. If you use the result code to deliver an integer and you
216have no need to include the {@link android.content.Intent}, you can call {@link
217android.app.Activity#setResult(int) setResult()} and pass only a result code. For example:</p>
218
219<pre>
220setResult(RESULT_COLOR_RED);
221finish();
222</pre>
223
224<p>In this case, there might be only a handful of possible results, so the result code is a locally
225defined integer (greater than 0). This works well when you're returning a result to an activity
226in your own app, because the activity that receives the result can reference the public
227constant to determine the value of the result code.</p>
228
229<p class="note"><strong>Note:</strong> There's no need to check whether your activity was started
230with {@link
231android.app.Activity#startActivity startActivity()} or {@link
232android.app.Activity#startActivityForResult startActivityForResult()}. Simply call {@link
233android.app.Activity#setResult(int,Intent) setResult()} if the intent that started your activity
234might expect a result. If the originating activity had called {@link
235android.app.Activity#startActivityForResult startActivityForResult()}, then the system delivers it
236the result you supply to {@link android.app.Activity#setResult(int,Intent) setResult()}; otherwise,
237the result is ignored.</p>
238
239
240
241
242
243
244