在H5页面中唤醒APP踩坑记

前言

公司要做在H5页面内唤醒我们公司的App功能,在此记录一下解决方法与参考文章。

原理

js没有办法获取到客户端是否安装了某个APP,所以我们可以用定时器在后台运行时会变慢的功能去模拟实现

URL scheme方式

  • 首选需要判断当前机型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // 判断浏览机型
    var browser={
    versions:function(){
    var u = navigator.userAgent;
    return {
    u: u,
    trident: u.indexOf('Trident') > -1, //IE内核
    presto: u.indexOf('Presto') > -1, //opera内核
    webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
    gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1,//火狐内核
    mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
    ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
    android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, //android终端
    iPhone: u.indexOf('iPhone') > -1 , //是否为iPhone或者QQHD浏览器
    iPad: u.indexOf('iPad') > -1, //是否iPad
    Mac: u.indexOf('Macintosh') > -1, // 是否是Mac
    webApp: u.indexOf('Safari') == -1, //是否为Safari浏览器
    weixin: u.indexOf('MicroMessenger') > -1, //是否微信
    qq: !!u.match(/\sQQ|\sTIM/i) //是否QQ或TIM
    }
    }()
    };
  • 需要区分是否是微信端(微信不允许在其中打开第三方APP,不过好像是有白名单之类的功能,具体情况没了解到),微信端解决方案有两个:

    1. 使用引导页,点击下载按钮时引导用户在浏览器中打开页面进行唤醒或下载
    2. 直接跳转下载页,用户在app Store中打开
  • URL scheme由客户端生成,打开此App的专属链接。(比如:weixin://这种形式)

  • 核心代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    /**
    * 打开app事件,未下载则跳转下载链接
    * downUrl: 下载链接
    * openUrl: 打开APPSchema
    * callback: 回调函数
    */
    function openApp(downUrl,openUrl,callback) {
    // 检查APP是否打开
    function checkApp(cb) {
    var _clickTime = +(new Date());
    var flag = false;
    function check(elsTime) {
    if(elsTime > 3000 || document.hidden || document.webkitHidden) {
    flag = true;
    cb(flag);
    console.log(elsTime,"s,elsTime超过3000了不会自动跳转下载了");
    }else {
    cb(flag);
    console.log("elsTime未大于3000,跳转下载链接")
    }
    }
    var _count = 0;
    var timer = setInterval(function() {
    _count ++;
    var elsTime = +(new Date()) - _clickTime;
    if(_count >= 100 || elsTime > 3000) {
    clearInterval(timer);
    check(elsTime);
    }
    },20);
    }
    // 创建a标签并触发点击跳转下载,两秒后删除
    var ifr = document.createElement('a');
    ifr.href = openUrl;
    $(ifr).css({display: 'none'});
    var event = document.createEvent('MouseEvents');
    event.initEvent('click',false,false);
    ifr.dispatchEvent(event);
    if(callback) {
    checkApp(function(opend) {
    callback && callback(opend)
    })
    }
    $('body').append(ifr);
    setTimeout(function() {
    $('body')[0].removeChild(ifr);
    },2000);
    }

    进入方法后首先创建了a标签,href为打开app的openUrl,然后用createEvent事件触发了a标签。进入checkApp方法生成一个定时器,如果没有安装app的话则_count会先大于等于100,此时的elsTime是没有大于3000的,所以可以在回调函数内进行下载链接跳转。但是如果安装了app(弹窗提示是否打开此app时页面是假死状态)打开后,定时器加载会变慢,那么elsTime就会大于3000,所以不进行跳转下载链接。

  • 使用方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if(browser.versions.iPhone || browser.versions.iPad){ // 机型判断
    if(!browser.versions.weixin){
    openApp(downloadUrl,openUrl,function(flag){
    if(!flag) {// 跳转下载页
    window.location.href = downloadUrl;
    }
    })
    }else {// 微信直接跳转下载,不必等2s
    window.location.href = downloadUrl;
    }
    }
  • 优化

    因为没有安装app的话需要等待两秒才跳转下载链接,所以这两秒的时间内给用户一个提示避免用户以为手机死掉了,优化后代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if(browser.versions.iPhone || browser.versions.iPad){ // 机型判断
    // popupHint('正在打开APP...'); // 弹窗提示
    if(!browser.versions.weixin){
    openApp(downloadUrl,openUrl,function(flag){
    // popupHint('','none'); // 有回调后关闭弹窗
    if(!flag) { // 跳转下载页
    window.location.href = downloadUrl;
    }
    })
    }else { // 微信直接跳转下载,不必等2s
    window.location.href = downloadUrl;
    }
    }

Schema 的弊端能通过Universal Link解决。

在没装App的时候,Universal Link是一个合法的url链接,浏览器可以正常跳转,因此不会出现在iOS上讨人厌的框。

Universal Link目前还没有基于iOS的UI/WKWebView的应用进行拦截,所以目前看还是能突破微信/手百的封锁。

配置apple-app-association文件

究竟哪些的url会被识别为Universal Link,全看这个apple-app-association文件

  • 你的域名必须支持Https
  • 域名根目录下放这个文件apple-app-association,不带任何后缀
  • 文件为json保存为文本即可
  • json按着官网要求填写即可

因为此方法需要域名支持https,所以我没有进行测试,是用URL scheme方法解决的,so没有代码例子

参考

ios:

Universal Link 前端部署采坑记

iOS的UniversalLink开发总结

UniversalLink通用链接

从微信/H5中调起iOS应用(这是一个总结了几个方法的文章)

Android下解决方法:

通过JS页面唤醒app

支持IOS9+和Android5+,JS打开APP的解决方案

结语

URL scheme的解决方法可以应付大部分场景了,微信端访问时引导用户通过safari打开进行下载。

有些Android低版本的系统,浏览器在访问URL scheme时会像打开url链接一样打开,导致404,如果需要向下兼容时就需要再研究一下了!

-------------End,感谢阅读!-------------

本文标题:在H5页面中唤醒APP踩坑记

文章作者:加贝H

原始链接:https://jiabeih.cn/2018/08/29/关于在H5打开APP/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。