Top
Fork me on Gitee My Github

h5 唤醒 app 功能

微信或浏览器访问 h5 链接,点击操作后进入指定 app

需求情景:
从 app 内部分享出去的网页顶部有一个“打开”按钮,用户点击后:
1、若用户客户端安装我们的 app,直接跳转到我们的 app;
2、若用户没有安装,跳转到应用宝提示用户下载;

universal link 是 ios9 之后出的功能。它是通过传统HTTP链接来启动 App。它其实就是一个https开头的链接,还要满足一些特定的规则才能被识别为 universal link,才能直接唤起 app(支持传参)
缺点:个别浏览器不支持唤醒,不支持跳转到 app store;通用链接可被屏蔽,点击右上角配置的链接之后,通用链接就失效了,在浏览器中点击‘打开’继续支持唤醒(ios10);...

Universal Link的基本运作流程;
APP第一次启动 or APP更新版本后第一次启动;
APP向工程里配置的域名发起Get请求拉取apple-app-association Json File;
APP将apple-app-association注册给系统;
由任意webview发起跳转的url,如果命中了apple-app-association注册过的通用链接;
打开App,触发Universal Link delegate;
没命中,webview继续跳转url;
在你进行apple-app-association 以及 App工程的配置之后,整个Universal Link的运作流程完全由系统控制了。

微信文档Universal Link

参考博客

参考网站:

b站:ios 微信直接打开、safari直接打开。其他浏览器 指定safari浏览器打开指示弹框,或者跳转app store

人民日报

function openApp(url) {
  var u = navigator.userAgent, ua = u.toLowerCase();
  if (ua.match(/iPhone\sOS/i) == "iphone os") {
    // 判断是否是qq、qq浏览器、微博 (这里的qq判断不精准)
    if(ua.match(/QQ/i) == "qq" || ua.match(/MQQBROWSER/i) == "mqqbrowser" || ua.match(/WeiBo/i) == "weibo"){
        $(".fixed_back").show(); // 弹框显示
    }else{
        window.location.href = url; // Universal Link 指定连接
    }
  } else if (ua.match(/Android/i) == "android") {
    // android 手机
  }
}
$(".fixed_back").click(function () { $(".fixed_back").hide(); })

2. URL Scheme

URL scheme是在app内配置的链接,比如:weixin://,superclass://
URL scheme的格式是[scheme]😕/[host]/[path]?[query]

指导弹框-参考页面

将参数配置在url scheme后面,唤醒app再进行页面跳转逻辑。

但是QQ和微信都把url scheme 唤醒app这种方式给禁了。

操作步骤:点击按钮,弹出指示弹框引导的分享;将链接在浏览器中显示,点击按钮后进行操作,ios进行判断如果能唤醒则唤醒,否则直接跳转ituns

android 参考文档

3. 应用宝或 ituns(这两种方式不能传参数)

终极解决方案-参考博客

总结:app进行配置,在微信中实现体验较好(可能需要一个中间页面),如果是其他浏览器,辅助第二种方案(或只跳转到app store)

safari浏览器打不开该网页,因为网址无效 弹框

URL Scheme 应用代码(亲测有效)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>H5唤醒app</title> 
</head>

