Intent Filter is a declarative statement in AndroidManifest.xml that tells the system what implicit intents an application component can handle. According to the Android Developer Guide, the filter contains action, category and data, based on which the system routes calls from other applications and system events. Android development uses Intent Filter as the main mechanism for loose coupling between components of different applications.
Key Takeaways
Intent Filter is a configuration element of an Android application that tells the system about the component's ability to handle certain types of implicit intents. Unlike explicit Intents that specify a specific class, implicit Intents contain only a description of the required action, and the system itself finds a suitable component based on registered filters.
Filters are declared inside a component — Activity, Service or BroadcastReceiver — in the AndroidManifest.xml file. Each filter can contain multiple action, category and data elements. A component can have an unlimited number of Intent Filters, each describing a separate handling scenario.
Intent Filter implements the principle of loose coupling between application components. Application A does not have to know about the existence of application B — it simply sends an Intent with an action description, and the system routes it based on filters. This mechanism underlies Share Sheet, browser selection and deep link handling.
Explicit Intents specify a specific component class to launch. They are used for internal navigation within a single application when the developer knows exactly which Activity should open. Implicit Intents contain only an action description, and the component is determined by the system dynamically.
Intent Filter works exclusively with implicit Intents. If an Intent specifies a specific class, the system ignores all filters and launches the specified component directly. Filters are checked only when resolving implicit calls, making them a key element of inter-application interaction.
| Characteristic | Explicit Intent | Implicit Intent |
|---|---|---|
| Component | Specified explicitly (className) | Determined by the system |
| Intent Filter | Not required | Required |
| Example | startActivity(Intent(this, ProfileActivity::class.java)) | Intent(ACTION_VIEW, Uri.parse("https://example.com")) |
| Security | Higher (no interception) | Lower (possible conflicts) |
Each Intent Filter consists of three groups of elements — action, category and data — the combination of which determines which Intents the component will receive. A filter is considered matched if the Intent matches at least one element of each group.
Action describes the action being performed — viewing, editing, sending. Category adds additional processing context — for example, the ability to launch from a browser. Data defines the format of the information being handled via URI or MIME type.
Example of an Intent Filter for an Activity that opens links to user profiles. The filter includes all three groups of elements for precise routing.
<activity android:name=".ProfileActivity">
<intent-filter>
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<category
android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="myapp"
android:host="profile" />
</intent-filter>
</activity>
Note the mandatory specification of category DEFAULT — without it the system will not pass implicit Intents to the component. The BROWSABLE category is added if the link should be handled from a browser.
A deep link on Android is configured through an Intent Filter with action VIEW and a data tag containing the scheme, host and path. When following a link like myapp://profile/42, the system finds an Activity with a matching filter and launches it with the passed URI. It is important to correctly configure pathPrefix, pathPattern or path for exact matching.
Starting with Android 6 (API 23), support for App Links was added — verified deep links via HTTPS. App Links use the same Intent Filter but with additional domain verification through Digital Asset Links. After verification, the system automatically opens the application without a selection dialog.
Example of a filter for App Link with verification via HTTPS link. In this case the scheme is always https, and the host matches the domain specified in Digital Asset Links.
<intent-filter android:autoVerify="true">
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<category
android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="example.com"
android:pathPrefix="/profile" />
</intent-filter>
The autoVerify attribute tells the system to check Digital Asset Links when the application is installed. If verification passes successfully, the application automatically becomes the default handler for the specified domain and paths.
After the system has selected a component to handle the Intent, the developer must extract data from the incoming intent inside the target component. For Activity, the getIntent() method in onCreate() is used; for BroadcastReceiver, the onReceive() method is used, where Intent is passed as a parameter.
Data extraction includes getting the action to determine the type of operation, data for the URI and extra parameters for additional information. Each of these elements may be absent, so a null check is mandatory before use.
Example of handling an incoming deep link in an Activity in Kotlin. The code extracts the URI from the Intent and makes navigation decisions based on the host and path.
class ProfileActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val uri = intent?.data
if (uri?.host == "profile") {
val userId = uri.lastPathSegment
loadProfile(userId)
}
}
}
It is recommended to use the safe call operator to check intent and data for null, as the activity may be launched without an incoming deep link. You should also check host and pathSegment for null before using them in navigation.
If several applications have registered an Intent Filter that matches the same implicit Intent, the system shows the user a selection dialog. The user can select an application for one-time use or set a default handler. Starting with Android 10, the selection dialog is shown only on the first call, after which the system remembers the user's choice.
To manage priority, the android:priority attribute in the intent-filter tag is used. The higher the value, the higher the priority of the component when resolving conflicts. However, priority does not work for filters from different applications — in this case, a selection dialog is always shown if no application is set as default.
The developer can programmatically call the selection dialog through Intent.createChooser(), passing the target Intent and a title. This is useful when an application wants to explicitly offer the user to choose a handler, even if a default application is set. For example, when sending images to social networks via ACTION_SEND with createChooser guarantees showing the dialog regardless of default settings.
One of the most common mistakes is the absence of the DEFAULT category in the Intent Filter. Developers copy configuration from examples but forget to add this category, as a result the Activity does not receive implicit Intents. The system simply does not see the filter for implicit calls, although explicit Intents continue to work.
The second common mistake is incorrect specification of scheme in the data tag without a full URI. If only the scheme is specified but the host is not, the filter will accept all links with this scheme from any source, which can lead to unwanted calls from untrusted sources. It is recommended to always specify at least scheme and host.
The third mistake is the absence of a null check for intent.data in the Activity code. If the Activity is launched not through a deep link but in the standard way from the launcher, the Intent does not contain a URI. Accessing intent.data without a check causes a NullPointerException and crashes the application. Always use intent?.data?.toString() with the safe call operator.
Frequently Asked Questions
Yes, the DEFAULT category is mandatory for receiving implicit Intents. Without it, the system will not pass implicit calls to the component, and the Intent Filter will only work for explicit Intents, which do not check filters anyway.
There is no limit. One Activity can contain any number of Intent Filters. Each filter describes a separate handling scenario, for example one filter for deep links, another for file handling, a third for Share Sheet.
Intent Filter is a general mechanism for handling implicit Intents. App Link is a special case of Intent Filter with verification through Digital Asset Links, which automatically assigns the application as the default handler for HTTPS links on a specified domain.
Yes, Intent Filter can be declared not only for Activity, but also for Service and BroadcastReceiver. For Service this allows running a background service from other applications, for BroadcastReceiver — receiving system broadcast messages.
The MIME type is specified in the data tag through the mimeType attribute. The filter determines what data types the component can handle — for example, image/* for all images or text/plain only for plain text. MIME types can be combined with URI schemes.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also