返回

浏览器唤醒 app 解决方案汇总

发布时间:2022-10-25 18:57:50 3505
# chrome# safari# webkit# git# 信息

原理及说明:

首先:无论 IOS 还是 Android,浏览器无法预知本地是否安装了某个 APP。
功能实现的本质是浏览器通过 URL_scheme 打开 APP。Twitter 就注册自己能被「twitter://」打开。
补充:如果是 APP 之间的互相跳转是很简单的:IOS 可以使用 UIApplication 的 canOpenUrl 方法来监测 URL_scheme 是否能打开对应的 APP。exp:如果「twitter://」检测能被打开,也就说明本地安装了 Twitter 。再用 UIApplication 的 openURL 方法,就能打开 Twitter 了。Android 中的做法类似。

实现方案:以 IOS9 为一个分水岭:

iOS7/iOS8:

iOS 中默认通过 Safari 打开 URL scheme,方法一般如下两种:

1,直跳方式:点击链接、修改 window.location 等。

唤醒你的 APP
或者:
window.location.href = schemeUrl;

PS:如果 APP 唤醒失败或者未安装的情况,有可能会调到 404 页面。很影响用户体验。一般情况会让他跳到其他页面或者下载 APP

2,iframe 方式:在 body 上添加 iframe,设置src属性为跳转的URL scheme。

这种方法不会引起页面可见的变化(页面变成一个新页面),不会导致浏览器的历史记录的变化。
实现思路:

<a href="APP下载地址">下载或打开APPa>
<script>
$('a').click(function() {
var ifr = document.createElement('iframe');
ifr.src = '自定义 URL scheme';
ifr.style.display = 'none';
document.body.appendChild(ifr);
setTimeout(function(){
document.body.removeChild(ifr);
}, 3000);
});
script>

实现思路:点击 a 标签,首先会尝试打开 URL scheme,如果成功,就唤起 APP;如果失败,则跳转到 href 属性,即下载页。
(该方案在很多安卓机型有问题)
Android

$('a').click(function() {
location.href = '自定义 URL scheme';
t = Date.now();
setTimeout(function(){
if (Date.now() - t < 1200) {
location.href = 'Android 下载地址';
}
}, 1000);
return false;
}

理想过程是这样:浏览器尝试打开 URL scheme,在 1 秒计时后,检查当前时间,如果实际时间已过 1200 毫秒,说明唤起 APP 成功(唤起 APP 会让浏览器的定时器变慢);如果没超过 1200 毫秒,很可能是没有安装应用,就跳到下载地址。
或者:

var ifr = document.createElement('iframe');
ifr.src = 'com.baidu.tieba://';
ifr.style.display = 'none';
document.body.appendChild(ifr);
var openTime = +new Date();
window.setTimeout(function(){
document.body.removeChild(ifr);
if( (+new Date()) - openTime > 2500 ){
window.location = 'http://exam.com/xxxx.apk';
}
},2000)

这种方案不稳定:因为 Android 是基于 Linux 的分时多任务的,setTimeout 的基准偏差可能会没那么大。

但如果设置比较小的运行间隔(<30ms),在浏览器或者 webview 中,应用切换到后台,setInterval 会被很明显的延迟执行,比如设置一个运行间隔 20ms,总计运行 100 次的定时器,如果页面一直处于前台,则 100 次跑完,总耗时与 100x20=2000ms 不会有太大差异,但页面在后台运行时,此时间会明显超过 2000ms。可以利用这一点来实现是否成功打开 APP 检测及回调。

function openApp(openUrl, appUrl, action, callback) {
//检查app是否打开
function checkOpen(cb){
var _clickTime = +(new Date());
function check(elsTime) {
if ( elsTime > 3000 || document.hidden || document.webkitHidden) {
cb(1);
} else {
cb(0);
}
}
//启动间隔20ms运行的定时器,并检测累计消耗时间是否超过3000ms,超过则结束
var _count = 0, intHandle;
intHandle = setInterval(function(){
_count++;
var elsTime = +(new Date()) - _clickTime;
if (_count>=100 || elsTime > 3000 ) {
clearInterval(intHandle);
check(elsTime);
}
}, 20);
}

//在iframe 中打开APP
var ifr = document.createElement('iframe');
ifr.src = openUrl;
ifr.style.display = 'none';
if (callback) {
checkOpen(function(opened){
callback && callback(opened);
});
}

document.body.appendChild(ifr);
setTimeout(function() {
document.body.removeChild(ifr);
}, 2000);
}

可以通过 document.hidden 或 document.[webkit|moz|ms] Hidden 来判断页面是否被置入后台(即应用被唤起),或 visibilitychange 事件,但对于 Android 4.4 版本一下则不支持。

iOS9

在 iOS 9 上,iframe 方案变得不可用。
按不能使用之前 Android 的代码,因为在打开自定义 URL scheme 时,会弹出对话框,询问是否用 xx 应用来打开。往往用户还没来得及点击打开,定时器又触发了,导致跳到 App Store。
可以在尝试打开 URL scheme 后,再加一个页面跳转,这样对话框会被覆盖,再刷新页面,就能无需确认唤起 APP:

$('a').click(function() {
location.href = '自定义 URL scheme';
location.href = '下载页';
location.reload();
}

下载页延时 2 秒跳转到 App Store。

APP 已安装这是没问题的,但如果 APP 未安装,跳 App Store 的请求会失败。
这时可以使用两个定时器:

$('a').click(function() {
location.href = '自定义 URL scheme';
setTimeout(function() {
location.href = '下载页';
}, 250);
setTimeout(function() {
location.reload();
}, 1000);
}

不过在 iOS9 中其实是支持 universal link 的,就是一个 http 域名形式,在微信中都可以唤起 APP。如果未安装的话,可以直接引导用户去 APP store 下载。

PS:没有完美的解决方案。

微信中打开

因为微信将唤起本地 APP 的接口给禁了,所以微信中是不能直接唤起 APP 的,一般做法是提示用户在浏览器中打开,之后的流程还是我们上面讲的内容。

但是,在 iOS9 中,这个限制是可以突破的,也就是说可以直接唤起 APP。方法就是使用我们上文提到的 universal link。

在 Android 和 iOS8 及其以下系统中,我们可以利用腾讯的亲儿子:应用宝。把你的唤起地址配置成你 APP 的应用宝地址,微信中跳转到这个地址后,如果用户已经安装了 APP,则可直接唤起,如果没有安装,则可直接点击下载。
PS:一般需要一个中间页面引导用户在尾部浏览器打开。微信唤醒 APP 默认只能到达首页。

需要判断的使用场景:
1,用户是在手机浏览器打开
2,微信浏览器打开
3,PC 中打开
4,universal link 是否被关闭
。。。

其他实现方案:

魔窗的 mLink。只要你加了魔窗的 sdk,就可以通过类似 “​​https://s.mlinks.cc/AA01​​” 的链接,在任何环境下打开你的 APP,兼容超过 600 台以上安卓机型的第三方主流浏览器。不管是在手机浏览器中,还是在微信中打开,你可以指定唤起 APP 后直达 APP 中的某个页面或内容(某个促销商品等),就算用户没安装 APP,点击下载安装之后,再打开,还是跳转到指定的页面。

魔窗使用教程:

需要准备的材料:

1,微信分享 AppID
2,应用宝微下载链接
3,IOS :Bundle ID、URI Scheme、下载地址、Team ID(如果配置了 Universal Link)
4,Android: 包名、URI Scheme、下载地址

后台生成极光魔链位信息

JS 使用:
1,直接引用 mLink JS 文件。不要下载之后放入项目