URL handling on Android devices works through intents. Intents let apps register themselves to get launched in response to certain specified actions, and URL opening is one of these actions. Follow the steps outlined in this documentation to define deep links for your app representing the content within your app that you want to expose to your end-users. This document will walk you through the process of declaring your deep links in your AndroidManifest.XML file, as well as handling the intent in your activity code.

The first step to making your app deep linkable is adding intent filters into your android manifest for all activities that you would like to make deep linkable.For every <activity> tag that you would like to make deep linkable, the intent filter must satisfy the following conditions:

  1. Have an <action> tag with the ACTION_VIEW intent action.
  2. Have a <data> tag to represent the URL that you would like to have the activity catch.
  3. Have two <category> tags, which the DEFAULT and BROWSABLE options.

Example:


<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" android:host="example.com" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />.

This means that the URL handler foursquare.HandleURL will handle URLs with the scheme foursquare.com

Registering a URL Scheme

To register an app as a handler for a URL scheme, we need to add an intent filter to the app's manifest. To do so, we need to know the family of URLs we want to register, and the fully-qualified component name of the activity that will handle the URL. Here, we say that the URL handler foursquare.HandleURL will handle URLs with the scheme foursquare.com. In the app's manifest, AndroidManifest.xml, we add a new activity to our app's application entry:

Example using custom schemes:

<activity xmlns:android="http://schemas.android.com/apk/res/android"
          android:name="foursquare.HandleURL"
          android:label="Foursquare">
    <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="foursquare.com" />
    </intent-filter>
</activity>

Example using HTTP scheme:

<activity xmlns:android="http://schemas.android.com/apk/res/android"
android:name="foursquare.HandleURL"
         android:label="Foursquare">
    <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="http" android:host="foursquare.com" />
    </intent-filter>
</activity>

Handling a URL Scheme

Inside an Activity, you can call getIntent() to retrieve the intent that launched that Activity. If the intent was to visit a URL (i.e., intent.getAction() == Intent.ACTION_VIEW), then intent.getData() will return that URL. To further structure your URL handling, you might consider employing a URL-routing library like Routable.

Visiting a URL from an Android app

Inside the Activity that you made deep linkable, you can call getIntent() to retrieve the intent that launched that Activity. If the intent was to visit a URL (i.e., intent.getAction() == Intent.ACTION_VIEW), then intent.getData() will return that URL.

For example:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Intent intent = getIntent();
    Uri data = intent.getData();
    String path = data.getPath();
    // Url "https://foursquare.com/explore?near=Mountain%20View&q=Dinner"
    // Path object now is equal to "near=Mountain%20View&q=Dinner"
}

Typing a URL in a browser

When a user enters a URL into the Android browser's location bar, the browser tries to handle the URL itself, instead of launching your app. Unfortunately, the browser doesn't issue a general-purpose VIEW/BROWSABLE intent when you type a URL into the location bar. It will launch your app, though, if you visit a link to your app in the page, or if a script on the page redirects the browser to your app.

Glossary

activity - A description of the entire Android activity. The activity tag starts with a namespace declaration (xmlns:android=...). If the namespace directive defining android is already in some enclosing tag (it probably is), then you don't need to define it again here. The name attribute is fully-qualified component name of the activity that we want to call. The label attribute is the name of your URL handler. The user will see the value of label when asked how to open your URL, so ensure that it is clear and comforting.

action - The action this intent provides. For a URL-handling intent, this must be VIEW.

category - The categories this intent filter covers. The categories BROWSABLE and DEFAULT should be supplied by an URL-handling intent. BROWSABLE is the usual URL-visiting category, and DEFAULT is automatically added to intents in many situations that you want to handle. (When the DEFAULT category isn't present in an intent, the intent will still match this filter).

data - The specific family of URLs to handle. To handle a URL scheme, you only need to specify the scheme attribute. If you want to be more discerning, and capture only some of the URLs at your selected scheme, you can specify a host value, and path, pathPrefix, or pathPattern. For more details, see the Android manifest.

intent-filter - The set of intents that this activity should handle.