How Android Chromium Uses Intent URLs to Launch Native Apps
This article explains the mechanics of how the Chromium web browser
on Android processes intent:// URLs to transition users
from a web page into a native mobile application. It covers the
structure of an intent URL, how Chromium intercepts and parses these
links, the security policies enforced during navigation, and the
fallback mechanisms used when a target application is not installed on
the device.
The Anatomy of an Intent URL
Traditional custom URL schemes (such as myapp://path)
fail with a broken page error if the target application is not installed
on the user's device. To solve this, Chromium on Android supports the
intent: scheme, which maps a web link directly to an
Android Intent object.
A standard Android intent URL follows this structure:
intent://host/path#Intent;scheme=custom_scheme;package=com.example.app;S.browser_fallback_url=https%3A%2F%2Fexample.com;end
intent://host/path: The base URI data passed to the application.scheme: The custom scheme the target app listens for in its manifest.package: The exact Android package name of the target application.S.browser_fallback_url: An URL-encoded web address to load if the app is missing.end: Signifies the end of the intent parameters.
Link Interception and Security Checks
When a user clicks an intent:// link, Chromium does not
make a network request. Instead, the navigation is intercepted by
Chromium's internal ExternalNavigationHandler class. Before
handing the request over to the Android operating system, Chromium
enforces several strict security policies:
- User Gesture Requirement: The navigation must be
initiated by a direct user action, such as tapping a link. If a webpage
attempts to trigger an
intent://URL automatically via JavaScript on page load, Chromium blocks the navigation to prevent malicious redirects. - Browsable Category Enforcement: Chromium
automatically attaches the
android.intent.category.BROWSABLEcategory to the intent. The target Android application must explicitly declare this category in itsAndroidManifest.xmlfile, proving it is safe to be launched from a web browser. - Component Stripping: To prevent websites from accessing private, unexported activities inside an app, Chromium strips any explicit component or class names defined in the intent string.
Parsing and Querying the OS
Once the security checks pass, Chromium converts the raw URL string
into a native Android Intent object by calling the Android
system method
Intent.parseUri(url, Intent.URI_INTENT_SCHEME).
Chromium then passes this Intent object to the Android
PackageManager using queryIntentActivities().
This asks the operating system for a list of installed applications
capable of handling the specific combination of scheme, host, path, and
package name defined in the link.
Execution and Fallback Handling
Based on the response from the Android PackageManager,
Chromium executes one of three outcomes:
- Launching the App: If a matching application is
installed on the device, Chromium calls
startActivity()with the generated intent. The Android OS pauses the browser and brings the native application to the foreground. - Triggering the Web Fallback: If no matching app is
found, Chromium inspects the parsed intent for the
browser_fallback_urlstring extra. If the developer included this parameter, Chromium cancels the external navigation and loads the fallback URL inside the current browser tab. - Redirecting to the Play Store: If the app is not
installed and no fallback URL is provided, Chromium checks if the
packageparameter was defined in the intent. If a package name is present, Chromium constructs amarket://details?id=<package_name>intent and redirects the user directly to the Google Play Store to download the application. If neither a fallback URL nor a package name is present, the navigation silently fails.