H5页面打开应用的几种方式
最近调研了在Android上打开H5页面的方式,本文做一下汇总。
Deep Link
Deep Link 就是在 Activity 中声明Intent Filters
的方式告诉系统,该应用可以打开特定规则的内容。缺点是当系统中出现多个可以处理相同 Intent 的应用,需要用户进行手动选择,并且在一些 rom 下,用户可以勾选永远不用不适用我们的 app 打开。
使用方式
例如我们希望处理scheme 为deeplink
,host 为applink.saymagic.cn
的请求。
- 声明如下 Activity的intent-filter:
<activity
android:name=".ItemListActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<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="deeplink" android:host="applink.saymagic.cn"/>
</intent-filter>
</activity>
- Activity 中解析 Intent
private fun parseIntent() {
val uri = intent.data
val scheme = uri.scheme
val host = uri.host
val path = uri.path
val query = uri.query
Log.d("ParseIntent", "scheme = $scheme, host = $host, path = $path, query = $query")
}
- 测试
adb shell am start -W -a android.intent.action.VIEW -d deeplink://applink.saymagic.cn
Activity成功启动.
App Link
因为使用Deep Links 有时会弹出一个对话框让用户选择是否在APP中打开。这会让用户困惑,对产品自身而言也会存在丢失用户的可能。为此, Android在Android 6.0 (API level 23) 及以后加入了App Links , 当用户点击对应的URI 时,会直接启动对应的APP,不会再有对话框出现。那系统是如何唯一确定一个 App的呢?
那就需要我们来证明一个 Uri 完全的归我们的应用所有。本例中applink.saymagic.cn
域名归我们所有。我们希望当用户点击applink.saymagic.cn
域名时可以跳转到我们的应用。
注:如果读者不方便构造 App Link
的环境,可以直接使用applink.saymagic.cn
域名。这个域名下的数据不会被我删除,同时,对应完整的 app 和签名的地址在:https://coding.net/u/saymagic/p/AppLink。读者可以 clone 下来进行实验。
使用方式
与 Deep Link 一样,需要通过声明intent-filter:
<activity
android:name=".ItemListActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<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="applink.saymagic.cn"/>
<data android:scheme="https" android:host="applink.saymagic.cn"/>
</intent-filter>
</activity>
- 配置assetlinks.json
- 获取我们应用签名文件的sha256值,本例中签名文件是 app 目录下的 secret 文件,在根目录下执行:
keytool -list -v -keystore ./app/secret
密钥库口令为applink
,执行结果:
红色框出的就是我们需要的信息
2.前往https://developers.google.com/digital-asset-links/tools/generator ,然后填写host,package,fingerprint:
然后点击GENERATE STATEMENT,生成一段json字符串:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target" : { "namespace": "android_app", "package_name": "cn.saymagic.applink",
"sha256_cert_fingerprints": ["3B:52:97:83:CD:92:7D:50:AA:70:94:62:B2:80:F3:AC:6D:B7:DE:E9:52:D5:7F:BD:5A:3B:8B:75:C1:A9:F0:94"] }
}]
将该 json 字符串拷贝下来,存放在名称为assetlinks.json
的文件中。
- 部署assetlinks.json
将assetlinks.json
部署到applink.saymagic.cn/.well-known
目录下。部署成功后,可以点击Test Statement
按钮来验证:
- 安装应用
使用adb shell dumpsys package d
命令可以查看系统中支持 App Link 的应用,以我自己的手机为例,在安装前:
可以看到,大多数国外的应用还是对App Link都做了支持。国内的应用中,只看到淘宝声明了一系列的域名。
安装时,如果我们截包的话,会看到系统发出对https://applink.saymagic.cn/.well-known/assetlinks.json
地址的请求:
安装结束后,再次使用adb shell dumpsys package d
命令,就会看到我们的应用:
- 测试:
adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d "https:/applink.saymagic.cn"
应用成功启动
微信环境
大多数想要在 H5中打开应用都可能希望通过微信来引流。但奈何微信对 Depp Link
和App Link
的支持都很差。网上很多文章提供的其它方式大多都已过时或者兼容性很差。如果您的应用支持App Link
,可行的方案是引导用户选择使用浏览器打开,这时,就会直接跳转到我们的应用了。下面是在微信浏览器中访问https:/applink.saymagic.cn
, 然后选择使用浏览器打开的效果:
如果应用支持的是Deep Link
,使用浏览器打开时就会出现多个应用的选择窗口。这里不再展示。
但这里有个问题是,如果用户没有选择我们的应用或者用户压根没有安装我们的应用该怎么办呢?我的想法是,当一个 url 不是在微信环境下打开的话,服务器直接重定向到应用下载页面。这样,相当于用户在浏览器中打开下载页面。
那微信上有没有更好的导流方案呢?腾讯全家桶中有一个叫应用宝的应用,它提供了微下载功能。支持在应用不存在时跳转应用宝下载,应用存在时启动应用或者打开指定页面。详细信息见:http://wiki.open.qq.com/index.php?title=mobile/%E5%BA%94%E7%94%A8%E5%AE%9D%E5%BE%AE%E4%B8%8B%E8%BD%BD
综上,我这边绘制了一个H5页面内打开应用的一个相对完整的流程图:
其它说明
- Deep Link支持自定义 scheme,而App Link 只支持 https 与 http 协议
- 在Chrome 浏览器中点击一个网址,Chrome会优先查找是否含有支持打开此网址的App Link 应用。有的话会直接通过应用打开。而国内的浏览器大多都没看到这个特性
参考资料
Create Deep Links to App Content
on