[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. 到高德開放平臺申請應用
首先注冊高德開放平臺的賬號,到控制臺中

添加應用

然后在應用下添加key

其中:
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進行配置

## 參考資料
- [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端常見問題解決方案
- 微信小程序常見問題解決方案