H5 页面唤起APP或跳转到下载APP的某个链接地址。总结如下:

在 IOS 中, 系统版本在 8 以下时,可以监听页面的 pagehide / visibilitychange 事件。 系统版本大于 8 以后,可以使用 universal Link 或 URL scheme 进行跳转。

// IOS 的唤起
function vForIOS(urlScheme, storeURL, fallback, universalLink) {
    var tid = deferFallback(TIMEOUT_IOS, storeURL, fallback);
    if (parseInt(os.version, 10) < 8) {
        bindPagehideEvent(tid);
    else {
        bindVisibilityChangeEvent(tid);
    }
    if (parseInt(os.version, 10) > 8 && os.name == 'iOS') {
        // 通过universalLink
        if (universalLink === undefined) {
            universalLink = urlScheme;
        else {
            clearTimeout(tid);
        }
        vLocation(universalLink);
    else {
        vIframe(urlScheme);
    }
}

在安卓中, 安卓版本 4.4.4 以上机型的安卓自带浏览器、chrome 浏览器,需要通过 intent 跳转 【详情请见 https://developer.chrome.com/multidevice/android/intents】,其他浏览器大多数可通过 url scheme 唤起。但由于唤起APP后浏览器并无回调事件,我们很难判断是否已成功拉起APP,比较通用的解决办法是判断计时器是否变慢,若APP启动浏览器最小化入后台将会导致计时器变慢,即为实际事件间隔大于理想时间间隔。若未变慢则判断为未成功拉起APP,则跳转至下载地址。此判断代码如下:

function deferFallback(timeout, storeURL, fallback) {
        var clickedAt = new Date().getTime();
        return setTimeout(function () {
            var now = new Date().getTime();
            if (isPageVisible() && now - clickedAt < timeout + INTERVAL) {
                fallback(storeURL);
            }
        }, timeout);
    }

安卓系统中,不同浏览器对唤起APP有严重的兼容性问题,主要处理方案有以下几种:

  1. 通过改变 window.location.href
  2. 通过创建 iframe 并为其 src 赋值
  3. 通过 intent
  4. 通过制造不可见 a 链接,并触发点击时间
// 打开页面的方式可能
    // 1. 通过改变location
    function vLocation(urlScheme) {
        window.location.href = urlScheme;
    }
    // 2. 通过ifreame
    function vIframe(urlScheme) {
        setTimeout(function () {
            var iframe = createHiddenIframe('appLauncher');
            iframe.src = urlScheme;
        }, 100);
    }
    // 3. 通过intent
    function vIntent(launchURI) {
        if (browser.name == 'Chrome') {
            move();
        else {
            setTimeout(move, 100);
        }
 
        function move() {
            // window.top.location.href = launchURI;
            window.location.href = launchURI
        }
    }
    // 3. 通过添加出发alink
    function vAlink(launchURI) {
        var aLink = document.createElement("a");
        aLink.setAttribute("href", launchURI);
        aLink.style.display = "none";
        document.body.appendChild(aLink);
        var event = document.createEvent("HTMLEvents");
        event.initEvent("click", !1, !1);
        aLink.dispatchEvent(event)
    }
  
    // IOS 中的 可见性事件
    function bindPagehideEvent(tid) {
        window.addEventListener('pagehide'function clear() {
            if (isPageVisible()) {
                clearTimeout(tid);
                window.removeEventListener('pagehide', clear);
            }
        });
    }
 
    function bindVisibilityChangeEvent(tid) {
        document.addEventListener('visibilitychange'function clear() {
            if (isPageVisible()) {
                clearTimeout(tid);
                document.removeEventListener('visibilitychange', clear);
            }
        });
    }
 
    function isPageVisible() {
        var attrNames = ['hidden''webkitHidden'];
        for (var i = 0, len = attrNames.length; i < len; i++) {
            if (typeof document[attrNames[i]] !== 'undefined') {
                return !document[attrNames[i]];
            }
        }
        return true;
    }

已知的浏览器兼容问题:

  1. 上述 chrome 和 Android Browser 可以使用 intent 的方式拉起 app
  2. QQ 浏览器 无法正确判断计时器是否变慢
  3. 微信浏览器 和 百度浏览器 无法唤起 app 除非加入其白名单
  4. 安卓4.4.4以前的 UC浏览器无法正确识别为 【安卓系统】需要单独设置判断条件

另: 研究京东唤起APP的代码时,其对百度浏览器做了如下操作,但我们对此的尝试并为成功,如下为其代码, 希望对后续研究此项的同学有帮助 :

function ai(aA) {
    var aD = ay(aA, true);
    var aB = aA.universalLinksUrl + "/ul/ul.action?" + aD;
    if (navigator.userAgent.indexOf("baidubrowser") >= 0) {
        window.location.href = aB
    else {
        var az = document.createElement("a");
        az.setAttribute("href", aB);
        az.style.display = "none";
        document.body.appendChild(az);
        var aC = document.createEvent("HTMLEvents");
        aC.initEvent("click", !1, !1);
        az.dispatchEvent(aC)
    }
}

H5 唤起 APP的解决方案的更多相关文章

  1. H5唤起app

    H5唤起app 1.判断是否在微信中打开 无论是在哪个平台的客户端Android/IOS,在微信的平台上访问都有一个问题,那就是无法启动客户端,这是微信为了安全性考虑的限制,android这边屏蔽sc ...

  2. h5唤起APP并检查是否成功

    // 检查app是否打开 function checkOpen(cb) { const clickTime = +(new Date()); function check(elsTime) { if ...

  3. h5 唤起app或跳转appStore

    //唤起app通过唤端媒介(URL Scheme)   //微信浏览器自6.3.x版本起禁用了大多数Scheme跳转功能,扫一扫目前可用   // URL 的组成:   // [scheme:][// ...

  4. H5及微信中唤起app的解决方案

    今天我们就来说说这个callapp-lib 我的接到的需求大概是这样的 如果检测到不是在app里面用webview打开的页面就会显示上面的立即打开按钮, 点击的话会判断是否在微信中, 如果在微信中打开 ...

  5. js在微信、微博、QQ、Safari唤起App的解决方案

    首先看下完整的流程: 简单说下universal link 在iOS9之前,唤起方式和现在安卓是一个的,都是使用scheme进行唤起,这种方式有个小问题,每次唤起,都会给个提示:是否打开xx应用,这样 ...

  6. H5唤起APP一些坑

    $(function () { function _openAppUrl(appUrl){ var ua = navigator.userAgent.toLocaleLowerCase(), open ...

  7. H5如何实现唤起APP

    前言 写过hybrid的同学,想必都会遇到这样的需求,如果用户安装了自己的APP,就打开APP或跳转到APP内某个页面,如果没安装则引导用户到对应页面或应用商店下载.这里就涉及到了H5与Native之 ...

  8. 简话h5唤起本地app

    在没接触这个功能之前,查询各种文档后也只是似懂非懂,做过之后,发现其实很简单,简言之就是通过一个iframe或者a标签来跳转app端提供的URL schema(至于这个URL schema的组成格式, ...

  9. 如何应用前端技术唤起app及判断用户来源及与原生交互的原理

    做唤起时需要native端进行配合, h5唤起app这种需求是常见的.在移动为王的时代,h5在app导流上发挥着重要的作用. 目前我们采用的唤起方式是url scheme(iOS,Android平台都 ...

随机推荐

  1. Python基础之面向对象进阶一

    一.isinstance(obj,cls)和issubclass(sub,super) 1.isinstance(obj,cls)检查obj是否是类 cls 的对象 class A: pass obj ...

  2. Laravel5使用QQ邮箱发送邮件配置

    在.env文件中设置如下MAIL_DRIVER=smtpMAIL_HOST=smtp.qq.comMAIL_PORT=465MAIL_USERNAME=00000000000@qq.comMAIL_P ...

  3. java函数式编程之Supplier

    原创 2016年12月25日 10:02:52 标签: 函数式编程 / java 3250 描述:Supplier< T>接口没有入参,返回一个T类型的对象,类似工厂方法. 源码: pub ...

  4. 论文阅读笔记九:SEMANTIC IMAGE SEGMENTATION WITH DEEP CONVOLUTIONAL NETS AND FULLY CONNECTED CRFS (DeepLabv1)(CVPR2014)

    论文链接:https://arxiv.org/abs/1412.7062 摘要 该文将DCNN与概率模型结合进行语义分割,并指出DCNN的最后一层feature map不足以进行准确的语义分割,DCN ...

  5. Python知乎热门话题数据的爬取实战

    import requestsfrom pyquery import PyQuery as pq url = 'https://www.zhihu.com/explore'headers = { 'u ...

  6. linux基础练习题(2)

    Linux命令作业(关卡二) 练习题1 理解操作系统的作用,以及各种操作系统的不同 要求: 为什么要有OS?没有OS能行吗?原因是什么? Linux内核指的是什么? Linux主要应用在哪些地方? 使 ...

  7. 关于The specified Android SDK Build Tools version (26.0.2) is ignored, as it is below the minimum...

    今天将项目迁移到另一台笔记本,进行build出现以下问题,导致build失败 The specified Android SDK Build Tools version (26.0.2) is ign ...

  8. 一脸懵逼学习Hadoop分布式集群HA模式部署(七台机器跑集群)

    1)集群规划:主机名        IP      安装的软件                     运行的进程master    192.168.199.130   jdk.hadoop      ...

  9. update + join 多表操作

    UPDATE vtiger_notificationcf as a INNER JOIN vtiger_crmentity as b ON a.notificationid = b.crmid SET ...

  10. [转]PO BO VO DTO POJO DAO概念及其作用(附转换图)

    来源:http://www.blogjava.net/vip01/archive/2013/05/25/92430.html J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手讨论问题的时候 ...