ACactus
ACactus

Reputation: 41

Can't link Android app with Digital Asset Link since app doesn't have a signature

I'm trying to to setup a Digital asset link from my website to my app, but I can't get it to work. I made sure the intent-filter was present in my manifest and I uploaded a assetlinks.json file using my Play store signing SHA 256 fingerprint, tested it with Google's statement list and it returned successfuly.

While going through verification steps again, I checked my device's app links with adb -d shell pm get-app-links --user current com.example.app and I realized that my app link didn't have a signature. I'm guessing that's its probably the reason the app can't link to my website since it can't compare a signature to the fingerprints given in the assetlinks.json hosted on my site's server.

My app link

com.example.app 01234567-89ab-cdef-0123-456789abcdef:
    User 0:
      Verification link handling allowed: true
      Selection state:
        Enabled:
          com.example.app

Compared to another

com.google.android.youtube:
    ID: 01234567-89ab-cdef-0123-456789abcdef
    Signatures: [<has-some-SHA256-certificate-fingerprints-here>]
    Domain verification state:
      youtu.be: system_configured
      m.youtube.com: system_configured
      youtube.com: system_configured
      www.youtube.com: system_configured
    User 0:
      Verification link handling allowed: true
      Selection state:
        Disabled:
          youtu.be
          m.youtube.com
          youtube.com
          www.youtube.com

For some reason, my app link doesn't have the same format as most of the other links, more importantly doesn't have a signature, and I can't figure out why. However I tried installing it, it always gave the same results. I tried installing it:

Has anyone any idea what I'm missing?

Upvotes: 2

Views: 5114

Answers (3)

while-loop
while-loop

Reputation: 11

This might help other people, but I made 2 intent filters:

  1. One with http/s only data tags and
  2. The other with my app's name as the scheme.

It didn't seem to work when the custom theme was bundled under one intent filter.

Upvotes: 1

ACactus
ACactus

Reputation: 41

I managed to find the solution to my problem. Turns out my intent-filter had multiple empty data tags which seemed to prevent my app to detect the website.

I forgot to specify that I'm my app's AndroidManifest is built by Cordova since I'm using Ionic. So I cannot edit my AndroidManifest directly. I have to use the ionic-plugin-deeplinks plugin.

The problem is, the ionic plugin generates an intent-filter with the data given in the package.json with the following format.

"cordova": {
  "plugins": {
    "ionic-plugin-deeplinks": {
      "URL_SCHEME": "my-url-scheme",
      "DEEPLINK_SCHEME": "https",
      "DEEPLINK_HOST": "com.example.app",
      "ANDROID_PATH_PREFIX": "/",
      "ANDROID_2_PATH_PREFIX": "/",
      "ANDROID_3_PATH_PREFIX": "/",
      "ANDROID_4_PATH_PREFIX": "/",
      "ANDROID_5_PATH_PREFIX": "/",
      "DEEPLINK_2_SCHEME": " ",
      "DEEPLINK_2_HOST": " ",
      "DEEPLINK_3_SCHEME": " ",
      "DEEPLINK_3_HOST": " ",
      "DEEPLINK_4_SCHEME": " ",
      "DEEPLINK_4_HOST": " ",
      "DEEPLINK_5_SCHEME": " ",
      "DEEPLINK_5_HOST": " "
    }
  }
}

This format is automatically generated by the plugin and adds multiple host/scheme/prefix to allow support of multiple addresses. However I'm using only one address, so when I'm generating the AndroidManifest with the plugin, it generates an intent-filter with many empty data tags in it.

<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:host="com.example.app" android:pathPrefix="/" android:scheme="https" />
    <data android:host=" " android:pathPrefix="/" android:scheme=" " />
    <data android:host=" " android:pathPrefix="/" android:scheme=" " />
    <data android:host=" " android:pathPrefix="/" android:scheme=" " />
    <data android:host=" " android:pathPrefix="/" android:scheme=" " />
</intent-filter>

As of now the only way I managed to remove the extra data tags was to fork the plugin's repository and remove the package.json extra properties from the plugin. It looks like this:

"cordova": {
  "plugins": {
    "ionic-plugin-deeplinks": {
      "URL_SCHEME": "my-url-scheme",
      "DEEPLINK_SCHEME": "https",
      "DEEPLINK_HOST": "com.example.app",
      "ANDROID_PATH_PREFIX": "/"
    }
  }
}

Which generates this intent-filter that is working has intented:

<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:host="com.example.app" android:pathPrefix="/" android:scheme="https" />
</intent-filter>

Upvotes: 2

Fredrik Johansson
Fredrik Johansson

Reputation: 3535

I might just have solved something like this. Things to check:

Please note, i'm only using imgur.com as an example, I'm not affiliated/working for them in any way.

  1. Check your assetlinks.json, and compare it to a working one (e.g. https://imgur.com/.well-known/assetlinks.json). You could also test your file like so: https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://imgur.com&relation=delegate_permission/common.handle_all_urls
  2. Next, check your AndroidManifest.xml, and ensure that the attribute android:autoVerify="true" is set on the intent-element (By mistake, I've declared mine on the activity-element) which caused same problem as above):
    <activity android:name=".MainActivity">
            <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="https"
                    android:host="imgur.com" />
            </intent-filter>
    </activity>
  1. Next, build a signed .apk (use the same keystore to sign your .apk with, as you've used to set the footprint in the assetlinks.json file - i.e. $ keytool -list -v -keystore myapp.keystore), and install that into the emulator. Something like this (uninstall app from emulator first):
    $ adb install /myapp/app-release.apk
    $ adb shell
    : pm get-app-links com.myapp.app

Also, this reference page is handy while working with this: https://developer.android.com/training/app-links/verify-site-associations#manual-verification -- hope this helps!

Upvotes: 0

Related Questions