本文来自网易云社区

作者:刘新奇

移动互联时代,很多互联网服务都会同时具备网站以及移动客户端,很多人认为APP的能帮助建立更稳固的用户关系,于是经常会接到各种从浏览器、webview中唤醒APP的需求,显然,这对于前端开发人员来说,是一件很纠结的事。

唤醒APP

目前常见的主动唤醒APP方式有几种:

Url scheme

Url scheme是iOS,Android平台都支持,只需要原生APP开发时注册scheme, 那么用户点击到此类链接时,会自动跳到APP。比如

<!-- 打开考拉APP首页 --><a href="kaola://www.kaola.com">打开APP</a><!-- 呼叫号码 --><a href="tel://13788889999">打开拨号</a>

如果配置scheme的路径,并在app中识别,则可以直接打开APP特定页面,如下:

<!-- 打开考拉APP商品详情 --><a href="kaola://www.kaola.com/product/8342.html">打开APP商品详情</a>

上述的链接,需要考虑手机是否支持此Scheme: 支持:弹出相应程序; 不支持:错误处理情况因平台而异,部分app会直接跳错误页(比如Android Chrome/41,iOS中老版的Lofter); 也有的停留在原页面,但弹出提示“无法打开网页”(比如iOS7);iOS8以及最新的Android Chrome/43 目前都是直接停留在当前页,不会跳出错误提示。 总体来看, iOS的支持程度比Android好,iOS在实际使用中,除非明确禁止的(比如微信),很少碰到不支持的情况;Android平台则各个app厂商差异很大,比如Chrome从25及以后就不再支持通过js触发(非用户点击),设置iframe src地址等来触发scheme跳转。

Android intent

这是Android平台独有的,使用方式如下

intent:HOST/URI-path // Optional host #Intent; package=[string]; action=[string]; category=[string]; component=[string]; scheme=[string]; end;

这里的HOST/URI-path, 与普通http URL 的host/path书写方式相同, package是Android app的包名,其它参数如action、category、component不是很理解, 具体见文档 , 比如打开考拉 app的商品详情,代码如下

<!-- 打开考拉APP --><a href="intent://www.kaola.com/product/8342.html#Intent;scheme=kaola;package=com.kaola;end">打开APP</a>

如果手机能匹配到相应的APP,则会直接打开;如没有安装,则会跳到手机默认的应用商店,比如Google原生系统Nexus 5,将会直接跳到Google Play, 对于国内各厂商定制过的系统,则跳转到各自的默认应用商店,或者弹出商店供选择。 intent 比scheme相对完善的一点是,提供一个打开失败去向URL的选项,可以通过指定参数 S.browser_fallback_url 来指定去向URL。 比如如下的打开APP动作,如果打开失败,则跳转到app下载页,这对于国内的特殊网络环境,还是挺有用的。

<!-- 打开考拉APP --><a href="intent://www.kaola.com/product/8342.html#Intent;scheme=kaola;package=com.kaola;S.browser_fallback_url=http%3A%2F%2Fapp.kaola.com;end">打开APP</a>

HTTP URL订阅

Android Chrome平台独有,app中订阅自有内容相关的URL,在Chrome中浏览相关网页时,会自动弹出提示,让用户选择用浏览器还是APP打开,通用性有限。

iOS内置APP广告条

在页面Head中增加meta, 添加智能 App 广告条 (iOS 6+ Safari), 如下

<meta"apple-itunes-app"content"app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL"

可以自动判断是否已安装应用, 可惜只能用于iOS+Safari, 在第三方应用中就不行了。 效果如下:

20180907111836c01a5144-104e-452d-a474-aa068cd974f7.png

Android Chrome内置app安装提示

这个是Mobile Chrome 43 beta新加入的特性,在用户浏览某一个网站多次后,如果Chrome发现该站点有原生APP,则会提示用户下载原生APP,此项特性开发者无法干预,完全是Google的推荐行为,在项目中用不上,具体见新闻报道

实际应用中存在的问题

移动平台提供这么多唤醒APP的方法,但是功能还不够完善,以下情况JS无法检测并做处理:

  1. APP如果唤醒失败,很多时候都会跳到错误页,影响用户体验,而我们的需求很可能是需要跳到下载或者其它页。

  2. APP成功唤醒,页面无法直接得知,系统没有提供此类回调。

