h5唤起app

公司给了一个需求,要求点击一个按钮去唤醒app(有app则唤醒,没有则跳到应用商场或者appStore)。以前没有写过这个,在网上搜了一些解决的方法,相应的方法也可能有大大小小的办法,然后结合一下,还可以凑合着用。

本文的方法是使用 Url scheme 来实现的H5与安卓、苹果应用之间的跳转链接

实现方法:

openRelevantApp() {
      var _this = this;
      var browser = {
        versions: function () {
          var u = navigator.userAgent, app = navigator.appVersion;
          return { //移动终端浏览器版本信息 
          ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端 
          android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或uc浏览器 
          iPhone: u.indexOf('iPhone') > -1, //是否为iPhone
          iPad: u.indexOf('iPad') > -1, //是否iPad 
          };
        }(),
      }
      var isIos = browser.versions.iPhone || browser.versions.iPad || browser.versions.ios; //ios终端
      var isAndroid = browser.versions.android; //android终端
      var isChrome = window.navigator.userAgent.indexOf("Chrome") !== -1;

      var downloadUrl1 = 'appStore中下载地址';
      
      var downloadUrl2 =  'Android应用商场的地址';
        
      var openUrl_IOS = `ios中打开相应页面的地址`;
      var openUrl_Android = `Android中打开相应页面的地址`;

      var ua = window.navigator.userAgent.toLowerCase(); //获取判断用的对象

      
      var startTime = Date.now();

      /** 在微信打开 */
      if(ua.match(/MicroMessenger/i) == 'micromessenger') {
          //由于微信不能直至打开app,所以提示用户使用浏览器打开相应的地址(我使用的是:当微信打开时,给一个弹窗,提示点击右上角使用浏览器打开)
          //相应的代码
      }else{
        if(isIos){ //判断是否是ios
          // 由于在ios中qq中也不能使用iframe和window.location.href唤起app 这里我也使用和微信中使用同一种方法
          if(ua.match(/QQ\/[0-9]/i)){ //判断是否是在qq里面
            //相应的代码
          }else{
            if(_this.isIOS9()){
              window.location.href = openUrl_IOS;
            } else {
              _this.openApp(openUrl_IOS);
            }
               
            //检查app是否打开
            function check(elsTime) {
              if (elsTime > 3000 || document.hidden || document.webkitHidden) {
              } else {
                window.location.href = downloadUrl1;
              }
            }

            // 启动间隔20ms运行的定时器,并检测累计消耗时间是否超过3000ms,超过则结束
            var _count = 0,intHandle;
            intHandle = setInterval(function() {
              _count++
              var elsTime = Date.now() - startTime
              if (_count >= 100 || elsTime > 3000) {
                clearInterval(intHandle)
                check(elsTime)
              }
            }, 20)
          }
        }else if(isAndroid) { //判断是否是android
          if(isChrome) {
            //chrome浏览器用iframe打不开得直接去打开
            window.location.href = openUrl_Android;
          }else{
            _this.openApp(openUrl_Android);
          }

          function check(elsTime) {
            if (elsTime > 3000 || document.hidden || document.webkitHidden) {
            } else {
              window.location.href = downloadUrl2;
            }
          }

          // 启动间隔20ms运行的定时器,并检测累计消耗时间是否超过3000ms,超过则结束
          var _count = 0,intHandle;
          intHandle = setInterval(function() {
            _count++
            var elsTime = Date.now() - startTime
            if (_count >= 100 || elsTime > 3000) {
              clearInterval(intHandle)
              check(elsTime)
            }
          }, 20)
        }else{
          function check(elsTime) {
            if (elsTime > 3000 || document.hidden || document.webkitHidden) {
            } else {
              window.location.href = downloadUrl2;
              // clearTimeout(interval);
            }
          }
          // 启动间隔20ms运行的定时器,并检测累计消耗时间是否超过3000ms,超过则结束
          var _count = 0,intHandle;
          intHandle = setInterval(function() {
            _count++
            var elsTime = Date.now() - startTime
            if (_count >= 100 || elsTime > 3000) {
              clearInterval(intHandle)
              check(elsTime)
            }
          }, 20)
        }
      }
    },

    openApp(src) {
      // 通过iframe的方式试图打开APP,如果能正常打开,会直接切换到APP,并自动阻止a标签的默认行为
      var ifr = document.createElement('iframe');
      ifr.src = src;
      ifr.style.display = 'none';
      document.body.appendChild(ifr);
      window.setTimeout(function(){
        document.body.removeChild(ifr);
      },200);
    },

    /*判断是否是ios9以上*/
    isIOS9() {
      //获取固件版本
      var getOsv = function () {
        var reg = /OS ((\d+_?){2,3})\s/;
        if (navigator.userAgent.match(/iPad/i) || navigator.platform.match(/iPad/i) || navigator.userAgent.match(/iP(hone|od)/i) || navigator.platform.match(/iP(hone|od)/i)) {
          var osv = reg.exec(navigator.userAgent);
          if (osv.length > 0) {
            return osv[0].replace('OS', '').replace('os', '').replace(/\s+/g, '').replace(/_/g, '.');
          }
        }
        return '';
      };
      var osv = getOsv();
      var osvArr = osv.split('.');
      //初始化显示ios9引导
      if (osvArr && osvArr.length > 0) {
        if (parseInt(osvArr[0]) >= 9) {
          return true
        }
      }
      return false
    },

注意:

因为在H5中无法判断是否安装app,只能通过先去尝试打开app,如果已经安装则直接打开app,否则根据打开app的时间来控制去跳转到下载页面(控制不是准确)。

在一些情况下跳转到app了,按返回键后还是会跳转到下载页面,因为浏览器差异兼容情况不一。ios中在safari中使用schema打开应用,应用没有安装的时候,会跳转App Store,如果第一次提示打开App Store或者应用市场时,选择“取消”,那么再点击的时候是无法跳转到App Store或者应用市场的,什么原因暂时也不清楚。

第一次写博客,当然也是为了纪录,使用的方法好多都是自己网上找到,然后经过自己的测试,有些地方不时很严谨,所以还是凑合这用吧 

参考网站:1、https://www.jianshu.com/p/88dbe73e34ec
2、https://www.jianshu.com/p/40430596e3ab
3、https://github.com/stuxt/stuxt.github.io/issues/32

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值