移动端h5调起手机app
当所做的h5页面在微信端打开时,想要调起手机内的app,一般我们会用scheme协议监测本地的应用,要是没有则下载app,有的话就直接打开。但是微信上是屏蔽了,所以我们要是在微信端,则得提示用户用浏览器打开页面再进行监测本地的应用。tips:如何判断是否在微信浏览器端:const u = navigator.userAgent;const isWeixin = u.toLowerCase().in
当所做的h5页面在微信端打开时,想要调起手机内的app,一般我们会用scheme协议监测本地的应用,要是没有则下载app,有的话就直接打开。
但是微信上是屏蔽了,所以我们要是在微信端,则得提示用户用浏览器打开页面再进行监测本地的应用。
tips:如何判断是否在微信浏览器端:
const u = navigator.userAgent;
const isWeixin = u.toLowerCase().indexOf("micromessenger") !== -1;
一、scheme协议
scheme 是一种页面之间跳转的协议,不仅可以用于app之间进行跳转,还可以用于 H5 页面跳转到app页面。
无论Android还是IOS,都可以通过在H5页面中打开 scheme 协议的地址,从而打开本地app。
[scheme]://[host][:port]/[path]?[query]
// 例子:
sinaweibo://userinfo?uid=3177804914
scheme: 协议名称(由开发人员自定义)(必要,其他都是可选)
host: 域名
port:端口
path: 页面路径
query: 请求参数
每个app的这些协议都不一样根据自己的情况去查找,有些App分IOS和Android的协议是相同的,有些又是不一致的。
那么scheme协议在原生的app内是怎么设置的呢:
<activity
android:name=".ui.main.ui.activity.SchemeFirstActivity"
android:screenOrientation="portrait">
<!--Android 接收外部跳转过滤器-->
<!--要想在别的App上能成功调起App,必须添加intent过滤器-->
<intent-filter>
<!-- 协议部分配置 ,注意需要跟web配置相同-->
<!--协议部分, sinaweibo://from?type=yangchong -->
<data android:scheme="sinaweibo"
android:host=""
android:path="/userinfo"
android:port=""/>
<!--下面这几行也必须得设置-->
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
二、在浏览器中打开 scheme
注意这步得是在除微信浏览器之外的浏览器中进行,因为在微信浏览器里scheme不起作用。
思路:
首先在本地打开scheme协议,等2秒之后(因为浏览器没有提供是否能打开scheme协议的回调函数,所以只能在这2秒内进行是否离开浏览器的监测判断),要是浏览器能弹出选择跳转app的弹窗,用户选择打开之后离开浏览器之后,那么我们就不弹出要下载app的apk,否则就打开这个apk进行下载。
本次用一个app做例子:
const u = navigator.userAgent;
const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端
const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
function click(){
if(isAndroid){
// 安卓的scheme协议跳转
window.location.href = "jegotrip://";
checkOpen();
}else if(isIOS){
// 做个例子,因为也不知道ios的是不是这个
window.location.href = "jegotrip://";
checkOpen();
}
}
/**
* 获取页面隐藏属性的前缀
* 如果页面支持 hidden 属性,返回 '' 就行
* 如果不支持,各个浏览器对 hidden 属性,有自己的实现,不同浏览器不同前缀,遍历看支持哪个
*/
function getPagePropertyPrefix() {
const prefixes = ["webkit", "moz", "ms", "o"];
let correctPrefix;
if ("hidden" in document) return "";
prefixes.forEach(prefix => {
if (`${prefix}Hidden` in document) {
correctPrefix = prefix;
}
});
return correctPrefix || false;
}
/**
* 判断页面是否隐藏(进入后台)
*/
function isPageHidden() {
const prefix = getPagePropertyPrefix();
if (prefix === false) return false;
const hiddenProperty = prefix ? `${prefix}Hidden` : "hidden";
return document[hiddenProperty];
}
/**
* 获取判断页面 显示|隐藏 状态改变的属性
*/
function getVisibilityChangeProperty() {
const prefix = getPagePropertyPrefix();
if (prefix === false) return false;
return `${prefix}visibilitychange`;
}
/**
* 检测是否唤端成功
*/
function checkOpen() {
const visibilityChangeProperty = getVisibilityChangeProperty();
const timer = setTimeout(() => {
const hidden = isPageHidden();
if (!hidden) {
// 端口唤起失败,下载apk
if(isAndroid) {
window.location = 'https://at.umtrack.com/ry0bya';
}else {
window.location = 'https://at.umtrack.com/SH1vyi';
}
}
}, 2000);
if (visibilityChangeProperty) {
document.addEventListener(visibilityChangeProperty, res => {
clearTimeout(timer);
});
return;
}
window.addEventListener("pagehide", () => {
clearTimeout(timer);
});
}
效果图:
注意,有时会有需求说,希望能主动触发click事件,让一进入页面就监测,但是由于浏览器会有拦截自动打开app,所以要特别说明
// 有时在进入页面的时候,直接调用click方法不会触发,可以试试下面的方法
// 模拟在移动端的点击
let theEvent = document.createEvent("Events");
theEvent.initEvent("click", true, true);
document.getElementsByClassName("toAppLink")[0].dispatchEvent(theEvent);
更多推荐
所有评论(0)