Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android M - App Linking not working in Chrome

So I'm looking to implement App Links in some new apps and I've read pretty thoroughly through the dev notes, setup a server, added the file with the correct json header and built a test app. The app deep linking introduced in Android M seems to be working if I send myself an email with the links attached, but when I do it on a sample page in chrome, it just reloads the page. I'm just hitting the root page on my web server. (https://www.EXAMPLE.com). I initially had some cert issues with chrome on my tablet but I added the root certificate and it now comes up green

I am using a Nexus 7 2013, freshly wiped and running Android M and Chrome, updated.

I am serving a HTML file on my server (Like it would if I had a fall back page).

Any idea if this is how I'm using the web page/fall back, or if I configured something wrong. It works beautiful in Gmail, no task selector, but not in chrome.

I tried mixing up a few examples html looks like this and none worked.

<a href="EXAMPLE://">Click HERE for schema</a>

<a href="https://www.EXAMPLE.com/">Click HERE for url with slash</a>

<a href="https://www.EXAMPLE.com">Click HERE for url, no slash</a>

<a href="#" onclick="window.location('https://www.EXAMPLE.com/')">Trying with onclick javascript</a>

My android manifest:

<activity
        android:name=".deepActivity"
        android:label="@string/title_activity_deep" >
        <intent-filter android:autoVerify="true">

            <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.EXAMPLE.com" />
            <data android:scheme="https" android:host="www.MYDOMAIN.com" />

            <!-- note that the leading "/" is required for pathPrefix-->
            <!-- Accepts URIs that begin with "example://gizmos”-->

        </intent-filter>

https://developer.android.com/training/app-links/index.html

edit:

I have been testing the auto-verify with the following command:

adb shell dumpsys package d | grep DOMAIN -ab5

and I get the results:

230:  Package: com.DOMAIN.deeplinkingtest
275:  Domains: www.DOMAIN.com
308-  Status:  undefined

From the documentation

Shows the current link-handling setting for this app. An app that has passed verification, and whose manifest contains android:autoVerify="true", shows a status of always. The hexadecimal number after this status is related to the Android system's record of the user’s app linkage preferences. This value does not indicate whether verification succeeded.

like image 931
James O'Toole Avatar asked Nov 10 '22 01:11

James O'Toole


1 Answers

...but when I do it on a sample page in chrome, it just reloads the page

I assume you mean you are just going into Chrome and typing https://example.com in the browser bar.

Unfortunately, App Linking won't work if you type a URL into the browser bar. This might sound frustrating but there is good reason why this shouldn't work. As Paul Kinlan, Google Dev Advocate explains it would be a poor user experience:

If a user enters a URL into the address bar of the system, then the intention of the user is to visit the page in question. We don’t believe that the user intended to go to the app. Ergo, redirecting the user to the app is a poor user experience.

link

This answer only relates to typing the URL into the Chrome URL bar. But the same (mostly) holds true for if the user clicks a link in a web page. Let's address why things aren't working with each of your example links. I'll start with the middle two:

<a href="https://www.EXAMPLE.com/">Click HERE for url with slash</a>

<a href="https://www.EXAMPLE.com">Click HERE for url, no slash</a>

For these links to start your application, Chrome would have to send an intent to the system with action.VIEW, category.DEFAULT**, category.BROWSABLE, and scheme either http or https. You can create an intent filter that would catch this intent (your App Linking intent filter will work):

<intent-filter android:autoVerify="true">
    <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.example.com"/>
</intent-filter>

If you check the logs (or just test it as you have) you can see that Chrome doesn't fire off an intent. They choose to handle that link internally (by navigating to a new page). This is a function of Chrome, not Android. There is no way to change that. However, you can specify a custom scheme in the URL that Chrome will respect. That brings me to your first URL:

<a href="EXAMPLE://">Click HERE for schema</a>

Chrome will respect the scheme in this URL and fire off an intent: action.VIEW, category.DEFAULT**, category.BROWSABLE, and scheme EXAMPLE. Depending on how you have your intent filter(s) setup, this will start your application. Your first impulse might be to add the EXAMPLE scheme to your App Linking intent filter:

<intent-filter android:autoVerify="true">
    <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:scheme="EXAMPLE"/>
    <data android:host="www.example.com"/>
</intent-filter>

This will allow you to click a link in Chrome and have Chrome open your app. However it will now break App Linking. The pro solution is to leave your App Linking intent filter unchanged, and add a second intent filter to catch your custom scheme:

<!-- EXAMPLE scheme intent filter -->
<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="EXAMPLE"/>
    <data android:host="www.example.com"/>
</intent-filter>

<!-- App Linking intent filter -->
<intent-filter android:autoVerify="true">
    <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.example.com"/>
</intent-filter>

This is probably TMI but getting to the root helps understand why things are working/not working.

** remember the system will add category.DEFAULT to any implicit intent.

============================================

UPDATE: I should add that using your own scheme is bad practice. An entirely better approach is documented here

like image 126
tir38 Avatar answered Nov 14 '22 23:11

tir38