实际需求、解决方案

  1. 要在打开APP失败时,不能使当前页面跳到错误页,且打开失败时,有失败函数回调。

  2. 如果成功打开APP,有成功函数回调。 针对第一点,可以将打开动作放到iframe中,就算跳转失败仍能停留在当前页面;那剩下的问题就是如何检测APP是否成功打开; 网上常见解决方案如下:

    //创建一个隐藏的iframevar ifr = document.createElement('iframe');
    ifr.src = 'com.baidu.tieba://';
    ifr.style.display = 'none';document.body.appendChild(ifr);//记录唤醒时间var openTime = +new Date();window.setTimeout(function(){ document.body.removeChild(ifr); //如果setTimeout 回调超过2500ms,则弹出下载if( (+new Date()) - openTime > 2500 ){     window.location = 'http://exam.com/xxxx.apk';}
    },2000)

    此脚本利用了程序切换到后台时,计时器回调会被推迟的原理,如果APP被唤醒,那么此网页必然进入后台,如果用户从APP再切换回来,时间一般也会超过2.5s;如果app没有唤醒,则setTimeout 基本上会准时回调,时间不会超过2s。但是实际上,这个仅仅在iOS平台有效,Android由于是多任务的,应用放到后台,setTimeout 基本上还是会准时触发,所以这个逻辑还不够完善。

那Android 浏览器有没有方法检测应用是否进入了后台呢? 页面可见性API(Page Visibility API), 可以通过检测 document.hidden 或 document.[webkit|moz|ms]Hidden 来检查页面是否可见,或者订阅页面的visibilitychange事件; 如果仅仅应用在新版Android及Chrome上,这个是很美好的,对于老版本(<4.4)及Android Webview, 则不可用。

暮然回首,那人却在灯火阑珊处,setInterval,对,就setInterval, 如果设置比较小的运行间隔(<30ms),在浏览器或者webview中,应用切换到后台,setInterval 会被很明显的延迟执行,比如设置一个运行间隔20ms,总计运行100次的定时器,如果页面一直处于前台,则100次跑完,总耗时与20ms x 100 = 2000ms 不会有太大差异, 但页面在后台运行时,此时间会明显超过2000ms。 可以利用这一点来实现是否成功打开APP检测及回调。 代码如下:

function openApp(openUrl, appUrl, action, callback) {    //检查app是否打开function checkOpen(cb){        var _clickTime = +(new Date());        function check(elsTime) {            if ( elsTime > 3000 || document.hidden || document.webkitHidden) {cb(1);} else {cb(0);}}        //启动间隔20ms运行的定时器,并检测累计消耗时间是否超过3000ms,超过则结束var _count = 0, intHandle;intHandle = setInterval(function(){_count++;        var elsTime = +(new Date()) - _clickTime;            if (_count>=100 || elsTime > 3000 ) {clearInterval(intHandle);check(elsTime);}}, 20);}    //在iframe 中打开APPvar ifr = document.createElement('iframe');ifr.src = openUrl;ifr.style.display = 'none';    if (callback) {checkOpen(function(opened){callback && callback(opened);});}    document.body.appendChild(ifr);      setTimeout(function() {        document.body.removeChild(ifr);}, 2000);
}

iframe方式打开APP的问题:

  • Android Chrome/25+ 无法打开APP,所以最好是APP配合监听http URL 来实现。

  • iOS、Android平台,近期发现在没有安装对应app时尝试唤醒,有少数APP会连当前页面(iframe的父页面)也变成错误页的情况。

其它问题: 微信无法打开或者下载,打开APP这个基本无解,下载则只能让应用进驻应用宝市场,然后检测到在微信中运行时,跳转到应用宝页面下载。

网易云大礼包:https://www.163yun.com/gift

本文来自网易云社区,经作者刘新奇授权发布

相关文章:
【推荐】 如何通俗地解释云计算,看完这组图就明白了
【推荐】 网易对象存储NOS图床神器

