定位并解析地理位置的封装

根据uniapp暴露的定位API:uni.getLocation,以及 高德开放平台文档:地理/逆地理编码。为了方便调用,我想到了将其进行合并封装。

思路为:先通过 uni.getLocation 进行定位,然后获取到经纬度,通过经纬度进行逆地理编码查询。

通过测试,在Web端逆地理编码并不存在跨域问题,但是有调用次数限制,日调用次数为3000000次,足以满足大部分需求。

  1. class Utils {
  2. constructor () {}
  3. ...
  4. // 获取地理位置详情信息
  5. async getLocationInfo() {
  6. // Reference:https://lbs.amap.com/api/webservice/guide/api/georegeo/
  7. return new Promise((resolve, reject) => {
  8. uni.getLocation({
  9. success: (res) => {
  10. console.log('获取定位成功')
  11. console.log(res)
  12. uni.request({
  13. url: 'https://restapi.amap.com/v3/geocode/regeo',
  14. data: {
  15. output: 'json',
  16. location: `${res.longitude},${res.latitude}`,
  17. key: 'your key',
  18. extensions: 'base',
  19. batch: false
  20. },
  21. success: (res) => {
  22. console.log(res)
  23. if (res.data && res.data.status === "1") {
  24. console.log('解析地理位置成功')
  25. console.log(res.data.regeocode.addressComponent.adcode)
  26. resolve(res.data)
  27. } else {
  28. console.log('解析地理位置失败')
  29. reject('解析地理位置失败')
  30. }
  31. },
  32. fail: (e) => {
  33. console.log('解析地理位置失败')
  34. console.log(e)
  35. reject('解析地理位置失败')
  36. }
  37. })
  38. },
  39. fail: err => {
  40. // this.toast('定位失败:' + JSON.stringify(err))
  41. console.log('获取定位失败')
  42. console.log(err)
  43. reject('获取定位失败')
  44. }
  45. });
  46. })
  47. }
  48. }

我将其挂载到了Vue的原型中,使用的时候:

  1. let locationInfo = await this.$utils.getLocationInfo()
  2. console.log(locationInfo)

如果响应正确,其格式应为:

  1. {
  2. "status": "1",
  3. "regeocode": {
  4. "addressComponent": {
  5. "city": "昆明市",
  6. "province": "云南省",
  7. "adcode": "530114",
  8. "district": "呈贡区",
  9. "towncode": "530114002000",
  10. "streetNumber": {
  11. "number": "1号",
  12. "location": "102.833659,24.8784011",
  13. "direction": "南",
  14. "distance": "141.125",
  15. "street": "锦绣大街"
  16. },
  17. "country": "中国",
  18. "township": "洛龙街道",
  19. "businessAreas": [
  20. []
  21. ],
  22. "building": {
  23. "name": [],
  24. "type": []
  25. },
  26. "neighborhood": {
  27. "name": [],
  28. "type": []
  29. },
  30. "citycode": "0871"
  31. },
  32. "formatted_address": "云南省昆明市呈贡区洛龙街道吉安街昆明市人民政府"
  33. },
  34. "info": "OK",
  35. "infocode": "10000"
  36. }

关于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. 到高德开放平台申请应用

首先注册高德开放平台的账号,到控制台中

📃 uniapp定位及地图 - 图1

添加应用

📃 uniapp定位及地图 - 图2

然后在应用下添加key

📃 uniapp定位及地图 - 图3

其中:

SHA1码的获取方式:在命令行中输入以下命令获取

  1. keytool -list -v -keystore test.keystore
  2. 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节点前:

  1. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  2. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  4. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  5. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
  6. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  7. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  8. <uses-permission android:name="android.permission.INTERNET"/>
  9. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
  10. <uses-permission android:name="android.permission.READ_LOGS"/>
  11. <uses-permission android:name="android.permission.WRITE_SETTINGS"/>

application节点下:

  1. <meta-data android:name="com.amap.api.v2.apikey" android:value=\"%用户申请的APPkey%\"></meta-data>
  2. <service android:name="com.amap.api.location.APSService"></service>

4. 在manifest.json中配置

manifest.json中将key进行配置

📃 uniapp定位及地图 - 图4

参考资料