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