[TOC]
# uniapp定位及地图
## 定位并解析地理位置的封装
根据uniapp暴露的[定位API:uni.getLocation](https://uniapp.dcloud.io/api/location/location),以及 [高德开放平台文档:地理/逆地理编码](https://lbs.amap.com/api/webservice/guide/api/georegeo)。为了方便调用,我想到了将其进行合并封装。
思路为:先通过 `uni.getLocation` 进行定位,然后获取到经纬度,通过经纬度进行逆地理编码查询。
通过测试,在Web端逆地理编码并不存在跨域问题,但是有调用次数限制,日调用次数为3000000次,足以满足大部分需求。
```js
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的原型中,使用的时候:
```js
let locationInfo = await this.$utils.getLocationInfo()
console.log(locationInfo)
```
如果响应正确,其格式应为:
```json
{
"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](https://ask.dcloud.net.cn/article/29)。离线打包自行在原生工程中配置。注意包名、appkey、证书信息必须匹配。真机运行可以正常定位,是因为真机运行基座使用了DCloud向高德申请的sdk配置,打包后必须由开发者自己申请。如果手机自带GMS且网络环境可以正常访问google定位服务器,此时无需在manifest填写高德定位的sdk配置。
我使用的是高德定位,具体流程如下:
### 1. 到高德开放平台申请应用
首先注册高德开放平台的账号,到控制台中
![](https://kan.xiaoyulive.top/uniapp/014.png)
添加应用
![](https://kan.xiaoyulive.top/uniapp/015.png)
然后在应用下添加key
![](https://kan.xiaoyulive.top/uniapp/016.png)
其中:
SHA1码的获取方式:在命令行中输入以下命令获取
```
keytool -list -v -keystore test.keystore
Enter keystore password: // 输入密码,回车
```
PackageName为`build.gradle`中配置的包名
创建好应用及key后,记住此key
### 2. 需要引入工程的jar/aar文件
需要将以下jar/aar文件([下载地址点这里](https://nativesupport.dcloud.net.cn/AppDocs/download/android))放到工程的libs目录下
| 路径 | 文件 |
| :------: | :-------------------------------------------------: |
| SDK\libs | amap-libs-release.aar, geolocation-amap-release.aar |
### 3. 在AndroidManifest.xml中配置
application节点前:
```xml
<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节点下:
```xml
<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进行配置
![](https://kan.xiaoyulive.top/uniapp/013.png)
## 参考资料
- [uniapp官方文档:获取位置](https://uniapp.dcloud.io/api/location/location)
- [地图插件配置](https://ask.dcloud.net.cn/article/29)
- [uniapp离线打包之定位模块的配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/androidModuleConfig/geolocation)
- [Android平台签名证书(.keystore)生成指南](https://ask.dcloud.net.cn/article/35777#keyinfo)
- uniapp项目搭建
- 通过cli创建uniapp项目
- uniapp平台特性
- uniapp基础
- 在uniapp中使用字体图标
- uniapp全局变量的几种实现方式
- uniapp自定义页面返回逻辑
- uniapp进阶
- 在网页中打开uniapp应用
- uniapp状态栏与导航栏
- 在uniapp中优雅地使用WebView
- uniapp Android离线打包
- Android原生工程搭建
- 在uni-app项目中集成Android原生工程
- uniapp热更新和整包更新
- Android Q启动白屏的问题
- uniapp原生插件开发与使用
- Android 原生插件使用
- uniapp基础模块配置
- uniapp定位及地图
- uniapp第三方支付、登录
- 常见问题及解决方案
- Android端常见问题解决方案
- H5端常见问题解决方案
- 微信小程序常见问题解决方案