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