Android Deeplink完成

在Android中,Deeplnk经过声明Activity的intent-filter来完成对自定义url拜访事件的捕捉。在有道背单词的项目中,咱们需要经过前端共享词单的方法,将词单共享给他人,并经过点击前端页面保藏按钮,完成调起客户端保藏词单的功用。
从前端经过自定义url的方法调起客户端这个功用本来一向都没有什么问题,直到最近有部分用户反应在某些浏览器下无法调起。下面咱们来看一下剖析查找问题的方法以及如何解决。 转载请注明来源「Bug总柴」

查看客户端deeplink装备

在AndroidManifest.xml文件中,对路由Activity装备如下:

<activity
            android:name=".deeplink.RouterActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:launchMode="singleTask"
            android:theme="@style/Theme.Translucent">
            <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="youdao.com"
                    android:scheme="recite"
                    android:pathPattern=".*"/>
            </intent-filter>
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".home.ui.MainActivity" />
        </activity>

里边比较重要的部分是intent-filter中的data装备,查看后发现装备正常,能够正常阻拦到 recite://youdao.com/.*的所有恳求。
转到RouterActivity经过断点调试,发现并没有抵达。然后能够确认是浏览器调起的时分发生了反常。

tips: adb 指令同样能够启动deeplink进行测验

Android-Deeplink跳转失败问题修复

剖析浏览器对deeplink处理

经过用户反应,主要集中是在UC和华为自带的浏览器点击前端页面的【保藏词单】无法调起有道背单词
一起咱们在chrome上面发现经过deeplink只有第一次会跳转到运用,往后几次都是没有任何相应,的确有点百思不得其解。
经过查找资料,发现了chrome的一个对Android Intent处理的介绍
Android Intents with Chrome
里边说到

One scenario is launching an app when the user lands on a page, which you can achieve by embedding an iframe in the page with a custom URI-scheme set as the src, as follows: . This works in the Chrome for Android browser, version 18 and earlier. It also works in the Android browser, of course.

The functionality has changed slightly in Chrome for Android, versions 25 and later. It is no longer possible to launch an Android app by setting an iframe’s src attribute. For example, navigating an iframe to a URI with a custom scheme such as paulsawesomeapp:// will not work even if the user has the appropriate app installed. Instead, you should implement a user gesture to launch the app via a custom scheme, or use the “intent:” syntax described in this article.

翻译一下,大约的意思就是之前经过没有用户主动操作就翻开app的行为在chrome25版别及之后会被禁止。开发者必须经过用户操作来触发跳转运用的行为。目前chrome的版别都现已68了,证明这个规矩现已由来已久。抱着试试看的姿态,开端查找是否是前端的代码有问题。 经过chrome inspect,捕捉到前端代码果然有一处疑似iframe的运用

Android-Deeplink跳转失败问题修复

Android-Deeplink跳转失败问题修复

随后经过对前端代码debug,果然有走了这段逻辑

Android-Deeplink跳转失败问题修复

证据确凿,能够找前端大神反应了。经过了解,的确是之前有改动过这部分的代码,运用了iframe来处理deeplink的翻开。处理的办法也相对简略,将iframe换成href来做跳转处理就能够了。

测验

最后咱们对国内的浏览器试了一下deeplink是否生效

UC浏览器

会弹出一个运用翻开提示,假如用户本次没有【答应】操作,则浏览器下次会阻拦翻开运用行为,没有任何提示,不知道这是一个bug仍是故意为之。点击【答应】后能够跳转运用

Android-Deeplink跳转失败问题修复

QQ浏览器

同样会弹出运用翻开题型,假如用户本次没有【翻开】,下次用户操作仍是会继续提示。点击【翻开】后能够跳转运用

Android-Deeplink跳转失败问题修复

360浏览器

行为与QQ浏览器相似,每次都会提示

Android-Deeplink跳转失败问题修复

猎豹浏览器

行为与QQ浏览器相似,每次都会提示

Android-Deeplink跳转失败问题修复

一加系统默许浏览器

行为与QQ浏览器相似,每次都会提示

Android-Deeplink跳转失败问题修复

搜狗浏览器

没有提示,直接跳转到app

chrome

行为与搜狗浏览器相似,没有提示,直接跳转app

测验结果除了UC浏览器第一次不点击跳转之后会跳转不了之外, 其他浏览器跳转app问题得到解决。

结语

经过这次查deeplink跳转的问题,收获了两点常识。

  • 一个是前端运用iframe来处理deeplink跳转会有问题
  • 二个是除了选用
"scheme://host/path"

这种deeplink方法之外,还能够选用

"intent://about/#Intent;action=[string];scheme=[string];package=[string];S.browser_fallback_url=[encoded_full_url];end"

的方法来触发运用intent的恳求拜访。

一起,在处理deeplink的规矩里边,体会到了一条准则:

  • 最短途径处理准则

意思就是刚开端的时分,deeplink处理的逻辑要从根目录开端进行。比如有一个保藏词单的需求,没有运用最短途径准则可能会规划成这样

recite://youdao.com/bookId?&action=collect

对应的处理是假如action为collect就保藏词单。这个时分需求假如改成默许进来不需要保藏就非常尴尬了。由于关于旧版别罢了,只认有action=collect才会处理,那就意味这假如想对默许的recite://youdao.com/bookId只是查看不保藏的需求,关于旧版别就没办法完成,会出现兼容性问题。
而最短途径处理准则,意思就是在开端的时分,尽量对最短的途径行为进行处理,详细到上面的例子,关于保藏某个词单的需求,咱们能够规划deeplink为

recite://youdao.com/bookId?&action=collect

然后咱们对 recite://youdao.com/bookId以及recite://youdao.com/bookId?&action=collect 都处理成保藏词单。上线之后,假如想修改默许参数行为,就能够直接改对 recite://youdao.com/bookId 的处理,这样关于旧版别仍然是能够执行的保藏行为,关于新版别就能够对应新的逻辑