I've followed the docs for adding deeplink where we use
https://mydomain.co/app or https://mydomain.co/app/details, etc to navigate to the app. So I've updated the manifest for this:
<intent-filter android:autoVerify="true">
<data
android:host="mydomain.co"
android:pathPrefix="/app"
android:scheme="https" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Generated the Digital Asset Links json file and added to the domain https://mydomain.co/.well-known/assetlinks.json
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "co.myapp.app",
"sha256_cert_fingerprints":
["redacted:key"]
}
}
]
So when I test using adb command (ex. adb shell am start -d "https://mydomain.co/app/profile/edit_profile")
it works perfectly but when I try using the link externally, it opens chrome and gives me 403. I'm not sure what I'm missing or what's wrong. Can somebody help me? Thanks in advance!
I found the solution: The main issue was the signature keys were not matching between Google Play and the release. That's because Google adds its own that can't be shared. So the only way to make it work was to upload the app in the Google Play Store. That means to make it work locally I need to add the signature key for the debug build into the Digital Asset Links json file.
Related
I have added my assetlinks.json to my website within the .well-known folder and confirmed the file is being served
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.******.*********",
"sha256_cert_fingerprints":
["23:DB:...."]
}
}]
I have added auto verify and data tags to the AndroidManifest.xml though as it is a capacitor application I wasn't 100% which intent-filter to add it to
<application>
<activity>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</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="https"/>
<data android:host=*****.*******.com" />
</intent-filter>
</activity>
The deep linking works fine when I manually add it within the phone/emulator but does not seem to "auto verify".
I tried the following adb commands
adb shell pm verify-app-links --re-verify com.*****.*******
then
adb shell pm get-app-links com.****.*******
And get back
com.*****.******:
ID: b5eb46a8-eb37-44ff-8b50-c6bc92402d34
Signatures: [23:DB:....]
Domain verification state:
*****.*****.com: 1024
I suppose my first question is - Should I even expect this to work with the application running in debug (unpublished/signed) and if so - any help?
according to the android app, link documentation: Do not publish your app with dev/test URLs in the manifest file that may not be accessible to the public (such as any that are accessible only with a VPN). A work-around in such cases is to configure build variants to generate a different manifest file for dev builds.
I'm working on a React Native app that is supposed to open when you click on a link that leads to the website. The iOS and Android 10 versions work just fine.
However, on Android 12 instead of opening the app the link opens in the browser. I have .well-known/assetlinks.json file in place that looks like this:
[
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "com.example",
"sha256_cert_fingerprints": [
"AA:BB:CC:DD:EE:FF...", // staging key fingerprint
"AA:BB:CC:DD:EE:FF..." // prod key fingerprint
]
}
}
]
I read this article through and through trying to find a solution to this.
I tried running adb shell pm verify-app-links --re-verify com.example and executing adb shell pm get-app-links com.example, but I keep getting the result:
Domain verification state:
example.com: legacy_failure
I also tried the Statement List Generator and Tester tool by Google. It says that there's no app deep linking permission on www.example.com, but after a few more tries it shows success.
My AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example">
<application ...>
<.../>
<activity ...>
<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"/>
<data android:host="example.com" />
</intent-filter>
<.../>
</activity>
<.../>
</application>
</manifest>
I tried changing android:host to www.example.com or *.example.com but that didn't seem to work either.
I'm trying to check how App Links work on android.
Here is what I have done so far -
Set up a local server with MAMP, apache points to port 80.
Created .well-known in the htdocs & also put the assetlinks.json in the created dir.
I am able to access it using - http://192.168.0.78/.well-known/assetlinks.json
where 192.168.0.78 is my lan ip. I generated the SHA using the keytool command.
Here are the contents of the file assetlinks.json:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.pbc.deeplinking_demo",
"sha256_cert_fingerprints":
["D9:29:00:B9:30:F1:24:A0:E7:7A:58:74:43:C6:06:FF:F6:16:BB:42:F3:A2:16:10:5D:81:27:37:3A:E5:A6:14"]
}
}]
Set up an android app with the applicationId : com.pbc.deeplinking_demo
Added the intent-filters with autoVerify=true to the activity
implementation below -
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</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:host="192.168.0.78" />
</intent-filter>
</activity>
With this config, I continue to see the disambiguation dialog asking me to choose between the default browser and the target app.
Note: I am able to access the mamp page & also the assetlinks.json from Chrome on Android emulator.
Am I missing something here or is it not possible to test this in local environment?
I have hosted assetlinks file into our domain https://ourdomain/.well-known/assetlinks.json And also verified this using https://developers.google.com/digital-asset-links/tools/generator and from android studio's App Links Assitant and got verified status from both the ways.
But when i am sharing debug APK for testing it's always opening in browser.
I also tried uploading on app store and downloaded from there for testing but it always open in browser.
Note: for debug build used my laptop SHA-256 and once app live on play store changed SHA ( got SHA-256from By going to Application Dashboard in Play Console then Release Management --> App Signing ) on hosted assetlinks file into our domain https://ourdomain/.well-known/assetlinks.json
Below is the code used in the manifest file.
<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="abc.test.com" />
</intent-filter>
Deep-links are working in Android 11 or before but on Android 12 it isn't.
But even after adding assetlinks.json file and adding all the intent-filters. Android 12 still isn't detecting deep-links. In Android-Manifest file turns out that scheme's tag is need to be separated from the data tag like this:
// OLD - Which is only working Android 11 or before
<data
android:host="domain.name"
android:pathPrefix="/videos"
android:scheme="https" />
// NEW - Which is working on all including Android 12
<data android:scheme="https" />
<data
android:host="domain.name"
android:pathPrefix="/videos" />
You need to add deep link verification.
See https://doordash.engineering/2022/01/25/your-deep-links-might-be-broken-web-intents-and-android-12/
I have same problem and solved by going to app info setting -> set as default ->support web addresses and you will see your short link
so turn it on and it will work ;)
Update:
as every one said its not a programmatically way so the best way is that link below said
In my case, the app is working in android 11, but it doesn't work in android 12 when the app is compiled and built with android studio.
I tested the production app; it works fine with the app link.
For development build, I have to go to App info -> Open by default -> Add link -> check off all the available links
This seems only happen with development builds; the apps installed from Google app store automatically has all the links selected.
In my case problem was with inconsistent between SHA Signatures in store build and https://ourdomain/.well-known/assetlinks.json, that's why deep links were disabled by default on Android 12, for fixing it we can connect our phone with problem build to Android studio and run this command:
adb shell pm get-app-links com.your_app_package_name
as a result you should see something like this:
com.your_app_package_name:
ID: .....
Signatures: [AB:CD:EF:HI:GK...]
Domain verification state:
your_domain.com legacy_failure
next you need to check whether the signature fingerprints is included in your https://ourdomain/.well-known/assetlinks.json, in my case it doesn't,
also keep in mind that in assetlinks.json file can be couple of signatures for example for debug, alpha, beta and production builds, it should looks like below:
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.your_app_package_name",
"sha256_cert_fingerprints" :["DE:BU:GS:HA:25:6...","PR:OD:SH:A:25:6..."]
}
}
]
After adding assetlinks.json in domain you have to reinstall app (just uninstall the app and install again) that will work
This fixed it for me:
<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="my.page.link" />
<data android:scheme="https" />
</intent-filter>
Notice: android:autoVerify="true"
The weird thing about this is only broke on certain Android phones, and wasn't necessarily consistent across API versions. Pixel 4 on API 33 worked fine without this fix and didn't work with Pixel 6 on API 33. What can ya do.
In my case after doing the above (debug/release SHA-256 keys in assetlinks, separate the scheme tag) the final culprit turned out to be the "path" tag. For some reason the verification process does not include the tag even though this has always been there in the app and used to work prior to Android 12. Not a big deal in my app since I was ignoring the path anyway.
Before (not working):
<data android:host="dl.example.com"
android:path="/test" />
<data android:scheme="https" />
After (working):
<data android:host="dl.example.com"/>
<data android:scheme="https"/>
Hope it helps someone
Follow these steps:
Step 1:
Add android:autoVerify="true" to your intents-filter.
Step 2:
Move the android:scheme to separate data tag
So now your intents-filter in manifest looks like this:
<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="websiteUrl"
android:pathPrefix="/" />
<data
android:scheme="https" />
<!-- note that the leading "/" is required for pathPrefix-->
</intent-filter>
Step 3:
Add your Digital Asset Links JSON file to following url:
https://{yourdomain.name}/.well-known/assetlinks.json
Note:- For production app make sure you use the digital asset links JSON file generated by Play console. You can find it at
Play console -> Your App -> Setup (Side menu option) -> App Integrity -> App signing (scroll to the bottom)
Step 4:
Verify that all the steps are correctly implemented by manually running app link validation using these commands - https://developer.android.com/training/app-links/verify-android-applinks#manual-verification
Step 5:
If your links were shown as verified in step 4 then now install the app on device and wait for atleast 2-3 minutes before clicking on any app links because in this time Android will verify your app links by reading your manifest file and the digital assets JSON file that you uploaded on your website.
After you have waited 2-3 minutes, now you can click on your app link and it should open your app.
Hope this helps!
Before Android 12, Deep link followed the standard implementation with the code in the Manifest:
<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="https"
android:host="www.yourdomain.dev"
android:pathPrefix="/set/v1" />
After Android 12, we have to add autoVerify to the intent-filter:
<intent-filter android:autoVerify="true" tools:targetApi="m">
And the website must be verified by adding assetlinks.json to the .well-known directory in your website (same as Apple does)
But, most important, you can only test this building and signing the app:
Build -> Generate Signed Bundle/APK
during development, you can test your implementation manually enabling the link in the app on your device
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:
From the Play store's internal testing
From a signed apk downloaded from the App bundle explorer
From the signed apk we normally upload to the Play store
From a manually signed apk built on my local machine
Has anyone any idea what I'm missing?
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>
This might help other people, but I made 2 intent filters:
One with http/s only data tags and
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.
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.
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
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>
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!