<body>
    <div id="div">测试跳转按钮</div>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
    <script>
        var app_links = "应用宝跳转链接",
        url_scheme = "app的url scheme协议";
        // app link
        function detectVersion() {
            let isAndroid, isIOS, isIOS9, version,
                u = navigator.userAgent,
                ua = u.toLowerCase();
            if (u.indexOf('Android') > -1 || u.indexOf('Linux') > -1) {   //android终端或者uc浏览器
                //Android系统
                isAndroid = true
            }
            if (ua.indexOf("like mac os x") > 0) {
                //ios
                var regStr_saf = /os [\d._]*/gi;
                var verinfo = ua.match(regStr_saf);
                version = (verinfo + "").replace(/[^0-9|_.]/ig, "").replace(/_/ig, ".");
            }
            var version_str = version + "";
            if (version_str != "undefined" && version_str.length > 0) {
                version = parseInt(version)
                if (version >= 8) {
                    // ios9以上
                    isIOS9 = true
                }
                else {
                    isIOS = true
                }
            }
            return { isAndroid, isIOS, isIOS9 }
        }
        // 判断手机上是否安装了app,如果安装直接打开url,如果没安装,执行callback
        function openApp(url, callback) {
            let { isAndroid, isIOS, isIOS9 } = detectVersion()
            if (isAndroid || isIOS) {
                var timeout, t = 4000, hasApp = true;
                var openScript = setTimeout(function () {
                    if (!hasApp) {
                        callback && callback()
                    }
                    document.body.removeChild(ifr);
                }, 5000)
                var t1 = Date.now();
                var ifr = document.createElement("iframe");
                ifr.setAttribute('src', url);
                ifr.setAttribute('style', 'display:none');
                document.body.appendChild(ifr);

                // 没有跳转
                timeout = setTimeout(function () {
                    var t2 = Date.now();
                    if (t2 - t1 < t + 100) {
                        hasApp = false;
                    }
                }, t); // 4000
            }
            if (isIOS9) {
                location.href = url;
                setTimeout(function () {
                    callback && callback()
                }, 250);
                setTimeout(function () {
                    location.reload();
                }, 1000);
            }
        }
        //跳h5
        function goConfirmAddr() {
            // 缺点:1. 未安装会弹出safari浏览器网址无效弹框
            // 2,跳转前会有中间弹框 
            if (confirm('是否跳转app store')) { // **这里加一个确认弹框,防止唤醒app后继续执行下面的代码跳转到ituns**
                window.location.href = app_links;
            }
        }
        // window.onload = function(){ // 进入页面后直接执行
        var oDiv = document.getElementById("div"); // 点击按钮执行
        oDiv.onclick = function () { openApp(url_scheme, goConfirmAddr) };
        // }

    </script>
</body>

</html>

ios工程师会配置universal links这样在唤醒ios app会更加方便,有一些浏览器不支持唤醒功能可以借助弹框引导到指定浏览器打开(如果开代理下载了app或者在某些情况下没有(默认)成功下载证书也可能不支持唤醒);android 使用app link配置,不过也有不同型号的手机存在,多测试,针对具体问题采用具体解决方案,适配直流设备。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>打开app</title>
</head>
<body>
    <a id="open-app-btn">打开app</a>        
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
        var u = navigator.userAgent,
            ua = u.toLowerCase();
        var objUrl = urlSlice(location.href);
        var app_links = '#', // 应用宝跳转链接
            url_scheme = '##', // app的url scheme协议
            ios_app_links = '#'; // ios Universal Link 带参数?share=" + objUrl.arteId
        var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端 ua.match(/Android/i) == 'android' || ua.match(/Linux/i) == 'linux'
        var isIOS = !u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 ua.match(/iPhone\sOS/i) == "iphone os"
        var isWeChat = /MicroMessenger/i.test(navigator.userAgent)

        function urlSlice(url) { // 获取url参数
            if(url.indexOf('?') == -1){
                return false;
            }
            var arr = decodeURIComponent(url).split("?");
                arr = arr[1].split("&");
            var len = arr.length, obj={};
            for (var i = 0;i < len;i++) {
                var a = arr[i].split("=");
                obj[a[0]] = a[1];
            }
            return obj;
        }

        // android app link
        function deeplink() {
            if ( isWeChat ) {
                window.location.href = app_links;
            } else {
                // window.location.href = url_scheme;
                var ifr = document.createElement("iframe")
                ifr.src = url_scheme
                ifr.style.display = "none"
                document.body.appendChild(ifr);
                window.setTimeout(function () {
                    document.body.removeChild(ifr);
                    var hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden || window.document.webkitHidden
                    if (typeof hidden == "undefined" || hidden == false) {
                        window.location.href = app_links;
                    }
                }, 2000)
            }
        }
        function openApp() {
            if ( isIOS ) {
                // 判断是否是qq、qq浏览器、微博
                if (ua.match(/QQ/i) == "qq" || ua.match(/MQQBROWSER/i) == "mqqbrowser" || ua.match(/WeiBo/i) == "weibo") {
                    $(".fixed_back").show();
                } else {
                    window.location.href = ios_app_links;
                }
            } else if ( isAndroid ) {
                // 判断是否是qq、qq浏览器、微博(如果浏览器限制相同可以包裹在设备判断外部)
                if (ua.match(/QQ/i) == "qq" || ua.match(/MQQBROWSER/i) == "mqqbrowser" || ua.match(/WeiBo/i) == "weibo") {
                    $(".fixed_back").show();
                } else {
                    deeplink()
                }
            }
        }

        // 打开app
        $("#open-app-btn").click(function () {
            openApp();
        })

        // 弹框蒙层
        $(".fixed_back").click(function () {
            $(".fixed_back").hide();
        })

    </script>
</body>
</html>
posted @ 2020-05-15 17:38  lisashare  阅读(1360)  评论(0编辑  收藏  举报