公司给了一个需求,要求点击一个按钮去唤醒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