zoukankan      html  css  js  c++  java
  • H5页面中唤起native app

    现在各类app,分享出去的H5页面中,一般都会带着一个立即打开的按钮,如果本地安装了app,那么就直接唤起本地的app,如果没有安装,则跳转到下载。这是一个很正常的推广和导流量的策略,最近产品经理就提出了这样的一个需求,做一个像今日头条功能一样的带打开app的下载条。

    实现这个功能,我们需要解决两个问题
    1、js如何唤起本地app
    2、js如何知道手机已经安装了对应的应用

    js如何唤起本地app

    既然是通过网页调用app,这个当然涉及到与app的通信。通过咨询ios和android的同事,ios与android都支持一种叫做schema协议的链接。这种协议的类似于我们熟悉的http协议,我们只要跟app协商好协议头,app通过拦截到这个协议头的请求就可以知道有网页要求调用。而对于js来说,我们这要像a标签的href一样来激活这个协议的链接就行了。

    比如:

    <a href="myapp://">调起app</a>


    这种方式ios和android都可以共用

    2、如何知道手机已经安装的对应的应用对于这个功能的实现,首先想到的是查询应用是否存在,但是这种方法显而易见是行不通的,比如说你在UC浏览器,微信中,我们无法主动的去查询我们系统中是否安装了该应用。所以这个判断是无法实现。所以我们就需要采用曲线救国的方式来实现。既然我们可以唤起app,那我们就可以忽略判断,直接唤起app,如果用户没有安装,我们做一个容错处理。

    结合这个思路,我们基本可以得到我们的实现方案

    var iframe = document.createElement('iframe');
    var body = document.body;
    iframe.style.display = "none";
    ar timer = null;
    
    var openapp = document.getElementById('openapp');
    openapp.addEventListener('click', function() {
    body.appendChild(iframe);
    iframe.src = "appschema://";
    timer = setTimeout(function() {
    wondow.location.href = "download.html"; //容错的下载页面
    }, 500);
    }, false)

    写完代码,做了测试,发现这样的实现有很多问题
    1、微信无法调起。微信对于链接的跳转限制很严重,很多下载外链都引导到浏览器打开
    2、调起app返回浏览器的时候,会跳转到下载页面,既然用户已经下载了app,再让页面跳转到下载页很不友好
    3、ios9+的safari无法通过iframe跳转到其他页面

    有问题就需要解决

    1、对于微信或者QQ空间,在网上查找资料,如果是在应用宝上线的应用,应用宝提供了微下载来实现微信和QQ打开app,先跳转到应用宝的的下载链接,然后下载宝链接会判断打开对应的app,具体参考(http://wiki.open.qq.com/index.php?title=mobile/%E5%BA%94%E7%94%A8%E5%AE%9D%E5%BE%AE%E4%B8%8B%E8%BD%BD)但是应用宝的微下载有个问题,ios微信和QQ中无法打开对应的应用,只是会通过你应用宝配置的appstore下载链接跳转到对应的下载页面,再从appstore里面打开应用。所以这个问题还是不能完全解决,只能完美解决android的机器

    2、针对问题2,网上有人通过监控页面的pagehide和visibilitychange方法来实现禁止跳转,具体的实现思路是监控页面是否隐藏,利用延时如果页面已经打开app,此时页面会是隐藏状态,触发页面的隐藏事件,clear延时事件,禁止跳转,不过这个方案会出现问题,有一些浏览器在app打开,离开浏览器之后,js事件不在执行,也就是此时无法监控的页面的隐藏,在返回页面的时候,js继续执行,但是事件监控的还是页面展示的状态,无法clear延时事件,所以该方式无法完美解决这个问题

    后来找到了另外的解决方案,调起app需要唤起另外的进程,所以js的进程会挂起,导致前后有一个时间差,记录前后的事件差对比就可以判断是否调起了app了

    iframe.src = "appschema://";
    var timer = null,
    t = Date.now();
    timer = setTimeout(function() {
    if (Date.now() - t > 1200) {
    clearTimeout(timer);
    return false;
    }
    }, 1000);

    3、对于问题3,Apple为iOS 9发布了一个所谓的通用链接的深层链接特性,即Universal links。只要在app中授权好域名,在网页中只要打开对应域名链接,都会检测与域名绑定的app是否存在,如果存在,直接调起app,具体参考(http://stackoverflow.com/questions/31891777/ios-9-safari-iframe-src-with-custom-url-scheme-not-working),并且该方法不会被微信拦截,可以在微信中使用,这样也就解决了我们在腾讯平台下ios无法通过微下载打开的问题

    最后再来整理一下我们的思路
    1、ios通过Universal links,针对ios9一下和以前版本没有实现Universal links,在绑定好的域名下做一个中间页,直接跳转到中间页
    2、android分平台,如果是微信或者QQ(可以通过用户代理检测),直接通过微下载,其他浏览器,直接用schema协议

    具体代码实现如下

    var url = {
            open: 'duchuang://',
            down: 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework'
        },
        iframe = document.createElement('iframe');
    iframe.style.cssText = 'display:none;width=0;height=0';
    var timer = null,
        //点击第三方下载
        isAndroid = !!navigator.userAgent.match(/android/ig),
        isIos = !!navigator.userAgent.match(/iphone|ipod/ig),
        isIpad = !!navigator.userAgent.match(/ipad/ig),
        isWeixin = (/MicroMessenger/ig).test(navigator.userAgent),
        isQQ = (/qq/ig).test(navigator.userAgent),
        openapp = document.getElementById('cal-app');
    openapp.addEventListener('click', function() {
        if (isIos) {
            window.location.href = "https://appdetail.netwin.cn/download.html"
        }
    
        if (isAndroid) {
            if (isWeixin || isQQ) { //andorid微信和QQ走微下载
                window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework&android_schema=' +  url;
            } else {
                body.appendChild(iframe);
                iframe.src = url.open;
                var t = Date.now();
                timer = setTimeout(function() {
                    if (Date.now() - t > 1200) {
                        clearTimeout(timer);
                        return false;
                    }
                    if (document.webkitHidden || document.hidden) {
                        return false;
                    }
                    window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework';
                }, 1000);
            }
        }
    }, false)
    
    
    document.addEventListener("webkitvisibilitychange", function() {
        var tag = document.hidden || document.webkitHidden;
        if (tag) {
            clearTimeout(timer);
        }
    });
    
    
    window.addEventListener('pagehide', function() {
        clearTimeout(timer);
    })
  • 相关阅读:
    SQL Server 和Oracle 12C体系结构图
    SQL Server Latch
    MSSQL SSIS agent job运行出错
    sys.processes spid 和 blocked是同一个 session id
    黑苹果导致Windows时间不对或关机不断电
    MSSQL shrink数据库
    MSSQL 死锁或阻塞检测
    MSSQL不能shrink日志
    tomcat配置https协议
    ELK windows下部署测试
  • 原文地址:https://www.cnblogs.com/caizhenbo/p/6339715.html
Copyright © 2011-2022 走看看