前提:在企業(yè)微信中開(kāi)發(fā)自建應(yīng)用食听,需要獲取用戶(hù)的實(shí)際地址(一波三折)(比如:上海市迪士尼樂(lè)園~)
“一波”:
最初的企業(yè)微信版本的獲取經(jīng)緯度與實(shí)際地址的方式是使用的百度地圖JavaScript API(需要用戶(hù)授權(quán)才可以正常使用)。
“一折”:
遇到的問(wèn)題:移動(dòng)端的兼容性是很難測(cè)試的全面的倔毙,因?yàn)槭袌?chǎng)上手機(jī)機(jī)型廠(chǎng)商、系統(tǒng)版本等五花八門(mén)阅仔,公司的測(cè)試機(jī)型有限傍菇,所以并沒(méi)有測(cè)試出來(lái)兼容性問(wèn)題。等上線(xiàn)之后勉盅,問(wèn)題出來(lái)了,很多用戶(hù)會(huì)提示“用戶(hù)拒絕授權(quán)地理位置”顶掉,是什么原因?qū)е碌哪夭菽龋课覀儊?lái)看一下僅使用百度地圖JS API的代碼:
getCurrentPositionByBaidu() {
return new Promise(function(resolve, reject) {
let geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(
function(r) {
if (this.getStatus() === BMAP_STATUS_SUCCESS) {
//精度為undefined 代表用戶(hù)拒絕授權(quán)地理位置
if (r.accuracy === null) {
reject({
type: '1', //授權(quán)失敗
errorMessage: '用戶(hù)拒絕授權(quán)地理位置',
});
}
let myGeo = new BMap.Geocoder();
myGeo.getLocation(new BMap.Point(r.longitude, r.latitude), result => {
if (result) {
resolve({
longitude: r.longitude,
latitude: r.latitude,
address: result.address,
});
} else {
reject({
type: '2', //詳細(xì)地址解析失敗
errorMessage: '詳細(xì)地址解析失敗',
});
}
});
} else {
reject({
type: '0', //百度地圖api調(diào)用出錯(cuò)
errorMessage: '百度地圖api調(diào)用出錯(cuò)',
});
}
},
function(err) {
//沒(méi)有網(wǎng)絡(luò)的返回值
if (err.errorCode === 3) {
reject({
type: '3', //超時(shí),沒(méi)有網(wǎng)絡(luò)
errorMessage: '超時(shí)一喘,沒(méi)有網(wǎng)絡(luò)',
});
} else {
reject({
type: '4', //未知的錯(cuò)誤
errorMessage: 'unknown error',
});
}
}
)
}
}
我們從代碼上可以看出驱还,當(dāng)百度地圖的api返回精確度(accuracy)為null時(shí),獲取到的經(jīng)緯度非常不準(zhǔn)確凸克,所以我們默認(rèn)是用戶(hù)拒絕授權(quán)了地理位置议蟆。經(jīng)過(guò)對(duì)比排查,發(fā)現(xiàn)導(dǎo)致這個(gè)問(wèn)題的原因是萎战,在企業(yè)微信環(huán)境中咐容,沒(méi)有喚起百度地圖的授權(quán)彈框。
“二折”
我們?nèi)绾卧谄髽I(yè)微信環(huán)境中喚起百度地圖的授權(quán)彈框呢蚂维?翻了一波百度地圖的api文檔戳粒,發(fā)現(xiàn)并沒(méi)有提供相關(guān)的api路狮,這個(gè)授權(quán)彈框是瀏覽器的行為,看著像是部分機(jī)型的企業(yè)微信禁掉了這個(gè)行為蔚约。
從百度地圖的角度沒(méi)有找到解決辦法奄妨,我想著是不是企業(yè)微信的客戶(hù)端api有破解之道呢?
哎發(fā)現(xiàn)了企業(yè)微信提供的getLocation方法:
//獲取地理位置接口
wx.getLocation({
type: 'wgs84', // 默認(rèn)為wgs84的gps坐標(biāo)苹祟,如果要返回直接給openLocation用的火星坐標(biāo)砸抛,可傳入'gcj02'
success: function (res) {
var latitude = res.latitude; // 緯度,浮點(diǎn)數(shù)树枫,范圍為90 ~ -90
var longitude = res.longitude; // 經(jīng)度直焙,浮點(diǎn)數(shù),范圍為180 ~ -180砂轻。
var speed = res.speed; // 速度奔誓,以米/每秒計(jì)
var accuracy = res.accuracy; // 位置精度
}
});
我們使用官方demo鏈接嘗試了一下這個(gè)api:http://open.work.weixin.qq.com/api/jsapidemo
驚喜!調(diào)用企業(yè)微信的api搔涝,彈起了企業(yè)微信的授權(quán)框:
所以我們想厨喂,通過(guò)企業(yè)微信的位置授權(quán)方式,應(yīng)該是已經(jīng)把a(bǔ)pp的位置權(quán)限控制好了庄呈,但是我們發(fā)現(xiàn)企業(yè)微信的getLocation方法的返回值只有經(jīng)緯度杯聚,然而我們需要獲取用戶(hù)的實(shí)際地址,所以我們打算:使用企業(yè)微信的授權(quán)+百度地圖的經(jīng)緯度+百度地圖的逆地址解析功能結(jié)合的方式抒痒,代碼變化如下:
//簡(jiǎn)寫(xiě)
getCurrentPositionByQYWX(){
wx.getLocation().then(
()=>{
getCurrentPositionByBaidu()
}
)
}
經(jīng)過(guò)測(cè)試,這個(gè)方式并沒(méi)有解決所有用戶(hù)的授權(quán)問(wèn)題。部分手機(jī)仍然需要百度地圖的授權(quán)才可以正常使用。
腦殼疼~
“三折”
我們從代碼本身來(lái)找找解決問(wèn)題的方法熙卡。
罪魁禍?zhǔn)资沁@里:
let geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(
function(r) {
if (this.getStatus() === BMAP_STATUS_SUCCESS) {
//精度為undefined 代表用戶(hù)拒絕授權(quán)地理位置
if (r.accuracy === null) {
reject({
type: '1', //授權(quán)失敗
errorMessage: '用戶(hù)拒絕授權(quán)地理位置',
});
}
}
}
)
我們調(diào)用百度地圖的api:getCurrentPosition()來(lái)獲取經(jīng)緯度的時(shí)候掏熬,會(huì)有這個(gè)精度(accuracy)的問(wèn)題,我們?cè)倏聪缕髽I(yè)微信的api: getLocation()方法返回了經(jīng)緯度改基,哎,有戲。但是企業(yè)微信使用的坐標(biāo)系是gps坐標(biāo)樟蠕,然而百度地圖使用的是百度坐標(biāo)系,坐標(biāo)系的不同會(huì)影響經(jīng)緯度的精確性靠柑,所以我們找到一個(gè)轉(zhuǎn)換坐標(biāo)系的方法庫(kù):gcoord.js寨辩。最終我們的想法是采用如下方案:企業(yè)微信授權(quán)+企業(yè)微信經(jīng)緯度轉(zhuǎn)百度坐標(biāo)+百度地圖逆地址解析。代碼如下:
getCurrentPosition(){
return new Promise(function(resolve, reject) {
weixin.getLocation().then(
(res) => {
let [longitude, latitude] = gcoord.transform(
[ res.longitude, res.latitude ], // 經(jīng)緯度坐標(biāo)
gcoord.WGS84, // 當(dāng)前坐標(biāo)系
gcoord.BD09 // 目標(biāo)坐標(biāo)系
);
console.log(longitude, latitude, '純打卡包轉(zhuǎn)換成百度地圖后經(jīng)緯度');
let myGeo = new BMap.Geocoder();
myGeo.getLocation(new BMap.Point(longitude, latitude), result => {
if (result) {
resolve({
longitude,
latitude,
address: result.address,
});
} else {
reject({
type: '2', //詳細(xì)地址解析失敗
errorMessage: i18n.t('addressResolveFail'),
});
}
});
},
() => {
reject({
type: '1', //授權(quán)失敗
errorMessage: i18n.t('userRefuseRight'),
});
}
);
});
}
上線(xiàn)至今歼冰,沒(méi)有反饋gps授權(quán)問(wèn)題了靡狞。