隐式 Intent 已经不是你以为的 Intent 了

企业动态
如果你的 App 内,有使用到隐式 Intent 去与其他 App 交互。例如,分享一个链接,当你的系统升级到 Android M(Api level 23) 之后,你就需要小心了,它可能并不能按照你的意愿去执行你想执行的任务。

 一、前言

如果你的 App 内,有使用到隐式 Intent 去与其他 App 交互。例如,分享一个链接,当你的系统升级到 Android M(Api level 23) 之后,你就需要小心了,它可能并不能按照你的意愿去执行你想执行的任务。

举个例子,你想分享一个链接,而每次都想让用户主动去选择一个,但是有时候这个操作并不能如愿,如果用户主动指定了某个 App 打开这个 链接,你的 App 将直接使用用户指定的 App 打开这个链接(其实是有例外情况的,后面说)。

二、Android M 改变了什么

一般我们想要分享一个链接出去,直接使用 隐式 Intent 即可。

在 Android M 之下,它会调起系统内,所有符合的 App 供用户选择一个合适的去打开。

可以看到,默认会弹出一个选择器,让用户选择一个 App 来处理。这没什么好说的,是一个常规的操作,应该几乎所有的 Android 开发人员,都是不陌生的。

除了这个系统的选择器,我们也是可以在代码中,去查询到符合 Intent 过滤要求的 App 的。需要使用 PackagemManager.queryIntentActivitys() 方法来进行查询,上面的 demo 中,也通过 Log 打印出了它的输出。

看输出,和我们选择器中的是一致的。

但是,这一切在 Android M 就开始改变了。

Android M 推出了 App Links 是的概念,系统将通过你的配置的网址进行身份验证,如果通过验证,你需要打开的链接,将直接使用你的 App 来打开,而不是直接跳转到一个浏览器,这个过程是不会向用户询问的。但是 App Links 依托于 Google 的服务,所以国内开发者应该享受不到它的便利。

但是处理通过网站的服务器来进行身份验证之外,还可以在设置页面中,对默认的程序进行设定。

路径是:系统设置 → 应用 → 应用程序 → 默认打开

例如这里打开了 Google + 这款 App 的默认打开页面。

可以在『打开支持的链接』中,选择是否默认打开使用它来完成打开链接的操作。

一旦选择了『在此应用中打开』,在去运行上面的程序,你将直接使用 Google+ 打开你的链接,而用户将失去选择的权利,除非用户将这里重新设置为『每次都询问』。

三、例外情况

实际上,这也是存在例外的情况的。

3.1 过滤会先校验 domain

下面是一个标准的 URL 格式:

scheme://host.domain:port/path

这种隐式 Intent ,优先考虑能与 domain 匹配的 App,这是系统内部的一个优先级策略。

例如,现在在我的系统中,有一款 HiitTime 的 App,它设定了一个 m.hiittime.com 的链接支持。

再修改前面提供的 Demo,只是把链接指向了它。

这样的情况下,哪怕我们也将 Google+ 设置为『在此应用内打开』,它最终也是允许用户去选择 HttiTime 这个 App 来处理的。

3.2 系统 App 优先级高

前面 HiitTime 的例子可以看到,实际上我是没有指定 Chrome 来处理的,但是选择器中,实际上是会有 Chrome 的选择的,这个我暂时没有发现可以去掉它的办法。

而在 Chrome 的默认开打的选择页面中,也是无法操作的,我只能理解为它对系统 App 做了特殊的保护处理。

四、辟谣

之前看到有人说可以在对 Intent 的 Uri 只设定 scheme ,例如,’http://‘ 然后后面什么都不跟,这样系统就会列出所有的浏览器供你选择,然后我们就可以在选择列表中,手动指定打开的 App ,这样就可以很好的打开它了。

但是实测,这样是行不通的,当设置了 Google+ 『在此应用内打开』的情况下,依然会直接使用 Google+ 来完成我们的操作,所以这个操作是不成立的。

但是也提供了另外的一个思路,我们实际上是可以通过 PackageManager 拿到系统中安装的 App 的,而通常我们需要分享打开的 App 就那么多,所以我们可以以穷举的方式,筛选出需要的 App ,自己来定义这个选择器,然后指定对 Intent 指定 PackageName 就可以完成对指定 App 的分享,而绕过『在此应用内打开』的设定。

这只是一个思路,没有实际实验,但是应该可行。

五、小结

如果你的 App 内,有这种隐式的操作,就应该检查一下是否在这样的情况下,依然能完成我们如期的功能。

【本文为51CTO专栏作者“张旸”的原创稿件,转载请通过微信公众号联系作者获取授权】

戳这里,看该作者更多好文

 

责任编辑:武晓燕 来源: 51CTO专栏
相关推荐

2013-03-28 09:07:37

Android开发Intent机制

2018-08-03 16:41:23

数据房子存量

2017-10-13 16:55:12

Android

2014-07-15 10:16:02

AndroidIntent

2009-04-03 08:21:37

AndroidGoogle移动OS

2013-01-10 14:54:48

Android开发组件Intent

2017-10-20 16:03:25

IntentUri序列化

2013-01-10 15:36:44

Android开发组件Intent

2010-08-18 10:13:55

IntentAndroid

2009-04-03 08:26:02

2015-08-11 09:51:06

谷歌重组Alphabet

2016-06-13 15:53:34

SDN开放网络操作系统ONOS

2010-02-07 10:40:55

Android Int

2017-08-08 11:18:26

AndroidIntent原生

2010-01-25 16:52:22

Android Int

2013-05-27 14:06:14

Android开发移动开发Intent机制

2016-12-13 22:38:40

2011-05-30 14:00:35

Android Activity Intent

2010-01-25 14:25:33

Android Int

2012-07-23 13:22:42

Intent Filt安全Android
点赞
收藏

51CTO技术栈公众号