定位并解析地理位置的封装
根据uniapp暴露的定位API:uni.getLocation,以及 高德开放平台文档:地理/逆地理编码。为了方便调用,我想到了将其进行合并封装。
思路为:先通过 uni.getLocation
进行定位,然后获取到经纬度,通过经纬度进行逆地理编码查询。
通过测试,在Web端逆地理编码并不存在跨域问题,但是有调用次数限制,日调用次数为3000000次,足以满足大部分需求。
class Utils {
constructor () {}
...
// 获取地理位置详情信息
async getLocationInfo() {
// Reference:https://lbs.amap.com/api/webservice/guide/api/georegeo/
return new Promise((resolve, reject) => {
uni.getLocation({
success: (res) => {
console.log('获取定位成功')
console.log(res)
uni.request({
url: 'https://restapi.amap.com/v3/geocode/regeo',
data: {
output: 'json',
location: `${res.longitude},${res.latitude}`,
key: 'your key',
extensions: 'base',
batch: false
},
success: (res) => {
console.log(res)
if (res.data && res.data.status === "1") {
console.log('解析地理位置成功')
console.log(res.data.regeocode.addressComponent.adcode)
resolve(res.data)
} else {
console.log('解析地理位置失败')
reject('解析地理位置失败')
}
},
fail: (e) => {
console.log('解析地理位置失败')
console.log(e)
reject('解析地理位置失败')
}
})
},
fail: err => {
// this.toast('定位失败:' + JSON.stringify(err))
console.log('获取定位失败')
console.log(err)
reject('获取定位失败')
}
});
})
}
}
我将其挂载到了Vue的原型中,使用的时候:
let locationInfo = await this.$utils.getLocationInfo()
console.log(locationInfo)
如果响应正确,其格式应为:
{
"status": "1",
"regeocode": {
"addressComponent": {
"city": "昆明市",
"province": "云南省",
"adcode": "530114",
"district": "呈贡区",
"towncode": "530114002000",
"streetNumber": {
"number": "1号",
"location": "102.833659,24.8784011",
"direction": "南",
"distance": "141.125",
"street": "锦绣大街"
},
"country": "中国",
"township": "洛龙街道",
"businessAreas": [
[]
],
"building": {
"name": [],
"type": []
},
"neighborhood": {
"name": [],
"type": []
},
"citycode": "0871"
},
"formatted_address": "云南省昆明市呈贡区洛龙街道吉安街昆明市人民政府"
},
"info": "OK",
"infocode": "10000"
}
关于APP端离线打包后定位失效的问题
我在本地打包后遇到这样一个问题:使用HBuilderX真机调试的时候,能够正常获取到定位。但离线打包后,就不可以获取到正确的定位信息,永远走的都是fail。经过一系列排查,发现需要在Android原生工程中进行相关配置才能正确获取到定位。
官方文档中提到:
Android由于谷歌服务被墙,或者手机上没有GMS,想正常定位就需要向高德等三方服务商申请SDK资质,获取AppKey。否则打包后定位就会不准。云打包时需要在manifest的SDK配置中填写Appkey。在manifest可视化界面有详细申请指南,详见:https://ask.dcloud.net.cn/article/29。离线打包自行在原生工程中配置。注意包名、appkey、证书信息必须匹配。真机运行可以正常定位,是因为真机运行基座使用了DCloud向高德申请的sdk配置,打包后必须由开发者自己申请。如果手机自带GMS且网络环境可以正常访问google定位服务器,此时无需在manifest填写高德定位的sdk配置。
我使用的是高德定位,具体流程如下:
1. 到高德开放平台申请应用
首先注册高德开放平台的账号,到控制台中
添加应用
然后在应用下添加key
其中:
SHA1码的获取方式:在命令行中输入以下命令获取
keytool -list -v -keystore test.keystore
Enter keystore password: // 输入密码,回车
PackageName为build.gradle
中配置的包名
创建好应用及key后,记住此key
2. 需要引入工程的jar/aar文件
需要将以下jar/aar文件(下载地址点这里)放到工程的libs目录下
路径 | 文件 |
---|---|
SDK\libs | amap-libs-release.aar, geolocation-amap-release.aar |
3. 在AndroidManifest.xml中配置
application节点前:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
application节点下:
<meta-data android:name="com.amap.api.v2.apikey" android:value=\"%用户申请的APPkey%\"></meta-data>
<service android:name="com.amap.api.location.APSService"></service>
4. 在manifest.json中配置
在manifest.json
中将key进行配置