从浏览器或者Webview 中唤醒APP相关推荐

  1. html唤醒手机app,怎么在html5中唤醒APP

    怎么在html5中唤醒APP 发布时间:2021-06-06 16:24:00 来源:亿速云 阅读:90 作者:Leah 怎么在html5中唤醒APP?相信很多没有经验的人对此束手无策,为此本文总结了 ...

  2. 微信浏览器中唤醒APP到指定页

    首先判断是在微信中,还是在浏览器中,如果在浏览器中,直接使用scheme url进行跳转,如果有app就直接进入app并通过页面隐藏事件监听,取消到下载页的跳转,没有唤醒则说明无app,到下载页. 在 ...

  3. Android中唤醒APP

    实例地址:唤醒APP <!DOCTYPE html> <html lang="zh"> <head><meta charset=" ...

  4. 在小程序内嵌的webview中唤醒手机地图app

    自己试的直接在内嵌的h5页面调用相关api打开地图发现并不生效,之后想到了一种由h5携带位置坐标参数跳到小程序,由小程序根据坐标打开地图app,果然可行. 如果想看**h5携带位置坐标参数**的话,可 ...

  5. H5页面唤醒app的方法

    iOS/Android 浏览器(h5)及微信中唤起本地APP 会遇到的问题: 如何解决未安装APP时的做好引导页 如何在微信中唤醒APP 在iOS9中如何处理universal link被用户误关的情 ...

  6. uniapp中唤醒支付宝,微信进行支付并返回app

    支付分为前端发起支付,和后端发起支付两种方式 1.在前端发起支付,uniapp给我们提供好了,可以使用的api接口. uni.requestPayment({provider: 'alipay',or ...

  7. iOS 浏览器唤醒app

    转自:https://www.jianshu.com/p/3936287bccdd 今天工作需要,要实现微信.QQ等扫描二维码,唤醒app,跳到指定页面的功能.我去,一想没有做过呀!好吧!今天有时间做 ...

  8. react native 实现浏览器唤醒APP并跳转指定页面

    推荐使用react-navigation导航器提供的Deep linking 功能来实现. 根据官方的例子来一步步实现: 假设我们要实现在浏览器上通过点击URI(mychat://chat/Eric) ...

  9. ionic 实现 应用内(webview中html页面点击) 和 应用外 (浏览器html页面点击) 打开本地安装应用...

    应用内(webview中html页面点击) : 应用内打开本地安装应用指的是webview里打开应用,需要2个步骤: 1: 需要下载一个cordova插件:com.lampa.startapp ,也可 ...

最新文章

  1. 100W无线充电方案文献调研 - 信息HUB
  2. 每天进步一点点:(11)进程优先级学习 nice
  3. 8、JavaScript深入浅出——数据类型
  4. selenium自动加载Flash
  5. IIC总线的操作时序
  6. git无法上传大文件
  7. 鹅厂员工平均月薪7万刷屏!公司每天赚9.5亿,养5.46万人
  8. call to a member funciton get() on null
  9. 移动开发者应注意的2012年五趋势
  10. SPSS对数据进行相关性和显著性分析
  11. 显示图片的html 页面,HTML基础——网站图片显示页面
  12. 一个基本c语言注释用什么字符串,C语言的词法规则京鸿智武 今天提纲:本文主要介绍了C语言中...
  13. CV领域的对比学习综述(下)
  14. Altium Designer --> 电气电路
  15. Hyperledger Avalon启动笔记
  16. CometOJ国庆欢乐赛 C两排房子 二分 D1 二分贪心 E贪心特判
  17. 首批小程序出炉,小游戏?
  18. 蓝桥杯练习之用Python解手算题
  19. 微信开发者工具报跨域问题,以及配置微信开发者工具可跨域
  20. 19篇顶会论文探索多模态情感识别前沿进展

热门文章

  1. 百合股份上市被暂缓表决:自主品牌收入占比仅约三成,曾多次因安全问题被处罚
  2. ffmpeg如何实现MP3转码g711a
  3. python变成exe1023无标题_GitHub - Qing1023/Python-100-Days: Python - 100天从新手到大师
  4. 计算机一级考试2018知识点,2018年全国计算机一级ms office考试内容
  5. (原创)IR2101应用笔记(IR2101)(全桥)(MOS)
  6. Innovus零基础lab学习全面复盘总
  7. 通过excel生成不同dimens文件来实现安卓屏幕适配
  8. 【mathtype】将公式左对齐(右对齐)
  9. c语言编写一个简单的答题系统
  10. mysql怎么限制输入男女_excel表格中如何限制只输入男女