Looking at j__m comment, I found this.
In AndroidManifest
write so:
<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" />
<!-- Write <data> tags with one attribute, if you use several domains. -->
<data android:scheme="https" />
<data android:host="example.com" />
</intent-filter>
<!-- Other domains-->
<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="server.com" />
</intent-filter>
android:autoVerify="true"
is needed for App Linking.
Create assetlinks.json
using Tools > App Links Assistant
. Then press Open Digital Asset Links File Generator
, enter domain, application id, select release
signing config and press Generate Digital Asset Links File
. Then you can save file or copy to clipboard.
You can create several assetlinks.json
files (for several applications) and join them into one JSON. To my mind it doesn't depend on Windows line endings (I used Notepad to concatenate JSONs). First time I auto-formatted it with Ctrl + Alt + L, and after uploading to domains App Link didn't work (probably because of later errors in AndroidManifest
), so on the 2nd try I didn't format JSON. I created assetlinks.json
for release
and debug
builds of the application.
Upload assetlinks.json
to https://example.com/.well-known/assetlinks.json
(in this answer I write: example.com
and mean your domain like company.name
). Check it with https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls
. The file and the domain have some restrictions. In my case everything was simple, we didn't change settings.
In your DeepLinkActivity
you can parse URLs with regular expressions. Use JUnit
to create tests. Call this method from onCreate()
:
private fun processDeepLink() {
if (intent?.data?.isHierarchical == true) {
val data = intent?.dataString
if (intent?.action == Intent.ACTION_VIEW && data != null) {
when {
REGEX.matches(data) -> // Get id and open some screen.
else -> // Either open MainActivity or skip this URL (open web browser instead).
}
finish()
}
}
}
companion object {
val REGEX = "^https://example.com/some_request/(\\d+).*".toRegex()
}
Warning! If you open a web browser from the application, you will fall into a loop. When clicking a link to your domain in the application, a browser won't appear, but your application will be opened automatically! What a surprise! So, in processDeepLink
you should check the URL and open MainActivity
when URL matches one of your masks. Skip others. Now a user will see a dialog with a list of browsers and your application (like in Deep Link). This happens because your application also handles links to your domains, like a browser.
You can also use WebView
instead of a browser (not a good solution), open Chrome Custom Tabs
or Chrome
.
Use device with Android 6 or later.
If https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls
returned no errors, build the application. Create an Email message, SMS, QR-code or another application with a link to your domain. Click it, and App Link will open your application or Deep Link will show a dialog to choose an application.
If App Link didn't work, read later.
In LogCat
select No Filters
and type IntentFilter
into search box. There should be:
I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:2 scheme:"https" hosts:"example.com" package:"com.my_package".
I/IntentFilterIntentOp: Verification 0 complete. Success:true. Failed hosts:.
Probably you will get:
I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:0 scheme:"https" hosts:"example.com server.com" package:"com.my_package".
I/IntentFilterIntentOp: Verification 0 complete. Success:false. Failed hosts:server.com.
Later you will try to fix domains in the application, so sometimes you can launch for clean install:
adb shell pm clear com.android.statementservice
Start adb shell dumpsys package d
and find your domains. There should be:
Package Name: com.my_package
Domains: example.com server.com
Status: always : 200000000
But probably it will be:
Package Name: com.my_package
Domains: example.com server.com
Status: ask
See also https://chris.orr.me.uk/android-app-linking-how-it-works/. Strange, but in an emulator it wrote: always
, while App Link didn't work.
I also tried adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://example.com"
to test App Link without a browser, but later it didn't work.
If you have several domains, comment (or remove) other domains in AndroidManifest
(retain only one domain, for example, "example.com"). Then click a URL https://example.com/something and check it uses App Link.
In my case I checked release
and debug
builds of the application. While the debug
build worked with App Link, release
didn't (and sometimes vise versa). I used the solution of rekire:
<meta-data
android:name="asset_statements"
android:resource="@string/asset_statements"/>
and it helped for 2 domains, but later stopped, so I removed it. In the end I wrote in AndroidManifest
<data>
tags with one attribute as j__m said.
Even if only one domain was failing, App Link was not working for other domains either. You can check domains one by one retaining only one domain each time in AndroidManifest
.
See also http://androidideas.com/handling-app-links-in-android/, https://willowtreeapps.com/ideas/a-better-user-experience-for-deep-linking-on-android, https://developer.android.com/training/app-links/verify-site-associations,