一个已经上架了很久的浙里办应用,用户突然让在有市场名称的地方加点击跳转到手机地图App导航的功能
作为敬业的乙方,当然马(bu)上(xiang)动工实现乙方的需求。
浙里办环境下
环境准备
浙里办上架的应用可以同时在浙里办App、浙里办微信小程序以及浙里办支付宝小程序三个环境下使用,所以要将三种情况都考虑到。
1、浙里办App环境
在index.html文件里引入
<script type="text/javascript" src="//assets.zjzwfw.gov.cn/assets/ZWJSBridge/1.1.0/zwjsbridge.js"></script>
2、浙里办微信小程序环境
需要借助weixin-js-sdk和uuid,可以直接通过包管理工具下载,在使用的地方引入。uuid用来获取设备的唯一标识
npm install weixin-js-sdk
npm install uuid
import wx from 'weixin-js-sdk';
import {v4 as uuid} from 'uuid' // 使用ECMAScript 模块语法引入有可能会报错,报错就是用下面的CommonJS 语法引入即可
// 或者
const {v4: uuid} = require('uuid')
*在页面加载的时候写入以下配置
// 跳转地图app相关配置
wx.config({
debug: false,
appId: '应用的appid,可以在IRS应用发布系统上查找,或直接使用微信小程序的appid',
timestamp: new Date().getTime(),
nonceStr: uuid().toString().replace(/-/g, ''),
signature: '应用的appkey,同样可以在IRS应用发布系统上找到',
jsApiList: ['openLocation'],
});
此配置一定要填写正确,不然功能不会实现
3、浙里办支付宝小程序 在index.html文件里引入
<script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js"></script>
功能实现源代码
直接上代码
import wx from 'weixin-js-sdk'
const {ZWJSBridge, ap} = window
const openMapApp = (dataObj) => {
// 用来判断当前环境
const bIsWeixinMini = window.navigator.userAgent.toLowerCase().includes('miniprogram/wx') || window.__wxjs_environment === 'miniprogram'
const sUserAgent = window.navigator.userAgent.toLowerCase();
const bIsDtDreamApp = sUserAgent.indexOf('dtdreamweb') > -1;
if (bIsDtDreamApp) {// 浙里办APP环境
if(dataObj.longitude && dataObj.latitude){
const openUrl = `zwfw://openThirdMap?longitude=${dataObj.longitude}&latitude=${dataObj.latitude}&locationName=${dataObj.name}`;
ZWJSBridge.openLink({
url: openUrl,
}).then((result) => {
console.log(result);
}).catch((error) => {
console.log(error);
});
}else{
Toast.show({
content: '获取当前位置失败,请重试',
});
}
} else if(bIsWeixinMini){ // 浙里办微信小程序环境
wx.ready(() => {
wx.openLocation({
longitude: parseFloat(dataObj.longitude),
latitude: parseFloat(dataObj.latitude),
name: dataObj.name,
address: dataObj.address,
});
})
} else{ // 浙里办支付宝小程序
window.ap.openLocation({
longitude: dataObj.longitude,
latitude: dataObj.latitude,
name: dataObj.name,
address: dataObj.address,
});
}
};
module.exports = {
openMapApp: openMapApp
}
非浙里办环境下功能的实现
我解决了包括微信小程序、App以及h5三种环境下的实现,以及Android和ios差异性的解决。上源码
注:h5端实现此功能需要借助callapp-lib
下载使用
npm install callapp-lib
import CallApp from 'callapp-lib';
openMapApp () {
//#ifdef MP
// 只适用于微信小程序
uni.openLocation({
longitude: parseFloat(this.mtkData.market.longitude),
latitude: parseFloat(this.mtkData.market.latitude),
name: this.mtkData.market.name,
address: this.mtkData.market.address,
scale: 18,
success: res => {
console.log(res)
}
})
//#endif
//#ifdef APP-PLUS
let latitude = this.mtkData.market.latitude
let longitude = this.mtkData.market.longitude
let name = this.mtkData.market.name
let url = "";
if (plus.os.name == "Android") {//判断是安卓端
plus.nativeUI.actionSheet({//选择菜单
title: "选择应用",
cancel: "取消",
buttons: [{title: "腾讯地图"},{title: "百度地图"}, {title: "高德地图"}]
}, function(e) {
switch (e.index) {
//下面是拼接url,不同系统以及不同地图都有不同的拼接字段
case 1:
//注意referer=xxx的xxx替换成你在腾讯地图开发平台申请的key
url = `qqmap://map/geocoder?coord=${latitude},${longitude}&referer=xxx`;
break;
case 2:
url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&coord_type=gcj02&src=andr.baidu.openAPIdemo`;
break;
case 3:
url = `androidamap://viewMap?sourceApplication=appname&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`;
break;
default:
break;
}
if (url != "") {
url = encodeURI(url);
//plus.runtime.openURL(url,function(e){})调起手机APP应用
plus.runtime.openURL(url, function(e) {
plus.nativeUI.alert("本机未安装指定的地图应用");
});
}
})
} else {
// iOS上获取本机是否安装了百度高德地图,需要在manifest里配置
// 在manifest.json文件app-plus->distribute->apple->urlschemewhitelist节点下添加
//(如urlschemewhitelist:["iosamap","baidumap"])
plus.nativeUI.actionSheet({
title: "选择地图应用",
cancel: "取消",
buttons: [{title: "腾讯地图"},{title: "百度地图"}, {title: "高德地图"}]
}, function(e) {
switch (e.index) {
case 1:
url = `qqmap://map/geocoder?coord=${latitude},${longitude}&referer=xxx`;
break;
case 2:
url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&content=${name}&src=ios.baidu.openAPIdemo&coord_type=gcj02`;
break;
case 3:
url = `iosamap://viewMap?sourceApplication=applicationName&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`;
break;
default:
break;
}
if (url != "") {
url = encodeURI(url);
plus.runtime.openURL(url, function(e) {
plus.nativeUI.alert("本机未安装指定的地图应用");
});
}
})
}
//#endif
//#ifdef H5
// 此处打开了一个自定义的popup,通过点击popup的按钮执行h5OpenApp方法
this.$refs.popup1.open()
//#endif
},
//h5打开手机导航app
h5OpenApp (index) {
let _this = this
let name = this.mtkData.market.name
let lat1 = this.mtkData.market.latitude
let lon1 = this.mtkData.market.longitude
let system = navigator.userAgent
let isAndroid = system.indexOf('Android') > -1 || system.indexOf('Linux') > -1; //android终端或者uc浏览器
let isiOS = !!system.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
console.log('系统', isAndroid, isiOS)
if (index === 1) { //打开高德地图
let scheme1 = ''
if (isAndroid) {
scheme1 = 'androidamap'
} else if (isiOS) {
scheme1 = 'iosamap'
}
const options = {
scheme: {
protocol: scheme1
},
intent: {
package: '',
scheme: ''
},
// appstore: '填写appstore的下载地址',
// yingyongbao: '填写应用宝的下载地址',
// fallback: '填写唤端失败后跳转的地址。'
logFunc: (status) => {
_this.$refs.popup1.close()
console.log(status, 'status')
if (status === 'failure') {
uni.showModal({
title: '提示',
content: '打开失败,请确定高德地图是否已下载。'
})
}
}
}
const callLib = new CallApp(options)
callLib.open({
// param: `sourceApplication=appname&poiname=衢州新农都&&lat=${lat1}&lon=${lon1}dev=0`,
param: {
sourceApplication: 'appname',
poiname: this.mtkData.market.name,
lat: lat1,
lon: lon1,
dev: 0
},
path: 'viewMap'
})
} else if (index === 2) { //打开百度地图
if (isAndroid) {
const options = {
scheme: {
protocol: 'baidumap'
},
intent: {
package: '',
scheme: ''
},
// appstore: '填写appstore的下载地址',
// yingyongbao: '填写应用宝的下载地址',
// fallback: '填写唤端失败后跳转的地址。'
logFunc: (status) => {
_this.$refs.popup1.close()
console.log(status, 'status')
if (status === 'failure') {
uni.showModal({
title: '提示',
content: '打开失败,请确定百度地图是否已下载。'
})
}
}
}
const callLib = new CallApp(options)
callLib.open({
// param: `sourceApplication=appname&poiname=衢州新农都&&lat=${lat1}&lon=${lon1}dev=0`,
param: {
location: lat1 + ',' + lon1,
title: name,
coord_type: 'gcj02',
src: 'andr.baidu.openAPIdemo'
},
path: 'map/marker',
callback: res => {
}
})
} else if (isiOS) {
const options = {
scheme: {
protocol: 'baidumap'
},
intent: {
package: '',
scheme: ''
},
// appstore: '填写appstore的下载地址',
// yingyongbao: '填写应用宝的下载地址',
// fallback: '填写唤端失败后跳转的地址。'
logFunc: (status) => {
_this.$refs.popup1.close()
console.log(status, 'status')
if (status === 'failure') {
uni.showModal({
title: '提示',
content: '打开失败,请确定百度地图是否已下载。'
})
}
}
}
const callLib = new CallApp(options)
callLib.open({
// param: `sourceApplication=appname&poiname=衢州新农都&&lat=${lat1}&lon=${lon1}dev=0`,
param: {
location: lat1 + ',' + lon1,
title: name,
content: name,
coord_type: 'gcj02',
src: 'ios.baidu.openAPIdemo'
},
path: 'map/marker',
callback: res => {
console.log(res)
}
})
}
}
},
补充:更为便捷的方式
通过点击跳转到地图服务的浏览器web网页,网页会提醒下载或跳转到对应的地图App。
// 高德地图
window.open(`https://uri.amap.com/marker?position=${lon1},${lat1}&name=${name}&coordinate=gaode&callnative=1`)
// 百度地图
window.open(`http://api.map.baidu.com/marker?location=${lat1},${lon1}&title=${name}&content=${name}&output=html&src=webapp.baidu.openAPIdemo`)
// 腾讯地图
window.open(`https://3gimg.qq.com/lightmap/v1/marker/?marker=coord:${lat1},${lon1};title:${name};addr:${name}&referer=在腾讯位置服务平台申请的应用的名称&key=在腾讯位置服务平台申请的应用的key`)