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计算器实操

    要求: 开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...

  2. 模块(import语句,from...import语句,_name_属性)

    1, 什么是模块? 模块就是一系列功能的集合体 模块分为四个通用的类别: 1), 使用python编写的.py文件(*****) 2), 已被编译为共享库或DLL的C或C++扩展 3), 把一系列模块 ...

  3. spring cloud feign覆写默认配置级feign client的日志打印

    一.覆写fegin的默认配置 1.新增配置类FeignConfiguration.java package com.config; import org.springframework.context ...

  4. spring cloud 声明式rest客户端feign调用远程http服务

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.Feign就是Spring Cloud提供的一种声明式R ...

  5. SRS流媒体服务器搭建+ffmpeg推流VLC取流观看

    一.编译SRS https://github.com/winlinvip/simple-rtmp-server 目前有1.0-release.2.0.3.0等版本 2.0官方文档地址:https:// ...

  6. Redis分布式锁(ServiceStack.Redis实现)

    1.设计思路 由于Redis是单线程模型,命令操作原子性,所以利用这个特性可以很容易的实现分布式锁.A用户端在Resdis写入1个KEY,其他的用户无法写入这个KEY,实现锁的效果.A用户使用完成后释 ...

  7. (原创)C# 压缩解压那些事儿

    吐槽: 搜狗推广API的报告服务太坑爹了!!! 搜狗推广API的报告服务太坑爹了!!! 搜狗推广API的报告服务太坑爹了!!! 搜狗的太垃圾了,获取下来的压缩包使用正常方式无法解压!!没有专门的API ...

  8. CDOJ 1962 天才钱vs学霸周2【最大流】

    以s=0,t=n+m+1分别为超级源点和超级汇点.网络流中的流量以0为开始,题目要求从1到20,我们先把每个点都减去1,即ai - m,bi - n.然后源点s与n个顶点连容量为ai的路,汇点t与m个 ...

  9. sendEmail 阿里云使用587端口

    使用sendEmail使用参数   -o tls=yes -s smtp服务器+端口 因为阿里云屏蔽了25端口,我使用465也不成功,只有使用587端口,我使用的qq企业邮箱,测试可用

  10. centos 6.9安装python 3.6

    .下载源码包在官网按照需要下载到本地 wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tgz .解压源码包 tar -xvf Pyt ...