Handling deep links from Google Plus

This post presents a simple way to handle deep links from Google Plus in your Android app and assumes that you already know how to implement or have already implemented deep linking for your app from sources other than Google Plus: one of the apps that you might want to integrate with is the phone's web browser, as it allows you to link to your app from various web pages.

Having this out of the way, let's have a look into one of the advantages deep linking from Google Plus has and how to implement this in a simple way that requires minimal maintainance after being implemented.

Possibly the biggest advantage of having your app handle deep links from the Google Plus app is that Google Plus checks the user's phone to determine if your app is present on the device.
If your application is missing, then Google Plus will direct the user to your application's page on Google Play from which the user can install it.

If your application is already installed on the device, then Google Plus will trigger an Intent that will start your application. This intent will have set vnd.google.deeplink as the URI scheme and com.google.android.apps.plus.VIEW_DEEP_LINK set as the action.

While this gives the Google Plus app the advantage of knowing exactly which app to start when the user taps on the post, it has the drawback of only being usable from the Google Plus app, effectively forcing you to handle it separately from other deep link intents in your app.

If you want to enable deep linking for your app from the phone's browser, keep in mind that you cannot set the the action of the intent that the browser's going to fire off when a user taps one of your links. The browser will always use an intent with the android.intent.action.VIEW action when it starts your application and the only thing that you can do is to have one or more intent filters that can handle this specific action.

This makes it harder to handle app navigation from deep links, as you have to deal with two separate intents that should do the same thing.

A good way to avoid having duplicate code to handle these intents is to have the content deep link ID on your Google Plus shares match the URI that you would use for displaying the same deep link when your app would be launched from the phone's browser. You can then call PlusShare.getDeepLinkId(Intent) and get a string which is the representation of a valid URI that your app can handle.

This gives you the ability to pass on the URI handling for the Google Plus deep links to the other part(s) of your app that is(are) handling URIs for regular deep links. Besides that, you have two more benefits from doing this: easier processing for the incoming deep links from Google Plus and the ability expand the deep links from Google Plus that your app handles without having to modify the code in your activity responsible for handling these links.

After doing this you can just create and fire off an intent with the URI string that you retrieved from PlusShare.getDeepLinkId(Intent) and the android.intent.action.VIEW action and your application will handle that intent as if it came from the browser. As an extra, you can set the package for the intent to match your application's package name in order to be sure that your app is the one that will handle this intent.

By doing the above, this is the only code that your app will need to handle incoming Google Plus deep links:

package com.example.app.activities

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import com.google.android.gms.plus.PlusShare;

public class GooglePlusDeepLinkActivity extends Activity{
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        String deepLinkId = PlusShare.getDeepLinkId(this.getIntent());
        Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(deepLinkId));
        launchIntent.setPackage("com.example.app");
        startActivity(launchIntent);
    }
}

Also, don't forget to declare the activity in AndroidManifest.xml with the noHistory flag set to true (so that it gets removed automatically from the activity stack) and the theme set to @android:style/Theme.NoDisplay (so that the activity does not get shown):

<activity android:name="com.example.app.activities.GooglePlusDeepLinkActivity"
    android:theme="@android:style/Theme.NoDisplay"
    android:noHistory="true">
    <intent-filter>
        <data android:scheme="vnd.google.deeplink" />
        <action android:name="com.google.android.apps.plus.VIEW_DEEP_LINK" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

I know that this may not be the optimal way to handle deep links from the performance point of view, but the performance impact of (re-)triggering a deep link way to small compared to the benefits that this approach provides in terms of inital development time and further code maintenance cost.

I've tried and tested this solution in conjunction with the MobileDeepLinking library on a lower end device and I could not notice any speed difference when starting an app from a regular deep link and starting the app from a Google Plus deep link which triggered the same link.

I hope you enjoyed this article, if there is something that you would like to add or share about this topic, feel free to use the comment section below.


Want to receive updates about new articles? Add me on Twitter or Google+