• H5 唤起 APP的解决方案


     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)
        }
    }
  • 相关阅读:
    课程详情页之前台
    课程详情页之后台
    java虚拟机原理图解6--class文件中的字段集合,field字段在class文件中是怎样组织的
    java虚拟机原理图解5--class文件中的访问标志,类索引,父类索引,接口索引集合
    java虚拟机原理图解4--class文件中的常量池详解(下)
    java虚拟机原理图解3--class文件中的常量池详解(上)
    java虚拟机原理图解2--class文件中的常量池
    JVM虚拟机原理图解1--class文件基本组织结构
    Http协议中GET和POST的区别
    SpringCloud插件之ribbon和feign的使用
  • 原文地址:https://www.cnblogs.com/yzhihao/p/8989195.html
Copyright © 2020-2023  润新知