Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android app indexing and deep links: did I get it wrong all the time?

I'm implementing app indexing and I think I'm missing something, but I don't know what.

Following the guide I added my intent-filters to the app and implemented what's needed in my activity.

my application's package is com.towers.hotelsclick and the associated website (where I didn't put the link rel meta-tag yet, since I'm just testing) is www.hotelsclick.com

I saw the following intent-filter example in the guide

<activity
  android:name="com.example.android.PetstoreActivity"
 android:label="@string/title_petstore">
    <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" />
        <data android:scheme="https" />
        <data android:host="www.examplepetstore.com" />
    </intent-filter>
</activity>

so I wrote mine in this way:

    <activity
        android:name=".ActivityForAppIndexing"
        android:label="@string/title_activity"
        android:screenOrientation="portrait" >
        <intent-filter android:label="@string/app_name">
            <data android:scheme="android-app"
                android:host="com.package.myappname" />
            <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="www.mywebsite.com" />
            <data android:scheme="https"
                android:host="www.mywebsite.com" />
        </intent-filter>
    </activity>

Also, I wrote a content provider in order to parse the URI

    <provider
        android:name=".contentproviders.HotelDetailsContentProvider"
        android:authorities="com.towers.hotelsclick" >
    </provider>

which should map the URIs as follows:

    private static final String BASE_PATH = "https";
private static final String AUTHORITY = "com.towers.hotelsclick";

public static final Uri CONTENT_URI = Uri.parse("android-app://" + AUTHORITY
        + "/" + BASE_PATH);

I'm testing the implementation via command line using the following adb command:

adb shell am start -a android.intent.action.VIEW -d "https://hotelsclick.com?hotel_id=135738" com.towers.hotelsclick

and it works. The app gets automatically opened with the right activity and the right parameters. When the app starts the onNewIntent method gets called:

    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 = HotelDetailsContentProvider.CONTENT_URI.buildUpon()
                .appendPath(recipeId).build();
        bundle = new Bundle();
        bundle.putString("pictureUrl", "");

        //showRecipe(contentUri);
    }
}

(I got it of course from the examples, that's why it talks about recipes and not hotels)

But I wonder: what should I do? Get data from the intent with a

getIntent().getData().getQuery()

or use the ContentProvider and get them from the URI?

Also, I'd like to test with the Google Search Console and the "View as google" funcionality if everything is okay. I uploaded my APK and saw an URI is requested.

Now, in the "testing your app" section of the documentation I saw that the links like http://hotelsclick.com?hotel_id=135738 are referred as "deep links" while those like android-app://com.towers.hotelsclick/https/hotelsclick.com?hotel_id=135738 are referred as "URI". Am I right?

The "View as google" funcionality asks for a URI but I don't know how to create one. Also, I wonder how this URI is passed to the app and I'm pretty sure I'm getting very confused about this all URI/deepLink thing, and can't find relief in the documentation.

Where and when should I use the URI? Where and when should I use the deepLink? I guess that since I'm going to put the link rel=URI in my webpages then the app will be called in the app indexing with the URI and not with the URL of the page. But if it's so... why is the adb shell am start -a android.intent.action.VIEW -d command used for testing with the URL and not the URI? Should my app be able to get and handle URIs or URLs? And how?

I thought I had understood something about app indexing, but today I'm starting to think I got it all wrong since I started. That's why I ask you for help in answering the questions above, and possibly sheding a light on all this URL/URI/intent-filter/ContentProvider mess.

Thank you everybody

like image 546
Marco Zanetti Avatar asked Feb 10 '16 14:02

Marco Zanetti


People also ask

What is the difference between deep links and app links?

When a user click an URL, it might open a dialog which asks the user to select one of multiple apps handling the given URL. On the other hand, An Android App Link is a deep link based on your website URL that has been verified to belong to your website. When user clicks that URL, it opens your app.

How does deeplink work on Android?

Understanding Deep LinksOpens the user's preferred app that can handle the link, if it's available. If the preferred app isn't available, it opens the only app that can handle the link. If multiple apps can handle the link, it opens a dialog that lets the user select from one of the apps that can open the link.


1 Answers

First, make sure that your app handles your URLs correctly:

adb shell am start \
  -a android.intent.action.VIEW \
  -d 'https://www.hotelsclick.com?hotel_id=135738'

Also check that the activity can be opened with the browsable category:

adb shell am start \
  -a android.intent.action.VIEW \
  -c android.intent.category.BROWSABLE
  -d 'https://www.hotelsclick.com?hotel_id=135738'

If this doesn't work, edit your intent filter to have both category DEFAULT and BROWSABLE, like this

<activity
  android:name="com.towers.hotelsclick.HotelActivity"
  android:label="@string/app_name">
    <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" />
        <data android:scheme="https" />
        <data android:host="www. hotelsclick.com" />
    </intent-filter>
</activity>

Check that the android-app link is handled properly (there is nothing to do), on your phone, open android-app://com.towers.hotelsclick/https/www.hotelsclick.com?hotel_id=135738

android-app://com.towers.hotelsclick/https/www.hotelsclick.com?hotel_id=135738

If that works, the only thing you have to do is add in your HTML page

<link rel="alternate"
      href="android-app://com.towers.hotelsclick/https/www.hotelsclick.com?hotel_id=135738" />

This tells Google that the page can be open in the app identified by com.towers.hotelsclick with an intent to view https://www.hotelsclick.com/?hotel_id=135738 (something you have just tested).

like image 51
regisd Avatar answered Nov 11 '22 11:11

regisd