Intent filters are expressions in an app's manifest file that specify which types of messages, or "intents," an app component is willing to receive. They function as public advertisements of an app's capabilities, allowing the Android system to connect user requests to the appropriate activity, service, or broadcast receiver.
Without an intent filter, a component can only be started by an explicit intent that names it directly. By adding a filter, you allow other apps and the system to trigger your app features based on the action requested, such as opening a web link or sharing a photo.
What is an Intent Filter?
An intent filter defines the "advertising profile" for an app component. It tells the Android system that if another app wants to perform a specific task, this component is a viable candidate to handle it.
The system uses these filters to resolve implicit intents. While an explicit intent specifies exactly which component to start by name, an implicit intent merely describes an action (like viewing a map). The system scans the manifest files of all installed apps to find intent filters that match the request. If multiple apps match, the system presents a "chooser" dialog for the user to select their preferred app.
Core Components of a Filter
A filter is defined in the <intent-filter> element and typically contains three sub-elements:
* Action: The general task to perform (e.g., ACTION_VIEW or ACTION_SEND).
* Data: The type of data accepted, defined by its URI (scheme, host, path) and MIME type (e.g., image/jpeg).
* Category: Additional environment info, such as whether the component should appear in the app launcher.
Why Intent Filters matter
Intent filters determine how your app interacts with the rest of the mobile ecosystem. They directly impact user experience and app discoverability.
- App Visibility: Filters using the
LAUNCHERcategory ensure your app appears in the device’s app drawer so users can find and open it. - Cross-App Communication: They allow your app to become the default handler for specific activities, such as viewing PDFs or replying to messages.
- User Choice: When multiple apps can handle the same intent, filters ensure the user can pick their favorite tool, fostering a flexible ecosystem.
- Security and Compliance: Proper filter configuration is mandatory for modern Android versions. [Apps cannot be installed on Android 12 or higher if components with intent filters do not specify an "android:exported" value] (Android Developers).
How Intent Filters work
The Android system performs a three-part "Intent Resolution" test to match an implicit intent against available filters. A component only receives the intent if the intent passes all three tests.
1. The Action Test
The intent must match one of the actions listed in the filter. If a filter lists multiple actions, any one of them is sufficient. If the filter lists no actions, it will fail all tests.
2. The Category Test
For an intent to pass, every category included in the intent must match a category in the filter. The filter can have more categories than the intent, but it cannot have fewer.
Note: To receive implicit intents, you must include the CATEGORY_DEFAULT in your filter. The system treats all implicit intents as having this category; without it, they will never resolve to your activity.
3. The Data Test
This test compares both the URI and the MIME type. It looks at the following URI parts:
* Scheme: (e.g., http or content)
* Host: (e.g., www.example.com)
* Path: The specific location on the host.
Best practices
Secure and efficient apps follow strict rules when declaring intent filters.
- Specify "android:exported" explicitly. Set this to
trueif you want other apps to trigger the component, orfalseto keep it internal. - Use explicit intents for services. [Beginning with Android 5.0, the system throws an exception if bindService is called with an implicit intent] (Android Developers). To keep your app secure, always name the specific service component you want to start.
- Include CATEGORY_DEFAULT. If you want an activity to be reachable by other apps for general tasks, this category is mandatory for successful intent resolution.
- Limit your component's capabilities. Create separate intent filters for unique jobs. One filter might handle viewing images, while another handles editing them. This helps the system accurately match the user's goal.
- Verify App Links. For web-based filters, [use the android:autoVerify attribute to confirm you own the associated domain] (Android Developers).
Common mistakes
Mistake: Forgetting the CATEGORY_DEFAULT.
Fix: Add <category android:name="android.intent.category.DEFAULT" /> to any activity filter intended for implicit intents.
Mistake: Using an implicit intent to start a background service.
Fix: Use an explicit intent by providing the specific class name of your service to prevent security hazards where a different app might intercept the request.
Mistake: Over-using the priority attribute.
Fix: Only use priority when you must enforce a specific execution order for broadcasts or prefer one activity over others. [In many cases, Android caps requested priorities to 0 for non-privileged applications] (Android Developers).
Mistake: Failing to sanitize extras in nested intents.
Fix: [Android 12 and higher provide debugging warnings for unsafe intent launches] (Android Developers). Validate all data if your app unparcels an intent from another intent's extras.
Examples
Example: Launcher Activity
This filter tells the system that this activity is the main entry point and should be listed in the app launcher.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
Example: Sharing Text Content
This filter allows an activity to receive "share" requests containing plain text from other apps.
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
Intent Filters vs. Explicit Intents
| Feature | Intent Filter (Implicit) | Explicit Intent |
|---|---|---|
| Targeting | Based on action, data, and category. | Based on Component Name (Class name). |
| Typical Use | Communicating with other apps. | Navigating between screens in your own app. |
| Security | Lower (other apps can potentially match). | Higher (targets a specific component). |
| User Experience | May trigger an "app chooser" dialog. | Starts the target component immediately. |
FAQ
How does the system decide which activity to show if multiple filters match?
The system displays a chooser dialog, allowing the user to select which app to use. Users can often set a "daily default." However, if your app performs a "share" action, you should force the chooser dialog so the user can pick a different destination every time.
Can I register intent filters while the app is running?
Filters for activities and services must be declared in the manifest file. However, filters for broadcast receivers can be registered dynamically using registerReceiver(), allowing your app to listen for specific events only while it is currently active.
What happens if no intent filter matches a request?
If the system cannot find a matching component for an implicit intent, [it throws an ActivityNotFoundException, which the sending app must handle] (Android Developers).
Why should I use PendingIntents?
A PendingIntent wraps an underlying intent and allows another application (like the Notification Manager) to execute that intent using your app’s permissions. [In Android 12+, you must explicitly specify if a PendingIntent is mutable or immutable] (Android Developers).
Does an explicit intent need an intent filter to work?
No. Explicit intents are always delivered to their target component regardless of any filters. Intent filters are only required to make a component accessible via implicit intents.