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

1

8

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

Hardtop answered 10/2, 2016 at 14:7 Comment(1)
Hey Marco, just a suggestion to make this question more readable: Please shorten the question! Cut down the irrelevant flaff, plus multiple questions inside a single question should be broken down into a list of questions.Simoom
M
8

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).

Midwifery answered 16/2, 2016 at 19:43 Comment(7)
Hello regisd, thank you for both your answers. Right now I can launch my activity by performing adb shell am start -a android.intent.action.VIEW -d "hotelsclick.com?hotel_id=135738" but I can't launch it using the QR code. A toast appears saying "Sorry we cannot open this link. There are no apps installed that can handle it". What does make my app sensitive to the former and not to the latter? Thank you.Hardtop
Also, I think the ?hotel_id=135738 section should not be after a slash. Therefore I created a new link with the android-app://com.towers.hotelsclick/https/www.hotelsclick.com?hotel_id=135738 link. It doesn't work either. Here it is: goo.gl/kOyLuxHardtop
Yes, I generated the wrong QR, and added an extra /.Midwifery
While I completed my response, I noticed that your intent filter is missing the activity name.Midwifery
Nope, I still get the same error. As I said, I tried creating a link without the slash as well but didn't work. Where would the activity name go in the intent-filter? I'm pretty sure I should put it without the intent filter, in the <activity android:name=".MyActivityName"... section, isn't it?Hardtop
Please update your question with how the activity is defined in the manifest.Midwifery
I just did that, I hope it helps.Hardtop

© 2022 - 2024 — McMap. All rights reserved.