| page.title=Allowing Other Apps to Start Your Activity |
| page.tags=intents |
| helpoutsWidget=true |
| |
| trainingnavtop=true |
| |
| @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 Simple Data</a></li> |
| <li><a href="{@docRoot}training/secure-file-sharing/index.html">Sharing Files</a> |
| </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 |
| declared the {@link android.content.Intent#CATEGORY_DEFAULT} category. If you do not declare it |
| in your intent filter, 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 Simple Data 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> |
| |
| |
| |
| |
| |
| |