Connect with your users with Google Search and App Indexing

James Montemagno

How do you keep users engaged and coming back for more once your app is installed on a their devices? Did you know that, according to Google, on average only 26% of apps installed on a user’s devices are used on a daily basis? There are several innovative ways to drive users back to your app. On iOS, you can use NSUserActivity or Core Spotlight to surface your app when the user is looking for related information. You could also use Google’s App Invites (both on iOS and Android) to let existing users recommend your app to their friends. Even if your app fulfills a user’s needs, once they’re searching in a browser, all hope of reconnecting them to it is lost. Until now, with Google’s introduction of App Indexing, which aims to solve this problem by putting your app front and center when users are in Google Search, the world’s most popular search engine.

App Indexing Monkeys

Available for both iOS and Android as part of Google Play services, App Indexing lets you expose your app content via search result, improving user re-engagement and driving new installs. In this post, I’m going to focus on an Android app that I built to learn all about your favorite monkeys called Monkeys App. With App Indexing, relevant results from my app will show in search results to deep link to content in it without requiring any navigation. In addition to this, relevant Google searches will now show search results from your website, along with a big button prompting users to install your app, which can lead to more downloads. For users who already use your app, users can re-engage quickly by navigating directly to your app from search results, and even appear on Android M’s Now on Tap.

I’m going to show you how to easily integrate Google’s App Indexing SDK into the Monkeys App for Android and its companion website in just a few minutes. App Indexing is also available to integrate into iOS applications, which you can learn more about on the Google Developer portal and the App Indexing iOS component.

In Action

Here are a few highlights of what the final integration looks like:

Getting Started

Before you get started implementing App Indexing, it’s important that your website is live and that a version of your app is live on Google Play.

Support HTTP URLs

Before ever integrating the App Indexing SDK, we can supply a specific activity with new intent filters to handle specific data schemes. This is the fist step in associating an HTTP URL such as http://monkeysapp.com/Home/Detail/Baboon to navigate into the app’s details activity instead of navigating to the website. This will also handle the case of heading to http://monkeysapp.com to simply launch the app.

Add Intent Filters

Intent filters are part of the app’s manifest file and specify the type of intents that the activity would like to receive. These are common when an application would like other apps to directly start a specific activity in your app, such as sharing text or photos. Filters in this case will tell App Indexing what types of URL data schemes your app can handle (such as http URLs). Filters are added as attributes to the Activity:

[Activity(Name = "com.refractored.monkeysapp.MainActivity", Label = "Monkeys App", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, Icon = "@drawable/ic_launcher")]
[IntentFilter(new []{ Intent.ActionView },
        Categories = new []
        {
            Android.Content.Intent.CategoryDefault,
            Android.Content.Intent.CategoryBrowsable
        },
        DataScheme = "http",
        DataPathPrefix = "/Home/Detail/"
        DataHost = "www.monkeysapp.com")]
public class MainActivity : AppCompatActivity
{
    //...
}

As you can see, I’m also setting DataPathPrefix to /Home/Detail/ to tell App Indexing where the content lives. You may also want another Intent Filter to handle launching your app from the website’s root, which would look like this:

[IntentFilter(new []{ Intent.ActionView },
    Categories = new []
    {
        Android.Content.Intent.CategoryDefault,
        Android.Content.Intent.CategoryBrowsable
    },
    DataScheme = "https",
    DataPathPrefix = "/Home/Detail/",
    DataHost = "www.monkeysapp.com")]

You can create additional Intent Filters to handle more URLs or to handle additional data schemes, such as https.

Handle Intent Filters

Your app will receive additional information that can be parsed to display information that was deep linked when it’s started with this intent filter. This information will be part of the Intent’s DataString. In this example, we’ll find the ID of the monkey by finding the last “/” in the URL that is passed in.

protected override void OnCreate(Android.OS.Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    SetContentView(Resource.Layout.activity_main);
     //Attempt to parse out monkey.
    OnNewIntent(Intent);
}

