| page.title=Intents and Intent Filters |
| page.tags="IntentFilter" |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#Types">Intent Types</a></li> |
| <li><a href="#Building">Building an Intent</a> |
| <ol> |
| <li><a href="#ExampleExplicit">Example explicit intent</a></li> |
| <li><a href="#ExampleSend">Example implicit intent</a></li> |
| <li><a href="#ForceChooser">Forcing an app chooser</a></li> |
| </ol> |
| </li> |
| <li><a href="#Receiving">Receiving an Implicit Intent</a> |
| <ol> |
| <li><a href="#ExampleFilters">Example filters</a></li> |
| </ol> |
| </li> |
| <li><a href="#PendingIntent">Using a Pending Intent</a></li> |
| <li><a href="#Resolution">Intent Resolution</a> |
| <ol> |
| <li><a href="#ActionTest">Action test</a></li> |
| <li><a href="#CategoryTest">Category test</a></li> |
| <li><a href="#DataTest">Data test</a></li> |
| <li><a href="#imatch">Intent matching</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>See also</h2> |
| <ol> |
| <li><a href="{@docRoot}training/basics/intents/index.html">Interacting with Other Apps</a></li> |
| <li><a href="{@docRoot}training/sharing/index.html">Sharing Content</a></li> |
| </ol> |
| |
| </div> |
| </div> |
| |
| |
| |
| |
| <p>An {@link android.content.Intent} is a messaging object you can use to request an action |
| from another <a href="{@docRoot}guide/components/fundamentals.html#Components">app component</a>. |
| Although intents facilitate communication between components in several ways, there are three |
| fundamental use-cases:</p> |
| |
| <ul> |
| <li><b>To start an activity:</b> |
| <p>An {@link android.app.Activity} represents a single screen in an app. You can start a new |
| instance of an {@link android.app.Activity} by passing an {@link android.content.Intent} |
| to {@link android.content.Context#startActivity startActivity()}. The {@link android.content.Intent} |
| describes the activity to start and carries any necessary data.</p> |
| |
| <p>If you want to receive a result from the activity when it finishes, |
| call {@link android.app.Activity#startActivityForResult |
| startActivityForResult()}. Your activity receives the result |
| as a separate {@link android.content.Intent} object in your activity's {@link |
| android.app.Activity#onActivityResult onActivityResult()} callback. |
| For more information, see the <a |
| href="{@docRoot}guide/components/activities.html">Activities</a> guide.</p></li> |
| |
| <li><b>To start a service:</b> |
| <p>A {@link android.app.Service} is a component that performs operations in the background |
| without a user interface. You can start a service to perform a one-time operation |
| (such as download a file) by passing an {@link android.content.Intent} |
| to {@link android.content.Context#startService startService()}. The {@link android.content.Intent} |
| describes the service to start and carries any necessary data.</p> |
| |
| <p>If the service is designed with a client-server interface, you can bind to the service |
| from another component by passing an {@link android.content.Intent} to {@link |
| android.content.Context#bindService bindService()}</code>. For more information, see the <a |
| href="{@docRoot}guide/components/services.html">Services</a> guide.</p></li> |
| |
| <li><b>To deliver a broadcast:</b> |
| <p>A broadcast is a message that any app can receive. The system delivers various |
| broadcasts for system events, such as when the system boots up or the device starts charging. |
| You can deliver a broadcast to other apps by passing an {@link android.content.Intent} |
| to {@link android.content.Context#sendBroadcast(Intent) sendBroadcast()}, |
| {@link android.content.Context#sendOrderedBroadcast(Intent, String) |
| sendOrderedBroadcast()}, or {@link |
| android.content.Context#sendStickyBroadcast sendStickyBroadcast()}.</p> |
| </li> |
| </ul> |
| |
| |
| |
| |
| <h2 id="Types">Intent Types</h2> |
| |
| <p>There are two types of intents:</p> |
| |
| <ul> |
| <li><b>Explicit intents</b> specify the component to start by name (the |
| fully-qualified class name). You'll typically use an explicit intent to start a component in |
| your own app, because you know the class name of the activity or service you want to start. For |
| example, start a new activity in response to a user action or start a service to download |
| a file in the background.</li> |
| |
| <li><b>Implicit intents</b> do not name a specific component, but instead declare a general action |
| to perform, which allows a component from another app to handle it. For example, if you want to |
| show the user a location on a map, you can use an implicit intent to request that another capable |
| app show a specified location on a map.</li> |
| </ul> |
| |
| <p>When you create an explicit intent to start an activity or service, the system immediately |
| starts the app component specified in the {@link android.content.Intent} object.</p> |
| |
| <div class="figure" style="width:446px"> |
| <img src="{@docRoot}images/components/intent-filters@2x.png" width="446" alt=""/> |
| <p class="img-caption"><strong>Figure 1.</strong> Illustration of how an implicit intent is |
| delivered through the system to start another activity: <b>[1]</b> <em>Activity A</em> creates an |
| {@link android.content.Intent} with an action description and passes it to {@link |
| android.content.Context#startActivity startActivity()}. <b>[2]</b> The Android System searches all |
| apps for an intent filter that matches the intent. When a match is found, <b>[3]</b> the system |
| starts the matching activity (<em>Activity B</em>) by invoking its {@link |
| android.app.Activity#onCreate onCreate()} method and passing it the {@link android.content.Intent}. |
| </p> |
| </div> |
| |
| <p>When you create an implicit intent, the Android system finds the appropriate component to start |
| by comparing the contents of the intent to the <em>intent filters</em> declared in the <a href= |
| "{@docRoot}guide/topics/manifest/manifest-intro.html">manifest file</a> of other apps on the |
| device. If the intent matches an intent filter, the system starts that component and delivers it |
| the {@link android.content.Intent} object. If multiple intent filters are compatible, the system |
| displays a dialog so the user can pick which app to use.</p> |
| |
| <p>An intent filter is an expression in an app's manifest file that |
| specifies the type of intents that the component |
| would like to receive. For instance, by declaring an intent filter for an activity, |
| you make it possible for other apps to directly start your activity with a certain kind of intent. |
| Likewise, if you do <em>not</em> declare any intent filters for an activity, then it can be started |
| only with an explicit intent.</p> |
| |
| <p class="caution"><strong>Caution:</strong> To ensure your app is secure, always use an explicit |
| intent when starting a {@link android.app.Service} and do not |
| declare intent filters for your services. Using an implicit intent to start a service is a |
| security hazard because you cannot be certain what service will respond to the intent, |
| and the user cannot see which service starts.</p> |
| |
| |
| |
| |
| |
| <h2 id="Building">Building an Intent</h2> |
| |
| <p>An {@link android.content.Intent} object carries information that the Android system uses |
| to determine which component to start (such as the exact component name or component |
| category that should receive the intent), plus information that the recipient component uses in |
| order to properly perform the action (such as the action to take and the data to act upon).</p> |
| |
| |
| <p>The primary information contained in an {@link android.content.Intent} is the following:</p> |
| |
| <dl> |
| |
| <dt><b>Component name</b></dt> |
| <dd>The name of the component to start. |
| |
| <p>This is optional, but it's the critical piece of information that makes an intent |
| <b>explicit</b>, meaning that the intent should be delivered only to the app component |
| defined by the component name. Without a component name, the intent is <b>implicit</b> and the |
| system decides which component should receive the intent based on the other intent information |
| (such as the action, data, and category—described below). So if you need to start a specific |
| component in your app, you should specify the component name.</p> |
| |
| <p class="note"><strong>Note:</strong> When starting a {@link android.app.Service}, you should |
| <strong>always specify the component name</strong>. Otherwise, you cannot be certain what service |
| will respond to the intent, and the user cannot see which service starts.</p> |
| |
| <p>This field of the {@link android.content.Intent} is a |
| {@link android.content.ComponentName} object, which you can specify using a fully |
| qualified class name of the target component, including the package name of the app. For example, |
| {@code com.example.ExampleActivity}. You can set the component name with {@link |
| android.content.Intent#setComponent setComponent()}, {@link android.content.Intent#setClass |
| setClass()}, {@link android.content.Intent#setClassName(String, String) setClassName()}, or with the |
| {@link android.content.Intent} constructor.</p> |
| |
| </dd> |
| |
| <p><dt><b>Action</b></dt> |
| <dd>A string that specifies the generic action to perform (such as <em>view</em> or <em>pick</em>). |
| |
| <p>In the case of a broadcast intent, this is the action that took place and is being reported. |
| The action largely determines how the rest of the intent is structured—particularly |
| what is contained in the data and extras. |
| |
| <p>You can specify your own actions for use by intents within your app (or for use by other |
| apps to invoke components in your app), but you should usually use action constants |
| defined by the {@link android.content.Intent} class or other framework classes. Here are some |
| common actions for starting an activity:</p> |
| |
| <dl> |
| <dt>{@link android.content.Intent#ACTION_VIEW}</dt> |
| <dd>Use this action in an intent with {@link |
| android.content.Context#startActivity startActivity()} when you have some information that |
| an activity can show to the user, such as a photo to view in a gallery app, or an address to |
| view in a map app.</dd> |
| |
| <dt>{@link android.content.Intent#ACTION_SEND}</dt> |
| <dd>Also known as the "share" intent, you should use this in an intent with {@link |
| android.content.Context#startActivity startActivity()} when you have some data that the user can |
| share through another app, such as an email app or social sharing app.</dd> |
| </dl> |
| |
| <p>See the {@link android.content.Intent} class reference for more |
| constants that define generic actions. Other actions are defined |
| elsewhere in the Android framework, such as in {@link android.provider.Settings} for actions |
| that open specific screens in the system's Settings app.</p> |
| |
| <p>You can specify the action for an intent with {@link android.content.Intent#setAction |
| setAction()} or with an {@link android.content.Intent} constructor.</p> |
| |
| <p>If you define your own actions, be sure to include your app's package name |
| as a prefix. For example:</p> |
| <pre>static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";</pre> |
| </dd> |
| |
| <dt><b>Data</b></dt> |
| <dd>The URI (a {@link android.net.Uri} object) that references the data to be acted on and/or the |
| MIME type of that data. The type of data supplied is generally dictated by the intent's action. For |
| example, if the action is {@link android.content.Intent#ACTION_EDIT}, the data should contain the |
| URI of the document to edit. |
| |
| <p>When creating an intent, |
| it's often important to specify the type of data (its MIME type) in addition to its URI. |
| For example, an activity that's able to display images probably won't be able |
| to play an audio file, even though the URI formats could be similar. |
| So specifying the MIME type of your data helps the Android |
| system find the best component to receive your intent. |
| However, the MIME type can sometimes be inferred from the URI—particularly when the data is a |
| {@code content:} URI, which indicates the data is located on the device and controlled by a |
| {@link android.content.ContentProvider}, which makes the data MIME type visible to the system.</p> |
| |
| <p>To set only the data URI, call {@link android.content.Intent#setData setData()}. |
| To set only the MIME type, call {@link android.content.Intent#setType setType()}. If necessary, you |
| can set both explicitly with {@link |
| android.content.Intent#setDataAndType setDataAndType()}.</p> |
| |
| <p class="caution"><strong>Caution:</strong> If you want to set both the URI and MIME type, |
| <strong>do not</strong> call {@link android.content.Intent#setData setData()} and |
| {@link android.content.Intent#setType setType()} because they each nullify the value of the other. |
| Always use {@link android.content.Intent#setDataAndType setDataAndType()} to set both |
| URI and MIME type.</p> |
| </dd> |
| |
| <p><dt><b>Category</b></dt> |
| <dd>A string containing additional information about the kind of component |
| that should handle the intent. Any number of category descriptions can be |
| placed in an intent, but most intents do not require a category. |
| Here are some common categories: |
| |
| <dl> |
| <dt>{@link android.content.Intent#CATEGORY_BROWSABLE}</dt> |
| <dd>The target activity allows itself to be started by a web browser to display data |
| referenced by a link—such as an image or an e-mail message. |
| </dd> |
| <dt>{@link android.content.Intent#CATEGORY_LAUNCHER}</dt> |
| <dd>The activity is the initial activity of a task and is listed in |
| the system's application launcher. |
| </dd> |
| </dl> |
| |
| <p>See the {@link android.content.Intent} class description for the full list of |
| categories.</p> |
| |
| <p>You can specify a category with {@link android.content.Intent#addCategory addCategory()}.</p> |
| </dd> |
| </dl> |
| |
| |
| <p>These properties listed above (component name, action, data, and category) represent the |
| defining characteristics of an intent. By reading these properties, the Android system |
| is able to resolve which app component it should start.</p> |
| |
| <p>However, an intent can carry additional information that does not affect |
| how it is resolved to an app component. An intent can also supply:</p> |
| |
| <dl> |
| <dt><b>Extras</b></dt> |
| <dd>Key-value pairs that carry additional information required to accomplish the requested action. |
| Just as some actions use particular kinds of data URIs, some actions also use particular extras. |
| |
| <p>You can add extra data with various {@link android.content.Intent#putExtra putExtra()} methods, |
| each accepting two parameters: the key name and the value. |
| You can also create a {@link android.os.Bundle} object with all the extra data, then insert |
| the {@link android.os.Bundle} in the {@link android.content.Intent} with {@link |
| android.content.Intent#putExtras putExtras()}.</p> |
| |
| <p>For example, when creating an intent to send an email with |
| {@link android.content.Intent#ACTION_SEND}, you can specify the "to" recipient with the |
| {@link android.content.Intent#EXTRA_EMAIL} key, and specify the "subject" with the |
| {@link android.content.Intent#EXTRA_SUBJECT} key.</p> |
| |
| <p>The {@link android.content.Intent} class specifies many {@code EXTRA_*} constants |
| for standardized data types. If you need to declare your own extra keys (for intents that |
| your app receives), be sure to include your app's package name |
| as a prefix. For example:</p> |
| <pre>static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";</pre> |
| </dd> |
| |
| <dt><b>Flags</b></dt> |
| <dd>Flags defined in the {@link android.content.Intent} class that function as metadata for the |
| intent. The flags may instruct the Android system how to launch an activity (for example, which |
| <a href="{@docRoot}guide/components/tasks-and-back-stack.html">task</a> the activity should belong |
| to) and how to treat it after it's launched (for example, whether it belongs in the list of recent |
| activities). |
| |
| <p>For more information, see the {@link android.content.Intent#setFlags setFlags()} method.</p> |
| </dd> |
| |
| </dl> |
| |
| |
| |
| |
| <h3 id="ExampleExplicit">Example explicit intent</h3> |
| |
| <p>An explicit intent is one that you use to launch a specific app component, such as |
| a particular activity or service in your app. To create an explicit intent, define |
| the component name for the {@link android.content.Intent} object—all |
| other intent properties are optional.</p> |
| |
| <p>For example, if you built a service in your app, named {@code DownloadService}, |
| designed to download a file from the web, you can start it with the following code:</p> |
| |
| <pre> |
| // Executed in an Activity, so 'this' is the {@link android.content.Context} |
| // The fileUrl is a string URL, such as "http://www.example.com/image.png" |
| Intent downloadIntent = new Intent(this, DownloadService.class); |
| downloadIntent.setData({@link android.net.Uri#parse Uri.parse}(fileUrl)); |
| startService(downloadIntent); |
| </pre> |
| |
| <p>The {@link android.content.Intent#Intent(Context,Class)} |
| constructor supplies the app {@link android.content.Context} and the |
| component a {@link java.lang.Class} object. As such, |
| this intent explicitly starts the {@code DownloadService} class in the app.</p> |
| |
| <p>For more information about building and starting a service, see the |
| <a href="{@docRoot}guide/components/services.html">Services</a> guide.</p> |
| |
| |
| |
| |
| <h3 id="ExampleSend">Example implicit intent</h3> |
| |
| <p>An implicit intent specifies an action that can invoke any app on the device able |
| to perform the action. Using an implicit intent is useful when your app cannot perform the |
| action, but other apps probably can and you'd like the user to pick which app to use.</p> |
| |
| <p>For example, if you have content you want the user to share with other people, create an intent |
| with the {@link android.content.Intent#ACTION_SEND} action |
| and add extras that specify the content to share. When you call |
| {@link android.content.Context#startActivity startActivity()} with that intent, the user can |
| pick an app through which to share the content.</p> |
| |
| <p class="caution"><strong>Caution:</strong> It's possible that a user won't have <em>any</em> |
| apps that handle the implicit intent you send to {@link android.content.Context#startActivity |
| startActivity()}. If that happens, the call will fail and your app will crash. To verify |
| that an activity will receive the intent, call {@link android.content.Intent#resolveActivity |
| resolveActivity()} on your {@link android.content.Intent} object. If the result is non-null, |
| then there is at least one app that can handle the intent and it's safe to call |
| {@link android.content.Context#startActivity startActivity()}. If the result is null, |
| you should not use the intent and, if possible, you should disable the feature that issues |
| the intent.</p> |
| |
| |
| <pre> |
| // Create the text message with a string |
| Intent sendIntent = new Intent(); |
| sendIntent.setAction(Intent.ACTION_SEND); |
| sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage); |
| sendIntent.setType({@link |
| org.apache.http.protocol.HTTP#PLAIN_TEXT_TYPE |
| HTTP.PLAIN_TEXT_TYPE}); // "text/plain" MIME type |
| |
| // Verify that the intent will resolve to an activity |
| if (sendIntent.resolveActivity(getPackageManager()) != null) { |
| startActivity(sendIntent); |
| } |
| </pre> |
| |
| <p class="note"><strong>Note:</strong> In this case, a URI is not used, but the intent's data type |
| is declared to specify the content carried by the extras.</p> |
| |
| |
| <p>When {@link android.content.Context#startActivity startActivity()} is called, the system |
| examines all of the installed apps to determine which ones can handle this kind of intent (an |
| intent with the {@link android.content.Intent#ACTION_SEND} action and that carries "text/plain" |
| data). If there's only one app that can handle it, that app opens immediately and is given the |
| intent. If multiple activities accept the intent, the system |
| displays a dialog so the user can pick which app to use..</p> |
| |
| |
| <div class="figure" style="width:200px"> |
| <img src="{@docRoot}images/training/basics/intent-chooser.png" alt=""> |
| <p class="img-caption"><strong>Figure 2.</strong> A chooser dialog.</p> |
| </div> |
| |
| <h3 id="ForceChooser">Forcing an app chooser</h3> |
| |
| <p>When there is more than one app that responds to your implicit intent, |
| the user can select which app to use and make that app the default choice for the |
| action. This is nice when performing an action for which the user |
| probably wants to use the same app from now on, such as when opening a web page (users |
| often prefer just one web browser) .</p> |
| |
| <p>However, if multiple apps can respond to the intent and the user might want to use a different |
| app each time, you should explicitly show a chooser dialog. The chooser dialog asks the |
| user to select which app to use for the action every time (the user cannot select a default app for |
| the action). For example, when your app performs "share" with the {@link |
| android.content.Intent#ACTION_SEND} action, users may want to share using a different app depending |
| on their current situation, so you should always use the chooser dialog, as shown in figure 2.</p> |
| |
| |
| |
| |
| <p>To show the chooser, create an {@link android.content.Intent} using {@link |
| android.content.Intent#createChooser createChooser()} and pass it to {@link |
| android.app.Activity#startActivity startActivity()}. For example:</p> |
| |
| <pre> |
| Intent intent = new Intent(Intent.ACTION_SEND); |
| ... |
| |
| // Always use string resources for UI text. |
| // This says something like "Share this photo with" |
| String title = getResources().getString(R.string.chooser_title); |
| // Create intent to show chooser |
| Intent chooser = Intent.createChooser(intent, title); |
| |
| // Verify the intent will resolve to at least one activity |
| if (sendIntent.resolveActivity(getPackageManager()) != null) { |
| startActivity(sendIntent); |
| } |
| </pre> |
| |
| <p>This displays a dialog with a list of apps that respond to the intent passed to the {@link |
| android.content.Intent#createChooser createChooser()} method and uses the supplied text as the |
| dialog title.</p> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <h2 id="Receiving">Receiving an Implicit Intent</h2> |
| |
| <p>To advertise which implicit intents your app can receive, declare one or more intent filters for |
| each of your app components with an <a href= |
| "{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> |
| element in your <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest file</a>. |
| Each intent filter specifies the type of intents it accepts based on the intent's action, |
| data, and category. The system will deliver an implicit intent to your app component only if the |
| intent can pass through one of your intent filters.</p> |
| |
| <p class="note"><strong>Note:</strong> An explicit intent is always delivered to its target, |
| regardless of any intent filters the component declares.</p> |
| |
| <p>An app component should declare separate filters for each unique job it can do. |
| For example, one activity in an image gallery app may have two filters: one filter |
| to view an image, and another filter to edit an image. When the activity starts, |
| it inspects the {@link android.content.Intent} and decides how to behave based on the information |
| in the {@link android.content.Intent} (such as to show the editor controls or not).</p> |
| |
| <p>Each intent filter is defined by an <a |
| href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> |
| element in the app's manifest file, nested in the corresponding app component (such |
| as an <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> |
| element). Inside the <a |
| href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a>, |
| you can specify the type of intents to accept using one or more |
| of these three elements:</p> |
| |
| <dl> |
| <dt><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a></dt> |
| <dd>Declares the intent action accepted, in the {@code name} attribute. The value |
| must be the literal string value of an action, not the class constant.</dd> |
| <dt><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a></dt> |
| <dd>Declares the type of data accepted, using one or more attributes that specify various |
| aspects of the data URI (<code>scheme</code>, <code>host</code>, <code>port</code>, |
| <code>path</code>, etc.) and MIME type.</dd> |
| <dt><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a></dt> |
| <dd>Declares the intent category accepted, in the {@code name} attribute. The value |
| must be the literal string value of an action, not the class constant. |
| |
| <p class="note"><strong>Note:</strong> In order to receive implicit intents, you |
| <strong>must include</strong> 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 this category in your intent filter, no implicit intents will resolve to |
| your activity.</p> |
| </dd> |
| </dl> |
| |
| <p>For example, here's an activity declaration with an intent filter to receive an |
| {@link android.content.Intent#ACTION_SEND} intent when the data type is text:</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"/> |
| </intent-filter> |
| </activity> |
| </pre> |
| |
| <p>It's okay to create a filter that includes more than one instance of |
| <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a>, |
| <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a>, or |
| <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a>. |
| If you do, you simply need to be certain that the component can handle any and all combinations |
| of those filter elements.</p> |
| |
| <p>When you want to handle multiple kinds of intents, but only in specific combinations of |
| action, data, and category type, then you need to create multiple intent filters.</p> |
| |
| |
| <div class="sidebox-wrapper"> |
| <div class="sidebox"> |
| <h2>Restricting access to components</h2> |
| <p>Using an intent filter is not a secure way to prevent other apps from starting |
| your components. Although intent filters restrict a component to respond to only |
| certain kinds of implicit intents, another app can potentially start your app component |
| by using an explicit intent if the developer determines your component names. |
| If it's important that <em>only your own app</em> is able to start one of your components, |
| set the <a href="{@docRoot}guide/topics/manifest/activity-element.html#exported">{@code |
| exported}</a> attribute to {@code "false"} for that component. |
| </p> |
| </div> |
| </div> |
| |
| <p>An implicit intent is tested against a filter by comparing the intent to each of the |
| three elements. To be delivered to the component, the intent must pass all three tests. |
| If it fails to match even one of them, the Android system won't deliver the intent to the |
| component. However, because a component may have multiple intent filters, an intent that does |
| not pass through one of a component's filters might make it through on another filter. |
| More information about how the system resolves intents is provided in the section below |
| about <a href="#Resolution">Intent Resolution</a>.</p> |
| |
| <p class="caution"><strong>Caution:</strong> To avoid inadvertently running a different app's |
| {@link android.app.Service}, always use an explicit intent to start your own service and do not |
| declare intent filters for your service.</p> |
| |
| <p class="note"><strong>Note:</strong> |
| For all activities, you must declare your intent filters in the manifest file. |
| However, filters for broadcast receivers can be registered dynamically by calling |
| {@link android.content.Context#registerReceiver(BroadcastReceiver, IntentFilter, String, |
| Handler) registerReceiver()}. You can then unregister the receiver with {@link |
| android.content.Context#unregisterReceiver unregisterReceiver()}. Doing so allows your app |
| to listen for specific broadcasts during only a specified period of time while your app |
| is running.</p> |
| |
| |
| |
| |
| |
| |
| |
| <h3 id="ExampleFilters">Example filters</h3> |
| |
| <p>To better understand some of the intent filter behaviors, look at the following snippet |
| from the manifest file of a social-sharing app.</p> |
| |
| <pre> |
| <activity android:name="MainActivity"> |
| <!-- This activity is the main entry, should appear in app launcher --> |
| <intent-filter> |
| <action android:name="android.intent.action.MAIN" /> |
| <category android:name="android.intent.category.LAUNCHER" /> |
| </intent-filter> |
| </activity> |
| |
| <activity android:name="ShareActivity"> |
| <!-- This activity handles "SEND" actions with text data --> |
| <intent-filter> |
| <action android:name="android.intent.action.SEND"/> |
| <category android:name="android.intent.category.DEFAULT"/> |
| <data android:mimeType="text/plain"/> |
| </intent-filter> |
| <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data --> |
| <intent-filter> |
| <action android:name="android.intent.action.SEND"/> |
| <action android:name="android.intent.action.SEND_MULTIPLE"/> |
| <category android:name="android.intent.category.DEFAULT"/> |
| <data android:mimeType="application/vnd.google.panorama360+jpg"/> |
| <data android:mimeType="image/*"/> |
| <data android:mimeType="video/*"/> |
| </intent-filter> |
| </activity> |
| </pre> |
| |
| <p>The first activity, {@code MainActivity}, is the app's main entry point—the activity that |
| opens when the user initially launches the app with the launcher icon:</p> |
| <ul> |
| <li>The {@link android.content.Intent#ACTION_MAIN} action |
| indicates this is the main entry point and does not expect any intent data.</li> |
| <li>The {@link android.content.Intent#CATEGORY_LAUNCHER} category indicates that this activity's |
| icon should be placed in the system's app launcher. If the <a |
| href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element |
| does not specify an icon with {@code icon}, then the system uses the icon from the <a |
| href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> |
| element.</li> |
| </ul> |
| <p>These two must be paired together in order for the activity to appear in the app launcher.</p> |
| |
| <p>The second activity, {@code ShareActivity}, is intended to facilitate sharing text and media |
| content. Although users might enter this activity by navigating to it from {@code MainActivity}, |
| they can also enter {@code ShareActivity} directly from another app that issues an implicit |
| intent matching one of the two intent filters.</p> |
| |
| <p class="note"><strong>Note:</strong> The MIME type, |
| <a href="https://developers.google.com/panorama/android/">{@code |
| application/vnd.google.panorama360+jpg}</a>, is a special data type that specifies |
| panoramic photos, which you can handle with the <a |
| href="{@docRoot}reference/com/google/android/gms/panorama/package-summary.html">Google |
| panorama</a> APIs.</p> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <h2 id="PendingIntent">Using a Pending Intent</h2> |
| |
| <p>A {@link android.app.PendingIntent} object is a wrapper around an {@link |
| android.content.Intent} object. The primary purpose of a {@link android.app.PendingIntent} |
| is to grant permission to a foreign application |
| to use the contained {@link android.content.Intent} as if it were executed from your |
| app's own process.</p> |
| |
| <p>Major use cases for a pending intent include:</p> |
| <ul> |
| <li>Declare an intent to be executed when the user performs an action with your <a |
| href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notification</a> |
| (the Android system's {@link android.app.NotificationManager} |
| executes the {@link android.content.Intent}). |
| <li>Declare an intent to be executed when the user performs an action with your |
| <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widget</a> |
| (the Home screen app executes the {@link android.content.Intent}). |
| <li>Declare an intent to be executed at a specified time in the future (the Android |
| system's {@link android.app.AlarmManager} executes the {@link android.content.Intent}). |
| </ul> |
| |
| <p>Because each {@link android.content.Intent} object is designed to be handled by a specific |
| type of app component (either an {@link android.app.Activity}, a {@link android.app.Service}, or |
| a {@link android.content.BroadcastReceiver}), so too must a {@link android.app.PendingIntent} be |
| created with the same consideration. When using a pending intent, your app will not |
| execute the intent with a call such as {@link android.content.Context#startActivity |
| startActivity()}. You must instead declare the intended component type when you create the |
| {@link android.app.PendingIntent} by calling the respective creator method:</p> |
| |
| <ul> |
| <li>{@link android.app.PendingIntent#getActivity PendingIntent.getActivity()} for an |
| {@link android.content.Intent} that starts an {@link android.app.Activity}.</li> |
| <li>{@link android.app.PendingIntent#getService PendingIntent.getService()} for an |
| {@link android.content.Intent} that starts a {@link android.app.Service}.</li> |
| <li>{@link android.app.PendingIntent#getBroadcast PendingIntent.getBroadcast()} for a |
| {@link android.content.Intent} that starts an {@link android.content.BroadcastReceiver}.</li> |
| </ul> |
| |
| <p>Unless your app is <em>receiving</em> pending intents from other apps, |
| the above methods to create a {@link android.app.PendingIntent} are the only |
| {@link android.app.PendingIntent} methods you'll probably ever need.</p> |
| |
| <p>Each method takes the current app {@link android.content.Context}, the |
| {@link android.content.Intent} you want to wrap, and one or more flags that specify |
| how the intent should be used (such as whether the intent can be used more than once).</p> |
| |
| <p>More information about using pending intents is provided with the documentation for each |
| of the respective use cases, such as in the <a |
| href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> |
| and <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a> API guides.</p> |
| |
| |
| |
| |
| |
| |
| |
| <h2 id="Resolution">Intent Resolution</h2> |
| |
| |
| <p>When the system receives an implicit intent to start an activity, it searches for the |
| best activity for the intent by comparing the intent to intent filters based on three aspects:</p> |
| |
| <ul> |
| <li>The intent action |
| <li>The intent data (both URI and data type) |
| <li>The intent category |
| </ul> |
| |
| <p>The following sections describe how an intents are matched to the appropriate component(s) |
| in terms of how the intent filter is declared in an app's manifest file.</p> |
| |
| |
| <h3 id="ActionTest">Action test</h3> |
| |
| <p>To specify accepted intent actions, an intent filter can declare zero or more |
| <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code |
| <action>}</a> elements. For example:</p> |
| |
| <pre> |
| <intent-filter> |
| <action android:name="android.intent.action.EDIT" /> |
| <action android:name="android.intent.action.VIEW" /> |
| ... |
| </intent-filter> |
| </pre> |
| |
| <p>To get through this filter, the action specified in the {@link android.content.Intent} |
| must match one of the actions listed in the filter.</p> |
| |
| <p>If the filter does not list any actions, there is nothing for an |
| intent to match, so all intents fail the test. However, if an {@link android.content.Intent} |
| does not specify an action, it will pass the test (as long as the filter |
| contains at least one action).</p> |
| |
| |
| |
| <h3 id="CategoryTest">Category test</h3> |
| |
| <p>To specify accepted intent categories, an intent filter can declare zero or more |
| <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code |
| <category>}</a> elements. For example:</p> |
| |
| <pre> |
| <intent-filter> |
| <category android:name="android.intent.category.DEFAULT" /> |
| <category android:name="android.intent.category.BROWSABLE" /> |
| ... |
| </intent-filter> |
| </pre> |
| |
| <p>For an intent to pass the category test, every category in the {@link android.content.Intent} |
| must match a category in the filter. The reverse is not necessary—the intent filter may |
| declare more categories than are specified in the {@link android.content.Intent} and the |
| {@link android.content.Intent} will still pass. Therefore, an intent with no categories should |
| always pass this test, regardless of what categories are declared in the filter.</p> |
| |
| <p class="note"><strong>Note:</strong> |
| Android automatically applies the the {@link android.content.Intent#CATEGORY_DEFAULT} category |
| to all implicit intents passed to {@link |
| android.content.Context#startActivity startActivity()} and {@link |
| android.app.Activity#startActivityForResult startActivityForResult()}. |
| So if you want your activity to receive implicit intents, it must |
| include a category for {@code "android.intent.category.DEFAULT"} in its intent filters (as |
| shown in the previous {@code <intent-filter>} example.</p> |
| |
| |
| |
| <h3 id="DataTest">Data test</h3> |
| |
| <p>To specify accepted intent data, an intent filter can declare zero or more |
| <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code |
| <data>}</a> elements. For example:</p> |
| |
| <pre> |
| <intent-filter> |
| <data android:mimeType="video/mpeg" android:scheme="http" ... /> |
| <data android:mimeType="audio/mpeg" android:scheme="http" ... /> |
| ... |
| </intent-filter> |
| </pre> |
| |
| <p>Each <code><a href="{@docRoot}guide/topics/manifest/data-element.html"><data></a></code> |
| element can specify a URI structure and a data type (MIME media type). There are separate |
| attributes — {@code scheme}, {@code host}, {@code port}, |
| and {@code path} — for each part of the URI: |
| </p> |
| |
| <p style="margin-left: 2em">{@code <scheme>://<host>:<port>/<path>}</p> |
| |
| <p> |
| For example: |
| </p> |
| |
| <p style="margin-left: 2em">{@code content://com.example.project:200/folder/subfolder/etc}</p> |
| |
| <p>In this URI, the scheme is {@code content}, the host is {@code com.example.project}, |
| the port is {@code 200}, and the path is {@code folder/subfolder/etc}. |
| </p> |
| |
| <p>Each of these attributes is optional in a <a |
| href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> element, |
| but there are linear dependencies:</p> |
| <ul> |
| <li>If a scheme is not specified, the host is ignored.</li> |
| <li>If a host is not specified, the port is ignored.</li> |
| <li>If both the scheme and host are not specified, the path is ignored.</li> |
| </ul> |
| |
| <p>When the URI in an intent is compared to a URI specification in a filter, |
| it's compared only to the parts of the URI included in the filter. For example:</p> |
| <ul> |
| <li>If a filter specifies only a scheme, all URIs with that scheme match |
| the filter.</li> |
| <li>If a filter specifies a scheme and an authority but no path, all URIs |
| with the same scheme and authority pass the filter, regardless of their paths.</li> |
| <li>If a filter specifies a scheme, an authority, and a path, only URIs with the same scheme, |
| authority, and path pass the filter.</li> |
| </ul> |
| |
| <p class="note"><strong>Note:</strong> A path specification can |
| contain a wildcard asterisk (*) to require only a partial match of the path name.</p> |
| |
| <p>The data test compares both the URI and the MIME type in the intent to a URI |
| and MIME type specified in the filter. The rules are as follows: |
| </p> |
| |
| <ol type="a"> |
| <li>An intent that contains neither a URI nor a MIME type passes the |
| test only if the filter does not specify any URIs or MIME types.</li> |
| |
| <li>An intent that contains a URI but no MIME type (neither explicit nor inferable from the |
| URI) passes the test only if its URI matches the filter's URI format |
| and the filter likewise does not specify a MIME type.</li> |
| |
| <li>An intent that contains a MIME type but not a URI passes the test |
| only if the filter lists the same MIME type and does not specify a URI format.</li> |
| |
| <li>An intent that contains both a URI and a MIME type (either explicit or inferable from the |
| URI) passes the MIME type part of the test only if that |
| type matches a type listed in the filter. It passes the URI part of the test |
| either if its URI matches a URI in the filter or if it has a {@code content:} |
| or {@code file:} URI and the filter does not specify a URI. In other words, |
| a component is presumed to support {@code content:} and {@code file:} data if |
| its filter lists <em>only</em> a MIME type.</p></li> |
| </ol> |
| |
| <p> |
| This last rule, rule (d), reflects the expectation |
| that components are able to get local data from a file or content provider. |
| Therefore, their filters can list just a data type and do not need to explicitly |
| name the {@code content:} and {@code file:} schemes. |
| This is a typical case. A <a |
| href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> element |
| like the following, for example, tells Android that the component can get image data from a content |
| provider and display it: |
| </p> |
| |
| <pre> |
| <intent-filter> |
| <data android:mimeType="image/*" /> |
| ... |
| </intent-filter></pre> |
| |
| <p> |
| Because most available data is dispensed by content providers, filters that |
| specify a data type but not a URI are perhaps the most common. |
| </p> |
| |
| <p> |
| Another common configuration is filters with a scheme and a data type. For |
| example, a <a |
| href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> |
| element like the following tells Android that |
| the component can retrieve video data from the network in order to perform the action: |
| </p> |
| |
| <pre> |
| <intent-filter> |
| <data android:scheme="http" android:type="video/*" /> |
| ... |
| </intent-filter></pre> |
| |
| |
| |
| <h3 id="imatch">Intent matching</h3> |
| |
| <p>Intents are matched against intent filters not only to discover a target |
| component to activate, but also to discover something about the set of |
| components on the device. For example, the Home app populates the app launcher |
| by finding all the activities with intent filters that specify the |
| {@link android.content.Intent#ACTION_MAIN} action and |
| {@link android.content.Intent#CATEGORY_LAUNCHER} category.</p> |
| |
| <p>Your application can use intent matching in a similar way. |
| The {@link android.content.pm.PackageManager} has a set of {@code query...()} |
| methods that return all components that can accept a particular intent, and |
| a similar series of {@code resolve...()} methods that determine the best |
| component to respond to an intent. For example, |
| {@link android.content.pm.PackageManager#queryIntentActivities |
| queryIntentActivities()} returns a list of all activities that can perform |
| the intent passed as an argument, and {@link |
| android.content.pm.PackageManager#queryIntentServices |
| queryIntentServices()} returns a similar list of services. |
| Neither method activates the components; they just list the ones that |
| can respond. There's a similar method, |
| {@link android.content.pm.PackageManager#queryBroadcastReceivers |
| queryBroadcastReceivers()}, for broadcast receivers. |
| </p> |
| |
| |
| |
| |