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 <intent-filter>}</a> 37 element in your manifest file for the corresponding <a 38 href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <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 <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 <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 <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 <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 <activity android:name="ShareActivity"> 99 <intent-filter> 100 <action android:name="android.intent.action.SEND"/> 101 <category android:name="android.intent.category.DEFAULT"/> 102 <data android:mimeType="text/plain"/> 103 <data android:mimeType="image/*"/> 104 </intent-filter> 105 </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 <action>}</a>, <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code 111 <category>}</a>, and <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code 112 <data>}</a> elements in each 113 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code 114 <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 <activity android:name="ShareActivity"> 129 <!-- filter for sending text; accepts SENDTO action with sms URI schemes --> 130 <intent-filter> 131 <action android:name="android.intent.action.SENDTO"/> 132 <category android:name="android.intent.category.DEFAULT"/> 133 <data android:scheme="sms" /> 134 <data android:scheme="smsto" /> 135 </intent-filter> 136 <!-- filter for sending text or images; accepts SEND action and text or image data --> 137 <intent-filter> 138 <action android:name="android.intent.action.SEND"/> 139 <category android:name="android.intent.category.DEFAULT"/> 140 <data android:mimeType="image/*"/> 141 <data android:mimeType="text/plain"/> 142 </intent-filter> 143 </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 @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