In this codelab, you'll learn how to handle deep links in a sample Android app. You'll be able to play with the sample app to simulate deep linking from search results on your own Android device.

What you'll learn

What you'll need

How will you use this tutorial?

Read it through only Read it and complete the exercises

How would rate your experience with building Android apps?

Novice Intermediate Proficient

You can either download all the sample code to your computer...

Download Zip

...or clone the GitHub repository from the command line.

$ git clone https://github.com/google/search-samples.git

First, let's see what the finished sample app looks like. With the code downloaded, the following instructions describe how to open the completed sample app in Android Studio.

  1. Select the android-deep-linking directory from the sample code folder (Quickstart > Import Project... > android-deep-linking).
  2. Click the Gradle sync button.
  3. Enable USB debugging on your Android device.
  4. Plug in your Android device and click the Run button. You should see the Recipe App home screen appear after a few seconds.
  5. Open a command line terminal on your computer and enter the following Android Debug Bridge command:
adb shell am start -a android.intent.action.VIEW \
-d "http://recipe-app.com/recipe/pierogi-poutine" com.recipe_app
  1. Verify that a recipe appears in the sample app. This is the result of a deep link into the app!

Frequently Asked Questions

Now that you've deep deep links in action, it's time to dig deeper into what deep links are and how they work. First let's look at some sample links from our recipe website.

http://recipe-app.com/recipe/grilled-potato-salad
http://recipe-app.com/recipe/haloumi-salad
http://recipe-app.com/recipe/wedge-salad

If your app is setup to support web deep links, you can click on these web links in a web browser and get taken to the corresponding page within your Android app. Let's simulate that from ADB now:

  1. Make sure your device is still setup for USB debugging as we saw in the previous step.
  2. Repeat the same Android Debug Bridge command you used previously, but this time, with a different recipe.
adb shell am start -a android.intent.action.VIEW \
-d "http://recipe-app.com/recipe/grilled-potato-salad"

You should see the recipe app refresh with the potato salad recipe.

When you run this command, you should see a disambiguation dialog popup which asks you if you want to open the link in a web browser or with the sample app. This disambiguation dialog doesn't show if we link directly to the sample app with an app deep link.

Android app deep links have a specific protocol and invoke the app package name, but otherwise look similar in structure to the URL of the corresponding pages. This is how they're constructed:

Using this protocol, we can create Android app deep links for the other recipes from our website like this:

android-app://com.recipe_app/http/recipe/grilled-potato-salad
android-app://com.recipe_app/http/recipe/haloumi-salad
android-app://com.recipe_app/http/recipe/wedge-salad

Now, lets try these app deep links on the sample app using the same steps as we used above except we'll pass in Android app deep links instead.

adb shell am start -a android.intent.action.VIEW \
-d "http://recipe-app.com/recipe/grilled-potato-salad" com.recipe_app

Now you should see the sample app display a recipe without requiring a disambiguation dialog. This is how our sample app will behave when it is completed.

Frequently Asked Questions

Now you're ready to build on top of the starter project to add deep links to it.

  1. Select the recipe-app-start directory from your sample code download (File > Import Project... > recipe-app-star).
  2. Click the Gradle sync button.
  3. Click the Run button.

You should see the Recipe App home screen appear after a few seconds.

Open a command line terminal on your computer and try to trigger a deep link like this:

adb shell am start -a android.intent.action.VIEW \
-d "http://recipe-app.com/recipe/pierogi-poutine" com.recipe_app

You'll see the following error because the starter project doesn't yet support deep links:

Error: Activity not started, unable to resolve Intent { act=android.intent.action.VIEW 
dat=http://recipe-app.com/recipe/pierogi-poutine flg=0x10000000 pkg=com.recipe_app }

Don't worry we'll add support for deep links in the following steps.

The first step in adding deep links to your app is to update the Android manifest. Let's do that now. Add a new intent filter to the Activity of your Android manifest file so that the Android operating system knows which deep links your app can handle.

AndroidManifest.xml

<activity android:name="com.recipe_app.client.RecipeActivity"
          android:label="@string/app_name" >
    <intent-filter android:label="@string/app_name">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with "http://recipe-app.com/recipe" -->
        <data android:scheme="http"
              android:host="recipe-app.com"
              android:pathPrefix="/recipe" />
    </intent-filter>
</activity>

The updated manifest provides the following new tags:

Tags

Description

<intent-filter>

Contains the view elements for the RecipeActivity.

<action>

Specifies the ACTION_VIEW intent action.

<data>

One for each data URI format that the activity accepts. This is the primary mechanism to declare the format for our deep links.

<category>

Used both for BROWSABLE and DEFAULT intent categories:

BROWSABLE -- required for a mobile browser to execute the intent from within Google Search results. Without this attribute, a click on your URL from a mobile browser will not resolve to your app. Instead, the current web browser will open the URL of the website.

DEFAULT -- required only if you want your Android app to respond to a click from any referring website. The intent used from Google search results includes the identity of your app, so the intent explicitly points to your app as the recipient. Other links to your site do not know your app identity, so the DEFAULT category declares your app can accept an implicit intent.

With the intent declared for the RecipeActivity, you now need to add the code to the sample app to show a recipe when a deep link intent is received.

First, in the onCreate() method, add a call to onNewIntent() and pass in the intent that was sent to create the current Activity.

RecipeActivity.java

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

Then, define the onNewIntent() method and verify that the Intent is a deep link intent. If it is a deep link intent, extract the recipe URI from the intent data, look it up in the content provider and make a call to the showRecipe() method to display the recipe.

RecipeActivity.java

protected void onNewIntent(Intent intent) {
    String action = intent.getAction();
    String data = intent.getDataString();
    if (Intent.ACTION_VIEW.equals(action) && data != null) {
        String recipeId = data.substring(data.lastIndexOf("/") + 1);
        Uri contentUri = RecipeContentProvider.CONTENT_URI.buildUpon()
                .appendPath(recipeId).build();
        showRecipe(contentUri);
    }
}

This takes the unique recipe ID in the deep link and looks it up in the local database of our recipe app. If a recipe with that ID is found, the app will show it on the screen.

Frequently Asked Questions

Now make sure that the deep links make it all the way to the correct views in your completed sample app.

  1. Click the Gradle sync button.
  2. Click the Run button. You should see the Recipe App home screen appear after a few seconds.
  3. Open a command line terminal on your computer and try to trigger a deep link like this:
adb shell am start -a android.intent.action.VIEW \
-d "http://recipe-app.com/recipe/pierogi-poutine" com.recipe_app
  1. Try changing these other recipe URLs into deep links and repeating the steps above.
http://recipe-app.com/recipe/grilled-potato-salad
http://recipe-app.com/recipe/haloumi-salad
http://recipe-app.com/recipe/wedge-salad

Frequently Asked Questions

Your app is now ready to handle deep links from Google Search.

What we've covered

Next Steps

Learn More