在H5中唤起APP原理:通过Scheme协议打开APP
需求
在用户浏览网页时,如何能判断该用户是否安装了该应用。如果安装了该应用,就直接打开该应用;如果没有安装该应用,就下载该应用。
跳转APP方式
方法有好几种,这里我们详细就URL Scheme方式讲解一下。(其他的有时间再说)
URL Scheme
什么是 URL Scheme?URL Scheme的作用?
对于Android,Scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面;通过scheme协议,服务器可以定制化告诉App跳转那个页面,可以通过通知栏消息定制化跳转页面,可以通过H5页面跳转页面等。
对于iOS,我们都知道苹果手机中的APP都有一个沙盒,APP就是一个信息孤岛,相互是不可以进行通信的,但是苹果还是给出了一个可以在app之间跳转的方法:URL Scheme。iOS的APP可以注册自己的URL Scheme,URL Scheme是为方便app之间互相调用而设计的,我们可以通过系统的OpenURL来打开该app,并可以传递一些参数。
URL Scheme必须能唯一标识一个APP,如果你设置的URL Scheme与别的APP的URL Scheme冲突时,你的APP不一定会被启动起来。因为当你的APP在安装的时候,系统里面已经注册了你的URL Scheme。一般情况下,是会调用先安装的app,但是iOS的系统app的URL Scheme肯定是最高的,所以我们定义URL Scheme的时候,尽量避开系统app已经定义过的URL Scheme。
简单的说,URL Scheme就是一个可以让app相互之间可以跳转的协议。每个app的URL Scheme都是不一样的,如果存在一样的URL Scheme,那么系统就会响应先安装那个app的URL Scheme,因为后安装的app的URL Scheme被覆盖掉了,是不能被调用的。
URL Scheme应用场景
客户端应用可以向操作系统注册一个 URL scheme,该 scheme 用于从浏览器或其他应用中启动本应用。通过指定的 URL 字段,可以让应用在被调起后直接打开某些特定页面,比如商品详情页、活动详情页等等。也可以执行某些指定动作,如完成支付等。也可以在应用内通过 html 页来直接调用显示 app 内的某个页面。综上URL Scheme使用场景大致分以下几种:
(1)服务器下发跳转路径,客户端根据服务器下发跳转路径跳转相应的页面
(2)H5页面点击锚点,根据锚点具体跳转路径APP端跳转具体的页面
(3)APP端收到服务器端下发的PUSH通知栏消息,根据消息的点击跳转路径跳转相关页面
(4)APP根据URL跳转到另外一个APP指定页面
URL Scheme协议格式
客户端自定义的 URL 作为从一个应用调用另一个的基础,遵循 RFC 1808 (Relative Uniform Resource Locators) 标准。这跟我们常见的网页内容 URL 格式一样。
一个普通的 URL 分为几个部分:scheme、host、relativePath、query。
比如:http://www.baidu.com/s?rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709,这个URL中,scheme 为 http,host 为www.baidu.com,relativePath 为 /s,query 为 rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709。
一个应用中使用的 URL 例子(该 URL 会调起车辆详情页):uumobile://mobile/carDetail?car_id=123456,其中 scheme 为 uumobile,host 为mobile,relativePath 为 /carDetail,query 为 car_id=123456。
简单来说,URL scheme的格式是:
[scheme]://[host]/[path]?[query]
几个常用的URL Scheme平台:
QQ: mqq://
微信: weixin://https://github.com/alibaba/butterfly
淘宝: taobao://
支付宝: alipay://
微博: sinaweibo://
优点:
同时支持Android和iOS平台
总结:
基本大部分解决方案的原理都是如此:先打开scheme协议来唤起app,如果超时了(比如超时2s)那么就跳转到app下载页。
code
<div class="home-button" @click="joinEvents">跳转到app内</div>
<div class="download-btn" @click="downloadBtn">下载app</div>
// vue3.0下实现代码
onMounted(async (): Promise<void> => {
document.addEventListener('visibilitychange', function () {
//监听当前页面有没有被移到后台
state.hidden = document.hidden
console.log('document hidden', document.hidden)
})
})
// 先打开scheme协议来唤起app,如果超时了(比如超时2s)那么就跳转到app下载页
const joinEvents = () => {
let scheme = ' taobao://event?eventID=' // scheme链接找客户端
if (isAnd()) {
console.log('安卓跳转app')
openLocation(scheme + state.activityData.eventID)
} else {
console.log('ios跳转app')
openLocation(scheme + state.activityData.eventID)
}
setTimeout(() => {
console.log('!state.hidden', !state.hidden)
if (!state.hidden) downloadBtn() //当前页面依然在说明没有下载App,所以跳转至商店下载
}, 2000)
}
// 打开app,并跳转到app内对应的页面
const openLocation = (url: any) => {
try {
console.log('openLocation跳转:', url)
window.location.href = url
} catch (e) {
console.log('openLocation错误', e)
}
}
// app下载
const downloadBtn = () => {
if (isAnd()) {
console.log('安卓下载')
//链接找安卓开发要
window.location.href =
'https://play.google.com/store/apps/details?id=123456'
} else {
console.log('ios下载')
// 链接找ios开发要
window.location.href = 'https://itunes.apple.com/us/app/12345'
}
}