Support HTTP URLs in Your App

App Indexing for Android uses HTTP URLs to direct users to content in your app.

Understand your site links

Structure your website and app so they share a common set of links that both platforms can open and use. For example, consider this website: http://www.appindexingsample.com. It’s a simple site for a cooking school, which contains recipe content that is ideal for indexing. It also contains a registration page where people can sign up for in-person classes and a page for browsing the in-person class schedule. These three types of content have three distinct link types:

  • Recipe Pages—http://www.appindexingsample.com/recipes/*
  • Registration Page—http://www.appindexingsample.com/registration/
  • Schedule Page—http://www.appindexingsample.com/schedule/

Add a matching view for each link type to your app. Then configure your app to recognize and handle each link type. Understanding the number and types of links you'll need to support before you start building streamlines your work. The following instructions refer back this URL structure for the examples.

Connect your site with your app

You should connect your site with your app using Digital Asset Links.

Digital Asset Links take the form of a JSON file called assetlinks.json. You upload it to your web server's .well-known directory. The file defines asset links behavior; in the case of App Indexing this means you must configure the following fields:

  • Relation: Specifies the type of relationship or delegation. For App Indexing specify that all urls delegate to the related asset link using delegate_permission/common.handle_all_urls.
  • Target: Using the namespace value of android_app determines the android app that receives the URLs. Configure it using its package name and the SHA-256 fingerprint of the certificate you used to sign your app before deploying it to the Play Store. See Signing Your Applications to learn more about deployment and your signing certificate.

Here’s an example assetlinks.json for an app package named com.appindexingsample.app. You’ll need to change the package name and sha256_cert_fingerprints content to match those for your app.

  [{
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target" : { "namespace": "android_app",
      "package_name": "com.appindexingsample.app",
                 "sha256_cert_fingerprints": ["hash_of_app_certificate"] }
  }]

Upload this content and make sure it's visible to everyone at https://<yoursite>/.well-known/assetlinks.json.

Receive incoming links in your app

In the previous section you saw how the URL structure of your site is an essential component for how to best build your app. You saw the three types of URLs on appindexingsample.com that your app must also support:

  • Recipes
  • Registration
  • Schedule

In the following sections you’ll see how to configure your Android app to recognize and respond to these links.

Add intent filters

The first step is to add intent filters to your android manifest file. In the AndroidManifest.xml, intent filters declare the HTTP URL patterns that your app handles from inbound links; the same URLs used for corresponding pages on your website. Refer to the Adding an Intent Filter section of Android Studio Help. Here’s an example of an Android manifest file for an app with activities for Schedule, Recipes, and Registration URLs:

  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.appindexingsample.app">
     <application
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
         android:supportsRtl="true"
         android:theme="@style/AppTheme">
         <activity android:name=".MainActivity">
             <intent-filter android:autoVerify="true">
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
         <activity android:name=".ScheduleActivity" />
         <activity android:name=".RecipeActivity" />
         <activity android:name=".RegistrationActivity"/>
    </application>
  </manifest>
  1. Select the <activity> tag in Android Studio to reveal the lightbulb icon to the left of the tag.
  2. Choose the lightbulb, then select Add URL from the drop-down list.

Now the activity expands to show the updated URL details:

  <activity android:name=".ScheduleActivity" >
     <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:host="app.appindexingsample.com"
             android:pathPrefix="/schedule"
             android:scheme="http" />
     </intent-filter>
  </activity>

You’ll likely have to update the host field, as it defaults to the app package name. Note that the DEFAULT and BROWSABLE categories are required. You may also want to edit the pathPrefix and the scheme. Here’s an example where the manifest has been updated for the appindexingsample.com site. It handles the pathPrefix property, and both HTTP and HTTPS schemes by adding a second <data> tag.

  <activity android:name=".ScheduleActivity" >
     <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:host="appindexingsample.com"
             android:pathPrefix="/schedule"
             android:scheme="http"/>
         <data
             android:host="appindexingsample.com"
             android:pathPrefix="/schedule"
             android:scheme="https"/>
     </intent-filter>
  </activity>

Now, when a user finds the /schedule link on your site and chooses to view the search result, your app launches and presents the schedule activity. It's important that the intent filter is conssistent with your app's logic. If the intent filter claims to support a URL, your app must also include logic to correctly handle the URL, otherwise App Indexing will fail. In the next section you'll see how to parse the link in this activity to determine how your app should render it and ensure App Indexing is successful.

Handle incoming URLs

Now that you've set the Intent Filter in your Android Manifest, your app launches a specific activity based on the URL passed to it. For example, the ScheduleActivity activity launches in response to a URL matching http://appindexingsample.com/schedule.

In this Activity you can then call getIntent() for the details from this intent. So your onCreate code could look like this:

  @Override
  protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_schedule);
     onNewIntent(getIntent());
  }

onCreate() passes the results of getIntent() (an Intent) to onNewIntent, for processing. The URL is available as a result of getDataString(), so it’s relatively simple to parse it. For example, suppose you want your app to change its background color based on whether a url is from the U.S., http://www.appindexingsample.com/schedule/ , or from another country, http://www.appindexingsample.com/ <country>. Parse out the last element of the URL and set the background color with code like this:

  protected void onNewIntent(Intent intent) {
       String action = intent.getAction();
       Uri data = intent.getData();
       if (Intent.ACTION_VIEW.equals(action) && data != null) {
           articleId = data.getLastPathSegment();
           TextView linkText = (TextView)findViewById(R.id.link);
           linkText.setText(data.toString());
       }
   }

When you finish building your app, and deploy it to the play store , your app launches in response to recognized URLs from search results.

Control indexing (optional)

You can control which app elements appear in Google Search. Specifically, you can adjust the following:

  • Exclude specific pages from Search results— For first-time App Indexing use, you can configure your manifest to include only those pages you want indexed by Google. Otherwise, create a noindex.xml file to specify the URLs you want excluded from Google Search. This is similar to how the robots noindex meta tag works for websites.
  • Exclude real-time app notifications from Search results—Use a noindex.xml file with a specific exclude tag for app notifications.

Create the noindex.xml file

Create a new XML file in your app's XML resources directory: res/xml/noindex.xml. Use statements with specific attributes to indicate the parts of your app to exclude from Google Search. These attributes are as follows:

  • uri—Excludes a specific URI from Google Search. Google doesn't index URLs that exactly match this attribute.
  • uriPrefix—Excludes all content below a URI path from Google Search. Google doesn't index those URLs starting with a string matching this attribute.
  • android:value="notification"—Excludes your app's notifications from Google Search. Google doesn't index the notifications of the app if you specify this attribute.

The following example shows a noindex.xml file that excludes a specific page, hidden directories, and limits app notifications from appearing in Google Search:

  <?xml version="1.0" encoding="utf-8"?>
  <search-engine xmlns:android="http://schemas.android.com/apk/res/android">
    <noindex android:value="notification"/>
    <noindex uri="http://appindexingsample.com/teachers/hidden-page"/>
    <noindex uriPrefix="http://appindexingsample.com/chefs/hidden_prefix"/>
  </search-engine>

Reference the noindex.xml file

After you add the noindex.xml file, reference it from the application section of the app’s AndroidManifest.xml file with the following line:

  <meta-data android:name="search-engine"
    android:resource="@xml/noindex"/>

For example:

  <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.appindexingsample.app">
    <application>
      <activity android:name="com.appindexingsample.app" ...>
        ...
      </activity>
      <meta-data android:name="search-engine" android:resource="@xml/noindex"/>
    </application>
    ...
  </manifest>

Next: Add the App Indexing API

Send feedback about...