H5 页面唤起APP或跳转到下载APP的某个链接地址。总结如下:
在 IOS 中, 系统版本在 8 以下时,可以监听页面的 pagehide / visibilitychange 事件。 系统版本大于 8 以后,可以使用 universal Link 或 URL scheme 进行跳转。
// IOS 的唤起
function
vForIOS(urlScheme, storeURL, fallback, universalLink) {
var
tid = deferFallback(TIMEOUT_IOS, storeURL, fallback);
if
(parseInt(os.version, 10) < 8) {
bindPagehideEvent(tid);
}
else
{
bindVisibilityChangeEvent(tid);
}
if
(parseInt(os.version, 10) > 8 && os.name ==
'iOS'
) {
// 通过universalLink
if
(universalLink === undefined) {
universalLink = urlScheme;
}
else
{
clearTimeout(tid);
}
vLocation(universalLink);
}
else
{
vIframe(urlScheme);
}
}
|
在安卓中, 安卓版本 4.4.4 以上机型的安卓自带浏览器、chrome 浏览器,需要通过 intent 跳转 【详情请见 https://developer.chrome.com/multidevice/android/intents】,其他浏览器大多数可通过 url scheme 唤起。但由于唤起APP后浏览器并无回调事件,我们很难判断是否已成功拉起APP,比较通用的解决办法是判断计时器是否变慢,若APP启动浏览器最小化入后台将会导致计时器变慢,即为实际事件间隔大于理想时间间隔。若未变慢则判断为未成功拉起APP,则跳转至下载地址。此判断代码如下:
function
deferFallback(timeout, storeURL, fallback) {
var
clickedAt =
new
Date().getTime();
return
setTimeout(
function
() {
var
now =
new
Date().getTime();
if
(isPageVisible() && now - clickedAt < timeout + INTERVAL) {
fallback(storeURL);
}
}, timeout);
}
|
安卓系统中,不同浏览器对唤起APP有严重的兼容性问题,主要处理方案有以下几种:
- 通过改变 window.location.href
- 通过创建 iframe 并为其 src 赋值
- 通过 intent
- 通过制造不可见 a 链接,并触发点击时间
// 打开页面的方式可能
// 1. 通过改变location
function
vLocation(urlScheme) {
window.location.href = urlScheme;
}
// 2. 通过ifreame
function
vIframe(urlScheme) {
setTimeout(
function
() {
var
iframe = createHiddenIframe(
'appLauncher'
);
iframe.src = urlScheme;
}, 100);
}
// 3. 通过intent
function
vIntent(launchURI) {
if
(browser.name ==
'Chrome'
) {
move();
}
else
{
setTimeout(move, 100);
}
function
move() {
// window.top.location.href = launchURI;
window.location.href = launchURI
}
}
// 3. 通过添加出发alink
function
vAlink(launchURI) {
var
aLink = document.createElement(
"a"
);
aLink.setAttribute(
"href"
, launchURI);
aLink.style.display =
"none"
;
document.body.appendChild(aLink);
var
event = document.createEvent(
"HTMLEvents"
);
event.initEvent(
"click"
, !1, !1);
aLink.dispatchEvent(event)
}
// IOS 中的 可见性事件
function
bindPagehideEvent(tid) {
window.addEventListener(
'pagehide'
,
function
clear() {
if
(isPageVisible()) {
clearTimeout(tid);
window.removeEventListener(
'pagehide'
, clear);
}
});
}
function
bindVisibilityChangeEvent(tid) {
document.addEventListener(
'visibilitychange'
,
function
clear() {
if
(isPageVisible()) {
clearTimeout(tid);
document.removeEventListener(
'visibilitychange'
, clear);
}
});
}
function
isPageVisible() {
var
attrNames = [
'hidden'
,
'webkitHidden'
];
for
(
var
i = 0, len = attrNames.length; i < len; i++) {
if
(
typeof
document[attrNames[i]] !==
'undefined'
) {
return
!document[attrNames[i]];
}
}
return
true
;
}
|
已知的浏览器兼容问题:
- 上述 chrome 和 Android Browser 可以使用 intent 的方式拉起 app
- QQ 浏览器 无法正确判断计时器是否变慢
- 微信浏览器 和 百度浏览器 无法唤起 app 除非加入其白名单
- 安卓4.4.4以前的 UC浏览器无法正确识别为 【安卓系统】需要单独设置判断条件
另: 研究京东唤起APP的代码时,其对百度浏览器做了如下操作,但我们对此的尝试并为成功,如下为其代码, 希望对后续研究此项的同学有帮助 :
function
ai(aA) {
var
aD = ay(aA,
true
);
var
aB = aA.universalLinksUrl +
"/ul/ul.action?"
+ aD;
if
(navigator.userAgent.indexOf(
"baidubrowser"
) >= 0) {
window.location.href = aB
}
else
{
var
az = document.createElement(
"a"
);
az.setAttribute(
"href"
, aB);
az.style.display =
"none"
;
document.body.appendChild(az);
var
aC = document.createEvent(
"HTMLEvents"
);
aC.initEvent(
"click"
, !1, !1);
az.dispatchEvent(aC)
}
}
|