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

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

现状
H5页面增加自定义协议拉起APP在移动端来讲是个非常特色的交互,而且也可以极大提高用户体验,基本是每个应用的标配。通过

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

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

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

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,跳转到指定页面就简单了。当然这种做法有限制,比如参数不能缺失,也不能支持其他平台分享过来的链接。如果应用的不同平台能统一跳转协议也是很不错的。

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

首先我们知道系统的很多弹框都是用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呢?

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

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

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

  1. iOS/Android 微信及浏览器中唤起本地APP

    title: iOS/Android 微信及浏览器中唤起本地APP date: 2017-05-10 10:19:20 tags: 需求概述 分享应用活动链接已经成为手机应用一个非常重要的推广传播形式 ...

  2. iOS/Android 微信及浏览器中唤起本地 APP

    需求概述 分享应用活动链接已经成为手机应用一个非常重要的推广传播形式.为了提高转化率,就需要让用户不管是在微信或者是浏览器中,都能在点击链接后, 唤起本地的 app 后 , 跳转到指定页面 . 虽然这 ...

  3. android微信下拉出现小程序,仿新版微信的小程序下拉栏

    原标题:仿新版微信的小程序下拉栏 本项目会对金融交易软件中存在的各种View进行模仿绘制,提供详细的实现思路,收集整理相关算法.文档以及专业资料. https://github.com/scsfwgy ...

  4. Android微信页面缓存清理,安卓微信浏览器缓存如何清理

    前言: 缓存这个问题的出现,真真切切的感受到微信浏览器这鬼东西对前端程序员充满了恶意,捋捋自己的发型,甚是恐慌(顿时有种想转php的冲动,有木有). 解决方案: 出现缓存问题导致用户出现很多车祸现场( ...

  5. android微信下拉出现小程序,Android 仿新版微信的小程序下拉栏

    Android 仿新版微信的小程序下拉栏 上周微信更新到了 6.6.1 版本,加入了微信小游戏.朋友圈都在玩跳一跳.而且现在微信把最近用过的小程序放到了首页顶部,轻轻下拉就可以快速访问了.可以看下效果 ...

  6. php判断是不是iphone访问,php基于http协议访问,判断访问来源iphone,android,微信浏览器,pc电脑...

    当我们采用php作为服务数据端口,为移动端,pc端提供数据接口的时候,可能会要求记录接口访问的来源是来之哪里. 例如:生成订单,可能就需要记录,以便做一些数据分析,为运营和推广提供一些数据支持. 代码 ...

  7. 打造Android微信朋友圈下拉刷新控件

    打造Android微信朋友圈下拉刷新控件> 转载于:https://www.cnblogs.com/zhujiabin/p/5707789.html

  8. 禁止微信浏览器的下拉滑动

    禁止微信浏览器的下拉滑动 解决思路: 1 先禁止body的滚动事件 2 再给需要scroll的元素加上自定义的滚动事件 注:加入此代码后要给需要scroll的元素加上.scroll的class var ...

  9. android仿微信发布动态功能,Android GridView扩展仿微信微博发图动态添加删除图片功能.pdf...

    Android GridView扩扩展展仿仿微微信信微微博博发发图图动动态态添添加加删删除除图图片片功功能能 这篇文章主要为大家详细介绍了Android GridView扩展仿微信微博发图动态添加删除 ...

最新文章

  1. 初始化栈、入栈、出栈、栈空、数制转换函数和主函数,实现1348转换成8进制的功能。
  2. ACE反应器(Reactor)模式
  3. 【AI白身境】深度学习中的数据可视化​​​​​​​
  4. OpenCV连接的组件Connected Components的实例(附完整代码)
  5. perl 处理文件路径的一些模块
  6. Spring Aware接口
  7. python windows自动化 爬虫_使用Python实现自动化截取Windows系统屏幕
  8. 测试用例编写注意事项
  9. matlab rgb2ntsc函数,matlab 颜色模型之间的转换
  10. 《基于ArcGIS的Python编程秘笈(第2版)》——第1章 面向ArcGIS的Python语言基础
  11. 一篇文章快速搞懂排序算法(含实现源码)
  12. 计算机的硬盘 u盘启动,U盘启动和硬盘启动两种不同教程步骤
  13. linux 内核模块 定时器,linux内核定时器__backup_timer_hour_struct_定时器_模块__169IT.COM...
  14. 在 Google 工作十年后的感悟
  15. 继电器控制电路原理解析说明
  16. 星城,你准备好了么?Greenplum走进长沙技术研讨会
  17. STORJ 有实际应用
  18. 强烈分享两个功能强大,可以极大提高工作效率的软件
  19. 微信小程序设置解锁密码
  20. DeepFM:深度学习算法助力华为应用市场APP推荐

热门文章

  1. prim算法求最小生成树_克鲁斯卡尔算法(Kruskal算法)求最小生成树
  2. 从蛋白质结构到功能的生物信息学研究 From Protein Structure to Function with Bioinformatics PDF
  3. Origin一键复制粘贴,也能批量更改图片格式
  4. 浮点数和整数的区别python_Python中整数和浮点数
  5. mastercam2018安装教程
  6. 计算机视觉与深度学习 | ORB特征提取:基于OpenCV+Python(附代码)
  7. Error: Could not find or load main class CLASS的解决方法
  8. dueros模拟测试没有请求后台_实战 | 用手写一个骚气的请求合并,演绎底层的真实...
  9. 学习分布式不得不会的CAP理论
  10. listview mysql查询_Sqlite 数据库分页查询(ListView分页显示数据)