背景: 有时候,会遇到这种需求,就是扫描二维码打开app,若是用户没有这个app则提示它跳转;或者,用户首次安装,通过扫描二维码进行跳转到应用商店,或直接下载apk。
用网页直接来调用app是不可能的,必须原生那边先做一些配置。而且,安卓和苹果的调用方法是不一样的。
一、方法1,直接统一跳转至应用市场
在h5页面上,不管用户是否安装过app,都直接跳转至应用商店,让用户从应用市场上打开app,这种方法比较简单直接,而且,微信扫描也不需要做特殊处理。
思路:首先,直接判断设备是android端还是ios端,然后,在点击按钮上赋值对应的应用商店下载链接就可以了。在微信上打开h5页面时也不用另外做处理,跳转之前,系统会默认弹出对话框询问是否跳转。
具体实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<style type="text/css">
body{
padding-top: 30px;
}
.open-app {
margin: 30px;
border-radius: 5px;
padding: 10px 20px;
border: 1px solid #ccc;
}
</style>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<a class="open-app">click me to store</a>
<script type="text/javascript">
var iosLinkUrl = "http://apps.apple.com/cn/app/id387682726" // 淘宝 app store 下载地址
var androidLinkurl = "https://a.app.qq.com/o/simple.jsp?pkgname=com.lucky.luckyclient" //(找不到淘宝应用宝地址,这里以lucky coffee为例)
var u = navigator.userAgent, isAndroid, isIOS
window.onload = function() {
init()
}
function init() {
isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端
isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
var link = isIOS ? iosLinkUrl : androidLinkurl
$('a').attr('href', link)
}
</script>
</body>
</html>
二、方法2
在h5页面上,用户点击打开app按钮,若用户手机上已经安装了app时,就直接打开app,否则,就引导用户前往应用市场,或者下载apk。这种操作,体验更好,方便用户操作与使用,而且,在业务需要的情况下,可以跳转到app指定页面和传参。
思路:在h5页面上唤醒app,需要用到scheme协议(由app端小伙伴提供),但是在微信游览器中scheme协议不起作用,有时在微信上打开的一些需要跳转到app的操作时,会提示在游览器上打开就是这个原因。
所以,需要先判断是否为微信游览器,是微信游览器的话,提示到游览器打开,不是的话,再判断是android端还是ios端,然后,作相应的处理。
具体实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<style type="text/css">
body{
padding-top: 30px;
}
.open-app {
margin: 30px;
border-radius: 5px;
padding: 10px 20px;
border: 1px solid #ccc;
}
</style>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<a class="open-app">click me to app</a>
<script type="text/javascript">
$('a').click(function() {
var u = navigator.userAgent;
var isWeixin = u.toLowerCase().indexOf('micromessenger') !== -1; // 微信内
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
// 微信内
if(isWeixin) {
alert('请在浏览器上打开')
} else {
//android端
if (isAndroid) {
//安卓app的scheme协议
window.location.href = 'taobao://';
setTimeout(function(){
let hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden ||window.document.webkitHidden
if(typeof hidden =="undefined" || hidden ==false){
//应用宝下载地址 (emmm 找不到淘宝应用宝的地址,这里放的是 lucky coffee 地址)
window.location.href ="https://a.app.qq.com/o/simple.jsp?pkgname=com.lucky.luckyclient";
}
}, 2000);
}
//ios端
if (isIOS) {
//ios的scheme协议
window.location.href = 'taobao://'
setTimeout(function(){
let hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden ||window.document.webkitHidden
if(typeof hidden =="undefined" || hidden ==false){
//App store下载地址
window.location.href = "http://itunes.apple.com/app/id387682726";
}
}, 2000);
}
}
});
</script>
</body>
</html>
如果,能检测到scheme就跳转到协议taobao,即打开app;
如果2秒后,还没有唤醒taobao,那么就认为该设备上没有安装taobao,即跳转到应用市场。
这里,可以选择直接打开窗口来打开链接,或者,也可以用到iframe框架
来打开链接,但是ios9屏蔽了iframe这个标签。
借助iframe可以在原页面打开一个页面:
使用iframe的话,既可以实现下载,又可以不重新打开页面,而且,对原页面的布局不会产生任何影响。
关键代码:
var src = 'http://imtt.dd.qq.com/16891/26747DD8B125A8479AD0C9D22CA47BC9.apk?fsname=com.snda.wifilocating_4.2.91_3211.apk&csr=1bbd';
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = "javascript: '<script>location.href=\"" + src + "\"<\/script>'";
document.getElementsByTagName('body')[0].appendChild(iframe);
form的action也可以发出请求:
var src = 'http://imtt.dd.qq.com/16891/26747DD8B125A8479AD0C9D22CA47BC9.apk?fsname=com.snda.wifilocating_4.2.91_3211.apk&csr=1bbd';
var form = document.createElement('form');
form.action = src;
document.getElementsByTagName('body')[0].appendChild(form);
form.submit();
补充:scheme的相关补充介绍
URL Scheme方式唤起Activity或App
URL Scheme是一种页面内部跳转协议,通过这个协议可以比较方便的跳转到app某一个页面。
scheme应用场景:
(目前1,2,5使用场景很广)
- 通过小程序,利用scheme协议打开原生app;
- H5页面点击锚点,根据锚点具体跳转路径app端跳转具体的页面;
- app端收到服务器端下发的push通知栏消息,根据消息的点击跳转路径跳转至相关页面;
- app根据URL跳转到另外一个app指定页面;
- 通过短信息中的url打开原生app。
附上Scheme协议详细介绍(https://segmentfault.com/a/1190000015880556)
三、具体应用举例
首先,判断是不是微信扫描的,如果是,则提示游览器打开;通过游览器访问以后,判断设备来源,如果是 android,就通过iframe来实现打开新页面,下载apk;如果是ios,就通过location.href打开新页面,跳转至应用商店。
相关图片如下所示:
具体实现:
<!DOCTYPE html>
<html style="font-size: 80.5%;">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta content="no" name="apple-mobile-web-app-capable">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<meta content="telephone=no" name="format-detection">
<title>下载 - 智能摄像机</title>
<link rel="stylesheet" type="text/css" href="http://publicfiles.xxx.com/yi_files/all.min.dc422677.css" />
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "//hm.baidu.com/hm.js?c80f110b564dd5a35f5c9d47bfe0520b";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<style>
.a_down{
display: block;
max-width: 65%;
margin: 2rem auto .5rem;
font-size: 2.4rem;
line-height: 2.4rem;
border: 1px solid #E73861;
color: #E73861;
padding: 1rem 0;
border-radius: .5rem;
text-align: center;
}
#tips{
display: none;
color:#ccc;
text-align: center;
}
</style>
</head>
<body style="background: #ffffff; width:100%;height:100%;">
<div class="wechat">
<img class="fc" src="http://publicfiles.xxx.com/yi_files/wechat-notice.png" />
</div>
<div id="layout">
<h2 class="t_title" style="font-family: 'FZLTXHK','Microsoft Yahei';font-weight: initial;color:#00BAAD;font-size: 2.2rem;">智能摄像机</h2>
<h4 class="t_des" style="font-family: 'FZLTXHK','Microsoft Yahei';color:#4C4C4C;font-weight: 200;">会看会听会思考 引领智能新生活</h4>
<img style="margin: 3rem auto;max-width: 100%;margin-left:-3%;" src="http://publicfiles.xxx.com/yi_files/yi_02_3.png" />
<a class="a_down" style=" background-color: #00BAAD; margin-top: -10%;border: 1px solid #00BAAD;color: #00BAAD; font-size: 1.4rem;
line-height: 1.4rem; border-radius: 100px;max-width: 80%;" href="javascript:;"><font style="color:#ffffff">智能下载</font></a>
<p id="tips" >正在下载,请稍等!</p>
</div>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-60717157-3', 'auto');
ga('send', 'pageview');
</script>
<script type="text/javascript" src="http://publicfiles.xxx.com/yi_files/zepto.min.1abd55c5.js"></script>
<script type="text/javascript" src="assets/js/cam.min.5ab037100.js"></script>
</body>
</html>
其中,cam.min.5ab037100.js文件是实现跳转的核心代码,如下:
/*
* 智能机浏览器版本信息:
*
*/
var browser = {
versions: function() {
var u = navigator.userAgent,
app = navigator.appVersion;
return { //移动终端浏览器版本信息
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.*/) || !!u.match(/AppleWebKit/), //是否为移动终端
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 || u.indexOf('Mac') > -1, //是否为iPhone或者QQHD浏览器
iPad: u.indexOf('iPad') > -1, //是否iPad
webApp: u.indexOf('Safari') == -1, //是否web应该程序,没有头部与底部
weixin: u.indexOf('MicroMessenger') > -1,
weibo: u.indexOf('weibo') > -1
};
}(),
language: (navigator.browserLanguage || navigator.language).toLowerCase()
}
if (browser.versions.android) {
console.log('增加按钮');
}
if (browser.versions.weixin || browser.versions.weibo) {
$('.wechat').addClass('wechat_active');
}
if (!browser.versions.ios) {
$('.a_down_url').addClass('android_active');
}
function uuid(){
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4";
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
function getCookie(name)
{
var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
if(arr=document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}
function setCookie(name,value)
{
var Days = 30;
var exp = new Date();
exp.setTime(exp.getTime() + Days*24*60*60*1000);
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
}
$('.a_down').on('click', function() {
console.log('下载');
try {
$('#tips').css("display:block")
} catch (e) {};
var uuids = getCookie('cid');
if(null!=uuids && uuids!=""){
uuids = uuids;
}else{
uuids = uuid();
setCookie('cid',uuids);
}
var datelong = new Date().getTime();
if (browser.versions.android) {
$.ajax({
url:'https://log.xxx.com/info.gif?cid='+uuids+'&p=android&data={"data":[{"t":"e","c":"AppInsDownload","ts":'+datelong+',"result":"true"}]}',
type:'get',
success:function(data){
console.log('成功:'+data);
}
})
try {
ga('send', 'event', '家庭相机客户端下载', 'click', '家庭相机客户端下载_Android', 1);
} catch (e) {};
try {
_hmt.push(['_trackEvent', '家庭相机客户端下载', 'click', '家庭相机客户端下载_Android', '1']);
} catch (e) {}
var startTime,
endTime;
setTimeout(function() {
var d = navigator.userAgent.match(/Chrome\/(\d+)/);
try {
startTime = (new Date()).getTime()
var iframe = document.createElement("iframe");
iframe.style.border = "none";
iframe.style.width = "1px";
iframe.style.height = "1px";
iframe.src = 'https://publicfiles.xxx.com/app/yicamera_china_release.apk' //'market://details?id=com.ants360.yicamera'; 安卓下载apk地址
document.body.appendChild(iframe);
// endTime = (new Date()).getTime();
} catch (e) {
}
}, 0)
} else if (browser.versions.ios) {
$.ajax({
url:'https://log.xxx.com/info.gif?cid='+uuids+'&p=ios&data={"data":[{"t":"e","c":"AppInsDownload","ts":'+datelong+',"result":"true"}]}',
type:'get',
success:function(data){
console.log('成功:'+data);
}
})
try {
ga('send', 'event', '家庭相机客户端下载', 'click', '家庭相机客户端下载_iOS', 1);
} catch (e) {};
try {
_hmt.push(['_trackEvent', '家庭相机客户端下载', 'click', '家庭相机客户端下载_iOS', '1']);
} catch (e) {}
setTimeout(function() {
location.href = 'https://itunes.apple.com/cn/app/xxx-zhi-neng-she-xiang-ji/id931168730?l=zh&ls=1&mt=8'; //ios地址
}, 250)
} else {
$.ajax({
url:'https://log.xxx.com/info.gif?cid='+uuids+'&p=android&data={"data":[{"t":"e","c":"AppInsDownload","ts":'+datelong+',"result":"true"}]}',
type:'get',
success:function(data){
console.log('成功:'+data);
}
})
try {
ga('send', 'event', '家庭相机客户端下载', 'click', '家庭相机客户端下载_其他', 1);
} catch (e) {};
try {
_hmt.push(['_trackEvent', '家庭相机客户端下载', 'click', '家庭相机客户端下载_其他', '1']);
} catch (e) {}
setTimeout(function() {
location.href = 'http://app.mi.com/detail/xxx'; //小米应用商店
}, 250)
}
})
$('.a_down_url').on('click', function() {
try {
ga('send', 'event', '家庭相机客户端下载', 'click', '家庭相机客户端下载_Android_APK_附加URL', 1);
} catch (e) {};
try {
_hmt.push(['_trackEvent', '家庭相机客户端下载', 'click', '家庭相机客户端下载_Android_APK_附加URL', '1']);
} catch (e) {}
setTimeout(function() {
location.href = 'http://app.mi.com/detail/xxx'; //小米应用商店
}, 250)
})
console.log(1024)
参考博客:
H5页面唤起指定app或跳转到应用市场(扫描二维码直接下载APP) https://blog.csdn.net/weixin_43085797/article/details/105137059
H5页面实现下载文件(apk、txt等)的三种方式 https://blog.csdn.net/weixin_34221112/article/details/88768839
h5 扫描二维码打开app和点击下载功能的实现 https://www.cnblogs.com/sxz2008/p/8245431.html
使用扫描二维码打开app http://www.javashuo.com/article/p-oiyumdpk-bm.html
h5 扫描二维码打开app和点击下载功能的实现 http://www.javashuo.com/article/p-twxyspeb-z.html
Scheme协议详细介绍 https://segmentfault.com/a/1190000015880556