为什么会有这篇文章:
在Android 6.0 之前,用户如果在短信中,点击一个链接「https://zd.badmask.com」,想要跳转到某 App 中,之前都是弹出符合这个意图过滤器的应用,大概会有浏览器、某App等,进而由用户选择,第一种是直接进入app,行为符合预期;第二种会选择打开浏览器「这也是大部分用户的行为」,呈现H5页面,通过H5页面,再进入App。
这个交互对于产品和用户来讲太复杂了,最期待的行为,点击之后,用户没有其他的选择权,直接定位到App。
先看效果:
不使用 Android App Links,会出现这样的行为:
使用 Android App Links,能直接跳转到对应的APP:
首先需要了解的概念:Deep linking 与 Android App Links
Deep linking:
深度链接,指将用户直接带到应用中特定内容的网址,Android中可以直接通过添加意图过滤器,将用户吸引到正确的活动。
缺点:如果用户安装了其他应用程序可以处理此意图,例如上图中的短信,并且手机安装的app中有如下代码,则单击后出现选择app的对话框,询问用户使用哪个应用程序。
<activity
android:name=".module.personal.ui.SplashActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait">
<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:host="zd.badmask.com" android:scheme="https" />
</intent-filter>
</activity>
Android App Links:
Android 6.0 及更高版本上的 Android App Links允许应用程序将自己指定为给定链接类型的默认处理程序。
优势:
安全且具体,链接必须经过google网站的关联方法检测,没有其他应用可以使用您的链接;
无缝的用户体验,如果未安装对应的App,则会跳转到浏览器,并显示该网址的内容,没有404,没有错误;「重要」
Android Instant Apps 支持;
通过Google搜索吸引用户;
Android 官方截图:
如何实现Android App Links
第一步:在 AndroidManifest.xml 文件中,加入 Intent Filter,
一个intent-filter标签中,暂时不要加入其他data标签,其中 scheme 必须为 https,但是 data 标签的 host 内容随意,稍后解释
<activity
android:name=".module.personal.ui.SplashActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait">
<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="zd.badmask.com" android:scheme="https" />
</intent-filter>
</activity>
第二步:创建json文件
title | require |
---|---|
sha256_cert_fingerprints | 你app的所用的签名文件的 SHA256 值,可以自己生成app的签名文件,即 keystore,推荐命令行方式,这样显得比较帅,哈哈 |
package_name | App 的 applicationId |
文件命名 | 命名为 assetlinks.json ,不可更改! |
其他的内容不要改动!!!
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "替换为 App 的 applicationId",
"sha256_cert_fingerprints": ["ED:41:94:D6---:8A:1B:F4"]
}
}]
第三步:将这个json文件,放到指定路径下
https://data标签中 host 的值/.well-known/assetlinks.json
很多博客把 assetlinks.json 文件的内容和名字搞错了,我也是很无语了,浪费了我很多时间啊~
关于https,需要注意SSL证书的问题,必须是可信任的证书
第四步:检验放到指定路径下的文件是否已生效
可通过这个链接检验:https://developers.google.com/digital-asset-links/tools/generator
第五步:给你的App打包,用第二步的keystore文件,生成Apk文件「就是可以发布到应用市场的 apk 文件」,安装到手机上,发送短信至手机,内容大概是「hello,test Android App Links,https://zd.badmask.com」
注:链接的内容是上文中 data 标签的 scheme 和 host 的值
这个时候就初步成功了,即使我上面还留有几个疑问。
FAQ
为什么intent-filter中,scheme一定要用https?
1.若想在短信等文本中,可以点击此链接,首先就要被识别为链接的形式,比如「https://zd.badmask.com/diary_book/13056043/」;用其他的 scheme 和 host 比如 badmask://zly 是不会被识别为链接的,自然就不可点击;
- Android App Links 对于链接的校验很严格,必须支持https才可以;
一个intent-filter标签中,如何加入其他data标签?
啥都不说,先上代码
<activity
android:name=".module.personal.ui.SplashActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait">
<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:host="launch"
android:scheme="https" />
<data
android:host="zd.badmask.com"
android:scheme="https" />
</intent-filter>
</activity>
官方解释如下
数字资产链接把你在 intent-filter 中列出的子域名堪称唯一、独立的域名,所以如果列出多个子域名,那必须在每个子域名中发布一个有效的 assetlinks.json 文件,增加了无故的工作量.
如果一个 Activity 想被多个 intent-filter 识别,而且不更改之前的 assetlinks.json 文件,可以看下面的代码:
<activity
android:name=".module.personal.ui.SplashActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:theme="@style/GMThemeWithBackground">
<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:host="launch"
android:scheme="badmask" />
</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:host="zd.badmask.com"
android:scheme="https" />
</intent-filter>
</activity>
//写两个 intent-filter 标签,之前定义的协议「badamsk://launch」依然可用.
//不至于因为增加一个 App Links 的功能而影响整体~
目前只支持跳转到指定的app,那么如果跳转到指定app的指定页面?
对应我例子中这个 https://zd.badmask.com 域名的,一定是App的启动页:
1.从产品角度讲,在 App 未启动的情况下,这可能会关联一系列与业务相关的初始化操作,初始化操作没有完成,可能会导致一些列问题,所以只能先打开这个页面,然后再跳转到指定的其他页面;
2.从技术角度讲,如果直接用 https://zd.badmask.com 对应一个页面,那么每个页面都需要对应的一个域名,不合理
好,那么只能把 https://zd.badmask.com 域名定位到启动页,但是我怎样跳转到App 的指定页面呢?
理想情况下,想写成下面这个样子,跳转到A页面之后,再跳转到url对应的另一个页面,解析参数就可以了,好,这只是想象...
https://zd.example.com?url=badmask://example
在短信中,url=badmask://example 这部分并不能被识别为链接,只有被识别为链接才能被跳转,所以放弃吧,用这种 https://zd.example.com/detail/1212/ ;
在「https://zd.example.com」这个协议对应的页面中去解析「detail/1212/」;
不过有一个问题需要注意,如果是 Android 6.0 以下的手机,或者手机上没有安装 app,那么会跳转到浏览器中,并且加载此网址对应的页面,所以为了避免用户访问404,在相应的路径下需要部署H5的代码。
Intent intent = getIntent();
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri uri = intent.getData();
if (uri != null) {
uri.getPath();//调用这个方法,拿到「detail/1212」,然后去解析具体的业务
//当然可以查看API调用其他方法
}
}
Android App Links的链接如果用短链接的形式,能不能跳转成功?
不能,短链接的原理都是重定向,而「https://data标签的内容/.well-known/assetlinks.json 」这个网址的要求不能被重定向.
Android App Links的链接如果出现在 Android 6.0以下的手机中 or 未提前安装 App,会有什么表现?
与 Deep linking 的表现类似,不过是直接跳转到浏览器,呈现此网页,所以此功能在 Android 6.0 以下 or 未安装 App 的手机上通用.
如果你只看到这里,就小看了Android App Links,还可以从 A app 跳转到 B app!!!
直接上代码,在另一个App中,写入如下代码:
textView.setMovementMethod(LinkMovementMethod.getInstance());
String a2 = "<a href='https://zd.badmask.com/diary_book/13056043/'>https://zd.badmask.com/diary_book/13056043/</a>";
CharSequence cs = Html.fromHtml(a2);
textView.setText(cs);
此时会显示为高亮显示的TextView,点击可直接跳转到https://zd.badmask.com/diary_book/13056043/ 该网址对应的页面。
不过这部分是我自己写在另一个 app 的代码,如果想直接应用在比如 微博/微信/QQ/简书 等平台,我测试了一下不可行,原因如下:
- 微博在我发送的内容里,发布成功后,内容更改为短链接的形式;
- 简书平台中输入的链接的内容,直接不可点击;
- 在 QQ/微博/更美 等 App中,即使发送的内容可以跳转,但基本都是跳转到App 中的某个固定页面 ,来呈现此 H5链接的内容...
不过 这个功能在做商务合作的时候,让合作方在其 App 中加入相应代码,跳转到我们的 App 里是完全 ok 的,所以还是具体产品层面的意义.
参考链接:
Android 官方
Android M的App Links实现详解
Android AppLinks 接入