突破Android微信微博浏览器限制直接拉起应

前言
众所周知,微信微博等应用为了防止用户在使用过程中跳出程序自己,对浏览器里面的自定义协议打开作了限制。这个需求很正常,是个产品经理都能想到。前端

但做为微博微信这种体量的应用来讲,我要多说几句:“右上角使用浏览器打开”成了每一个前端开发者的标配,能够说浪费了多少的人力和财力,亦能够说造就了多少的就业机会。APP作得越大,越应该有社会责任感。这种简单粗暴的方式让千千万万的开发者感到心痛,无语。请把选择权交还给用户,既然用户点开了浏览器,咱们也理解大家为本身APP操碎了心,是否能够作成弹框再让用户选择:是否打开xx应用?android

现状
H5页面增长自定义协议拉起APP在移动端来说是个很是特点的交互,并且也能够极大提升用户体验,基本是每一个应用的标配。经过git

<a href="orpheus://playlist/19850925" />

就能够在点击的时候触发拉起应用(前提是系统已经安装支持这个协议的应用,这个例子里面叫orpheus。github

微信微博浏览器如何封禁自定义协议呢?web

public boolean shouldOverrideUrlLoading(WebView view, String url)

Android的WebView控件有个叫shouldOverrideUrlLoading的回调,任何连接的打开(包括http和各类自定义协议)都会先走这个回调,交给应用自己来判断是否要接手处理,return true表示接手,WebView就再也不处理,不然WebView就继续处理。
处理自定义协议其实不是WebView自带的功能,而是须要开发者在这个回调里面去实现。好比相似这样:浏览器

Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

那微信微博与其说拦截,倒不如说他们只判断了本身白名单的协议而后放行。微信

方法
除了苦逼的前端开发者实现个右上角用浏览器打开功能,还有一些思路能够参考。
1.假装成白名单协议
咱们知道微信有白名单,好比合做的京东就能够直接打开,因此咱们能够把咱们的应用作成京东的协议名称,这样若是用户手机上面没有安装京东,就能直接拉起你的应用。若是安装了京东,则会跳出弹框让用户选用哪一个打开(这个是系统行为)。这个方案有点猥琐。
2.用右上角浏览器打开的时候能够把本身应用置顶。咱们知道右上角用浏览器打开其实也是微信调用了上述那段代码,只不过协议固定是http或者https。固然微信仍是作过修改的,第一个位置固定放QQ浏览器(即便没有安装)。除了第一个位置剩余是按系统读取的顺序排列的。由于Intent实际上是有优先级的,那如何利用系统Intent优先级来让本身的应用在这个弹框里面排在第二位呢?异步

首先应用固然要实现支持http/https协议,否则你都不会出如今这个页面里面。而后给Intent配置域名信息,以下:
这样在本身域名匹配上面排列就会靠前。甚至你能够在这个协议实现上面,直接将http/https的url转换成native参数,直接打开native页面,省去中间webview跳转。
若是url转成native参数有点麻烦,你能够在分享连接的时候带上Intent.toUri做为参数,这样后续收到url以后直接Intent.parseUri获得Intent,跳转到指定页面就简单了。固然这种作法有限制,好比参数不能缺失,也不能支持其余平台分享过来的连接。若是应用的不一样平台能统一跳转协议也是很不错的。ide

突破
还能再作点什么吗?答案是确定的。这个突破不是绝对的,而必需要求程序在后台有个活着的进程。若是你感兴趣请继续往下看。url

首先咱们知道系统的不少弹框都是用Activity实现的,他能够弹出在任何应用的任意一个界面上面,说到底这个弹框也是属于系统的某个应用,好比手机管家等等。那为何一个APP在后台能启动的一个Activity能够在任意另一个APP上面呢?
秘密就在于Intent.FLAG_ACTIVITY_NEW_TASK这个flag,咱们知道若是context.startActivity里面的context不是Activity,是必需要加这个flag才能启动成功。
第一个问题解决了,在android上面是有可能让咱们的一个页面呈如今微信之上。那如何触发调用呢?聪明的你可能想到了,对,就是在H5页面上面给本身应用发请求。
在本身应用里面实现一个很是简单的HttpServer,接听来自本机的请求,一旦收到请求则直接使用Intent.FLAG_ACTIVITY_NEW_TASK拉起Activity。

惋惜是当你去尝试在H5页面里面给127.0.0.1或者localhost发请求的时候发现根本收不到,由于狡猾的微信微博浏览器限制了这两个本机地址,限制方式也很简单,仍是刚才的shouldOverrideUrlLoading判断下url的host是否是这2个就能够了。因而聪明的你确定又想到了绕过的方式。没错随便弄个域名解析到127.0.0.1上面。

因而整个链路快要完成了,剩下就是一些额外的工做,好比客户端和H5页面约定一串端口,按照约定顺序依次遍历直到请求获得响应。由于端口有可能被占用。而后再约定一个加解密方式以防止被恶意攻击。

这种方式有没有可能被微信微博封禁呢?由于原理都是系统实现,惟一的可能点就是对域名进行解析发现仍是127.0.0.1的话继续拦截。但这个作法有点代价,首先shouldOverrideUrlLoading不能阻塞调用,这样就影响正常使用了。若是作成异步的就须要新增一个dns查询服务,这个彻底看xx产品经理的意思。可能原来不会考虑,这篇文章发出去了用的人多了估计会考虑了。。。请给开发者留一条活路。

写到这里我猜你确定在想,程序活着这个条件是个硬伤,虽然多迈出了一步但仍是受限很多。因而又引出了一个古老的话题:如何程序保活。这不是本篇文章的范畴,我也不推荐你去研究和花费心思,这也不是一个正确的方向。
最后给一个提示:你的公司有没有兄弟产品,亦或是有没有使用一个公共的SDK呢?

更多细节请参考我给的例子,点击这里连接能够参看。有任何问题欢迎留言讨论,喜欢就点赞,请支持原创。

更多文章请关注微信公众号:安卓之美

相关文章
相关标签/搜索