protected override void OnNewIntent(Intent intent)
{
    base.OnNewIntent(intent);
    var action = intent.Action;
    var data = intent.DataString;
    if (Intent.ActionView != action || string.IsNullOrWhiteSpace(data))
        return;

    //only if deep linking
    if (!data.Contains("/Home/Detail/"))
        return;

    var monkeyId = data.Substring(data.LastIndexOf("/", StringComparison.Ordinal) + 1).Replace("%20", " ");

    if (!string.IsNullOrWhiteSpace(monkeyId))
    {
        var i = new Intent(this, typeof(DetailsActivity));
        i.PutExtra("Name", monkeyId);
        StartActivity(i);
    }
}

Declare App and Website Association

This is probably the trickiest part of the process, as you must have both your App set up in Google Play and your website registered on Google Search. For this to work, you must be the verified owner of your app in Google Play and it must be the same account that is managing the app in the Search Console.

  • From Search Console: Add and verify your app to Search Console (see Search Console for Apps for instructions). Go to Associate a Website, choose your verified app from the list, and enter the URL of the site or sites you want to associate with the app.
  • From the Developer Console: Request to verify your website. This sends a message to your webmaster to associate your app to your site. See App Indexing on Google Search on the Developer Console Help Center for details.

Screenshot_20160111-105046

Add App Indexing API

Now it’s time to set up App Indexing in your app. The API enables you to provide specific information to App Indexing to autocomplete queries on the phone and improve re-engagement for your app by providing the API title, description, and optionally more structured data information.

Add Google Play services (GPS)

First, add the App Indexing NuGet to your Xamarin.Android application.

App Indexing Nuget

Bring in App Indexing namespaces

In the Activity that you wish to add the App Indexing API to, in this case the monkey details page, add the following using statements:

using Android.Gms.AppIndexing;
using Android.Gms.Common.Apis;
using Android.Runtime;
using IndexingAction = Android.Gms.AppIndexing.Action;

Add App Indexing API calls

It’s now time to set up the information that we want to supply to App Indexing that will allow search results to show pertinent information. In this instance, the information is dynamic based on the monkey that we’re viewing:

public class DetailsActivity : AppCompatActivity
{
    Monkey monkey;
    GoogleApiClient client;
    string url, title, description, schemaType;
    protected override void OnCreate(Android.OS.Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.activity_detail);

        //Setup GoogleApiClient and get information
        client = new GoogleApiClient.Builder(this).AddApi(AppIndex.API).Build();
        url = $"http://monkeysapp.com/Home/Detail/{monkey.Name.Replace(" ", "%20")}";
        title = monkey.Name;
        description = monkey.Details;
        schemaType = "http://schema.org/Article";
    }

    // Generate the IndexingAction on the demand
    public IndexingAction AppIndexAction
    {
        get
        {
            var item = new Thing.Builder()
            .SetName(title)
            .SetDescription(description)
            .SetUrl(Android.Net.Uri.Parse(url))
            .Build();

            var thing = new IndexingAction.Builder(IndexingAction.TypeView)
                .SetObject(item)
                .SetActionStatus(IndexingAction.StatusTypeCompleted)
                .Build();

            return thing.JavaCast();
        }
    }
}

Indicate App Activity

When the activity is created the new Indexing Action is also​ created and can be sent to the App Indexing API.

protected override async void OnStart()
{
    base.OnStart();
    client.Connect();
    await AppIndex.AppIndexApi.StartAsync(client, AppIndexAction);
}

protected override async void OnStop()
{
    base.OnStop();    
    await AppIndex.AppIndexApi.EndAsync(client, AppIndexAction);
    client.Disconnect();
}

The StartAsync method will associate the currently viewed item with the URL that was constructed and is the heart and soul of the App Indexing API.

Test Implementation

Test that your links open your app by using the Android Debug Bridge, where {DEEP-LINK} represents the URI declared in your app manifest. See Supported Deep Link Methods.

adb shell am start -a android.intent.action.VIEW -d "{DEEP-LINK}" com.your.packagename

Find more information on testing at https://developers.google.com/app-indexing/android/test

Learn More

With just a few lines of code and a few Intent Filters, you’re on your way to deep integration with Google Search and App Indexing to easily increase engagement in your app. To learn more about App Indexing, head over to the Google Developer portal and then be sure to grab the Google App Indexing Component for iOS and Android’s Google Play services – App Indexing Component, and don’t forget to grab the full source code for the Monkeys app on my GitHub.

0 comments

Discussion is closed.

Feedback usabilla icon