一、URL Scheme介绍
1、什么是 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被覆盖掉了,是不能被调用的。
2、URL Scheme应用场景:
客户端应用可以向操作系统注册一个 URL scheme,该 scheme 用于从浏览器或其他应用中启动本应用。通过指定的 URL 字段,可以让应用在被调起后直接打开某些特定页面,比如商品详情页、活动详情页等等。也可以执行某些指定动作,如完成支付等。也可以在应用内通过 html 页来直接调用显示 app 内的某个页面。综上URL Scheme使用场景大致分以下几种:
(1)服务器下发跳转路径,客户端根据服务器下发跳转路径跳转相应的页面
(2)H5页面点击锚点,根据锚点具体跳转路径APP端跳转具体的页面
(3)APP端收到服务器端下发的PUSH通知栏消息,根据消息的点击跳转路径跳转相关页面
(4)APP根据URL跳转到另外一个APP指定页面
3、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。
行为(应用的某个功能页面)
|
scheme://[path][?query]
| |
应用标识 功能需要的参数
|
二、安卓平台设置
1、设置UrlSchemes
打开项目的manifest.json文件,切换到“代码视图”
(1)5+App项目:在manifest.json文件的”plus”->”distribute”->”google”下添加schemes节点数据如下:
"plus": {
"distribute": {
"google": {
"schemes": [
"test"
],
//...
},
//...
},
(2)uni-app项目:把上面的schemes节点数据放到manifest.json的”app-plus”->”distribute”->”android”节点下
(3)值域说明:
为字符串数组,每个字符串为一个urlscheme,使用小写字母(不要使用特殊字符、中文),可设置多个。比如设置为test,那么其他App呼起你的app的scheme协议就是test://。
保存后提交App云端打包生效。
2、浏览器中通过href启动应用
安装应用后,我们可以在html页面中,通过href直接调用应用:
<a href="test://abc">test:<a>
3、uni-app中处理urlscheme启动传递的参数
在App.vue的onShow里可以直接获取
onShow: function() {
var args= plus.runtime.arguments;
if(args){
// 处理args参数,如直达到某新页面等
}
}
4、5+ APP中处理urlscheme启动传递的参数
在其它应用中通过href调用Url Scheme传递过来的值,可以通过plus.runtime.arguments获取,其值为完整的urlscheme字符串,如上面href的值启动应用后获取的plus.runtime.arguments值为“test://abc”。代码示例如下:
document.addEventListener('plusready',function(){
checkArguments();
},false);
// 判断启动方式
function checkArguments(){
console.log("plus.runtime.launcher: "+plus.runtime.launcher);
var args= plus.runtime.arguments;
if(args){
// 处理args参数,如直达到某新页面等
}
}
// 处理从后台恢复
document.addEventListener('newintent',function(){
console.log("addEventListener: newintent");
checkArguments();
},false);
三、iOS平台设置
1、设置UrlSchemes
(1)可视化界面配置:打开项目的manifest.json文件,在“App常用其它设置”页面“iOS设置”下的UrlSchemes中配置scheme字段:
注意:多个scheme使用’,’分割
2、代码视图配置:打开项目的manifest.json文件,切换到“代码视图”
(1)5+App项目:在manifest.json文件的”plus”->”distribute”->”apple”节点下添加urltypes数据
(2)uni-app项目:在manifest.json的”app-plus”->”distribute”->”ios”节点下添加urltypes数据
urltypes节点数据如下:
"plus": {
"distribute": {
"apple": {
"urltypes": [
{
"urlidentifier":"com.xxx.test",
"urlschemes": [
"test"
]
}
],
//...
},
//...
},
//...
},
//...
值域说明:urlidentifier为标识,可自定义,格式为反向域名格式;
urlschemes为要指定的scheme值,字符串数组,使用小写字母,可设置多个。 比如设置为test,那么其他App呼起你的app的scheme协议就是test://。
3、uni-app中处理urlscheme启动传递的参数
在App.vue 中onLaunch 里获取
onLaunch: function() {
plus.globalEvent.addEventListener('newintent', (e)=>{
var args= plus.runtime.arguments;
if(args){
// 处理args参数,如直达到某新页面等
}
});
}
在App.vue的onShow里获取
onShow: function() {
setTimeout(function(){
var args= plus.runtime.arguments;
if(args){
// 处理args参数,如直达到某新页面等
}
},10);
}
h5页面
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes" /><!-- home screen app 全屏 -->
<meta name="apple-mobile-web-app-status-bar-style" content="black" /><!-- 状态栏 -->
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="keywords" content="红叉">
<link rel="icon" href="#" type="image/x-icon"/>
<title>红叉</title>
<script>
;(function(win, lib) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
console.warn('将根据已有的meta标签来设置缩放比例');
var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute('content');
if (content) {
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute('data-dpr', dpr);
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
function refreshRem(){
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
win.addEventListener('resize', function() {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener('pageshow', function(e) {
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === 'complete') {
doc.body.style.fontSize = 12 * dpr + 'px';
} else {
doc.addEventListener('DOMContentLoaded', function(e) {
doc.body.style.fontSize = 12 * dpr + 'px';
}, false);
}
refreshRem();
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
}
flexible.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
}
})(window, window['lib'] || (window['lib'] = {}));
</script>
<script>
// 初始化方法
window.onload = function(){
var dom = document.getElementById("xpopup");
var page = document.getElementById("body");
var ua = window.navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
dom.style.display="black";
page.style.overflow="hidden";
return true; //是微信
}else{
dom.style.display="none";
return false; //不是微信
}
}
//解决ios下 双击放大问题!
var lastTouchEnd = 0;
document.documentElement.addEventListener('touchend', function (event) {
var now = Date.now();
if (now - lastTouchEnd <= 300) {
event.preventDefault();
}
lastTouchEnd = now;
}, false);
//判断打开的浏览器是不是微信浏览器
function isWeiXin(){
var ua = window.navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
return true; //是微信
}else{
return false; //不是微信
}
}
//点击下载方法
function xclick(){
let u = navigator.userAgent;
if (/(iPhone|iPad|iPod|iOS)/i.test(u)) {
window.location = "t7heo9://";
// window.location.href = "https://apps.apple.com/cn/app/%E7%BA%A2%E5%8F%89/id1581706539";
setTimeout(function(){
window.location.href = "https://apps.apple.com/cn/app/%E7%BA%A2%E5%8F%89/id1581706539";
},200);
}else{
window.location = "t7heo9://pay";
setTimeout(function(){
window.location.href = "https://sizex-app.oss-cn-hangzhou.aliyuncs.com/92066ce78abb4d0ab9a5f29a78c005ab/dev-install/1212.apk?uuid=612f6858d3775";
},200);
}
}
</script>
</head>
<body id='body' style="overflow-x:hidden">
<div id="hc">
<!-- 微信浏览器弹窗 -->
<div class="images ximg" id="xpopup">
<img class="w80" src="https://sizex-app.oss-accelerate.aliyuncs.com/92066ce78abb4d0ab9a5f29a78c005ab/base/landing-popup.png">
</div>
<!-- 顶部标题 -->
<div class="image" onclick="xclick()">
<img src="https://sizex-app.oss-accelerate.aliyuncs.com/92066ce78abb4d0ab9a5f29a78c005ab/base/landing-header.png">
</div>
<!-- 下载app领福利 -->
<div class="image" onclick="xclick()">
<img src="https://sizex-app.oss-accelerate.aliyuncs.com/92066ce78abb4d0ab9a5f29a78c005ab/base/landing-content.png">
</div>
<!-- 商品列表 -->
<div class="image" onclick="xclick()">
<img src="https://sizex-app.oss-accelerate.aliyuncs.com/92066ce78abb4d0ab9a5f29a78c005ab/base/landing-product.png">
</div>
<!-- 底部小程序二维码 -->
<div class="image">
<img src="https://sizex-app.oss-accelerate.aliyuncs.com/92066ce78abb4d0ab9a5f29a78c005ab/base/landing-bottom.png">
</div>
</div>
</body>
<style>
* {
padding: 0;
margin: 0;
}
.image{
width: 100%;
}
.images{
height: 100%;
position: absolute;
width: 100%;
z-index: 10;
top: 0px;
background-color: rgba(0,0,0,0.7);
}
.image img{width: 100%;}
.w80{
position: absolute;
width: 80%;
top:30px;
right: 30px;
z-index: 10;
}
.ximg{
position: absolute;
width: 100%;
z-index: 10;
top: 0px;
}
</style>
</html>