Android 通过短信跳转到特定 App -- Android App Links

为什么会有这篇文章:

在Android 6.0 之前,用户如果在短信中,点击一个链接「https://zd.badmask.com」,想要跳转到某 App 中,之前都是弹出符合这个意图过滤器的应用,大概会有浏览器、某App等,进而由用户选择,第一种是直接进入app,行为符合预期;第二种会选择打开浏览器「这也是大部分用户的行为」,呈现H5页面,通过H5页面,再进入App。
这个交互对于产品和用户来讲太复杂了,最期待的行为,点击之后,用户没有其他的选择权,直接定位到App。

先看效果:

不使用 Android App Links,会出现这样的行为:

不使用 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 官方截图:
developer.android.com截图
如何实现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

检验链接是否可用.png

第五步:给你的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 是不会被识别为链接的,自然就不可点击;

  1. 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>

官方解释如下


官方解释.png

数字资产链接把你在 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/简书 等平台,我测试了一下不可行,原因如下:

  1. 微博在我发送的内容里,发布成功后,内容更改为短链接的形式;
  2. 简书平台中输入的链接的内容,直接不可点击;
  3. 在 QQ/微博/更美 等 App中,即使发送的内容可以跳转,但基本都是跳转到App 中的某个固定页面 ,来呈现此 H5链接的内容...
    不过 这个功能在做商务合作的时候,让合作方在其 App 中加入相应代码,跳转到我们的 App 里是完全 ok 的,所以还是具体产品层面的意义.

参考链接:
Android 官方
Android M的App Links实现详解
Android AppLinks 接入

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容