get-location.md 9.4 KB
Newer Older
D
DCloud_LXH 已提交
1 2 3 4
## uni.getLocation(options) @getlocation

<!-- UTSAPIJSON.getLocation.description -->

W
wanganxp 已提交
5
::: warning 注意
W
wanganxp 已提交
6 7 8 9 10 11 12 13 14 15 16
Web平台本API调用了腾讯地图的免费gcj02坐标转换接口,该接口从2024年7月18日起被腾讯逐步下线,导致老版本中本API无法使用。请立即升级到 `uni-app 4.24版`

升级后注意:
1. manifest中配置好自己的地图厂商key
2. 确保在地图厂商那里配额足够
3. 确保在地图厂商那里有周边服务的权限。否则无法获取周围地址
4. 确保自己的域名在地图厂商那里正确配置了域名白名单

如果运行在微信浏览器中,可以使用微信的jssdk的定位能力。这个是微信向腾讯地图申请的key,开发者无需配置自己的key。

地图厂商的商业授权较贵,如需购买,请点击[获取优惠](https://ask.dcloud.net.cn/explore/map/)
W
wanganxp 已提交
17 18
:::

D
DCloud_LXH 已提交
19 20
<!-- UTSAPIJSON.getLocation.compatibility -->

D
DCloud_LXH 已提交
21 22 23 24 25 26
<!-- UTSAPIJSON.getLocation.param -->

<!-- UTSAPIJSON.getLocation.returnValue -->

### 注意

W
wanganxp 已提交
27
### 坐标系、系统定位、三方定位等概念
D
DCloud_LXH 已提交
28

W
wanganxp 已提交
29
wgs84坐标是国际GPS坐标系,gcj02是中国国内坐标系。同一个位置,2种坐标系数值不同。
D
DCloud_LXH 已提交
30

W
wanganxp 已提交
31
中国的地图厂商(如高德、腾讯),仅能使用gcj02坐标。如果将wgs84坐标显示在中国地图上,就会发现偏移。
D
DCloud_LXH 已提交
32

W
wanganxp 已提交
33
同理,将gcj02坐标显示在google地图上,也会偏移。
D
DCloud_LXH 已提交
34

W
wanganxp 已提交
35
手机厂商默认预置的都是wgs84坐标,也即入参type设为system或不填时,只能返回wgs84坐标。
zhaofengliang920817's avatar
zhaofengliang920817 已提交
36

W
wanganxp 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
iOS设备的系统定位还会返回逆地址解析,即geocode,将坐标转换为城市街道信息。Android设备的系统定位不支持逆地址解析。

某些老型号国产Android Rom(常见于Android6以下)因gms阉割问题不支持系统定位,另部分国产Rom可能不支持高度信息。

如不使用系统定位,而使用专业地图厂商provider,则可以使用gcj02坐标、逆地址解析geocode功能、以及稳定的所有设备均支持的定位服务。

获取gcj02坐标,有2种方式:
1. 使用国内地图厂商的SDK,也即使用provider,打包时需包含相应模块,并配置向地图厂商申请的key信息。
2. 手机端获取系统定位,拿到wgs84坐标后,使用国内地图厂商的web接口,将wgs84坐标转换为gcj02坐标,web接口也有逆地址解析功能。

不管通过哪种方式获取gcj02坐标,都需要向地图厂商缴纳商业授权费用。DCloud提供了优惠获取地图商业授权的方案,[详见](https://uniapp.dcloud.net.cn/tutorial/app-geolocation.html#lic)

uni-app x的App标准基座定位在4.25前仅支持系统定位,4.25起集成了腾讯定位。

4.25及以下低版本单独可下载[腾讯定位插件](https://ext.dcloud.net.cn/plugin?id=14569),在插件中配置key打包后生效。
D
DCloud_LXH 已提交
52

53
上述腾讯定位插件属于[ext api插件](https://uniapp.dcloud.net.cn/api/extapi.html),引用到工程后,会覆盖uni.getLocation的实现,替换掉系统定位。
D
DCloud_LXH 已提交
54

W
wanganxp 已提交
55
使用三方定位,需要在地图厂商注册账户、创建应用、获取key。然后将key填写到manifest.json中。
D
DCloud_LXH 已提交
56

W
wanganxp 已提交
57
web平台有可视化界面,在manifest的Web配置中寻找定位和地图。填入key后需注意校验,如果在地图厂商后台开启了域名、ip校验,那么如果Web运行或发行后的域名与地图厂商后台配置的不符,就无法获取定位。
D
DCloud_LXH 已提交
58

W
wanganxp 已提交
59
app平台目前还没有可视化界面,需要在manifest的源码视图中配置。
zhaofengliang920817's avatar
zhaofengliang920817 已提交
60

W
wanganxp 已提交
61 62
- app需要在manifest.json文件中配置`uni-getLocation`节点,[详见](../collocation/manifest-modules.md#uni-getLocation)
- 使用内置腾讯定位和iOS14以上高精度定位时,需要在info.plist中配置对应的Key,参考[在info.plist配置定位相关的Key](../collocation/manifest-modules.md#uni-getLocation-key)
D
DCloud_LXH 已提交
63

W
wanganxp 已提交
64 65 66
地图厂商在App端大多会校验包名和证书,请务必保证在地图厂商后台创建的应用,填写的包名、证书摘要,和实际运行的应用匹配,否则无法使用三方定位。

### 权限@permission
W
wanganxp 已提交
67 68 69 70

定位属于隐私权限,不管在浏览器、App还是小程序,都需要用户同意授权才可以获取。

获取手机端app是否拥有定位权限,请使用API [uni.getAppAuthorizeSetting](get-app-authorize-setting.md)
zhaofengliang920817's avatar
zhaofengliang920817 已提交
71

W
wanganxp 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
除了用户未给app赋予定位权限,有的设备可能直接关闭了定位功能。此时可通过 [uni.getSystemSetting](get-system-setting.md) 来获取定位开关。

### 定位的原理和精度

定位包括gps等卫星定位和基站wifi等网络定位。

卫星定位的精度较高,但卫星定位要求手机设备与高空卫星之间没有阻挡,在阴天、室内,卫星定位会受影响。

有时设备可连接的高空卫星数量较少,定位精度就会较差。如果连接不到任何卫星,定位会失败。

而基于基站和wifi路由的网络定位,精度要被卫星定位差很多。网络定位的核心是手机要有网,无需顾忌和高空卫星之间的阻挡。网络定位一般只能知道设备在某个基站周围,但没有很精细的位置。

- 当设备无法获取定位坐标时,需检查:
	* 手机定位开关是否关闭
	* web站或App是否被拒绝了定位权限
	* 设备是否即没有卫星信号又没有网络
	* 使用三方定位时,地图厂商的校验是否通过,web的域名、ip、签名;app的包名、证书摘要,这些信息在地图厂商配置的和实际运行的,是否一致
	* 地图厂商后台的配额是否足够、权限是否开通

- 当设备可以获取坐标,但在地图上有偏差时,需检查:
	* 是否没有卫星信号,只有网络定位的话精度确实有误差
	* 是否没有高精度定位权限
	* 坐标系是否匹配,把wgs84坐标显示在只支持gcj02的中国地图上肯定是会偏差的
zhaofengliang920817's avatar
zhaofengliang920817 已提交
95

D
DCloud_LXH 已提交
96 97
<!-- UTSAPIJSON.getLocation.tutorial -->

D
DCloud_LXH 已提交
98
<!-- UTSAPIJSON.getLocation.example -->
D
DCloud_LXH 已提交
99 100 101 102

<!-- UTSAPIJSON.general_type.name -->

<!-- UTSAPIJSON.general_type.param -->
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
103

WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
104 105 106

## 定位provider对象描述

W
wanganxp 已提交
107
### UniLocationSystemProvider(系统定位)@locationsystemprovider
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
108

WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
109 110 111 112 113
| 名称           | 类型      | 必备 | 默认值 | 描述                                  |
| -------------- | --------- | ---- | ------ | ------------------------------------- |
| id             | string    | 是   | -      | 服务供应商标识                        |
| description    | string    | 是   | -      | 服务供应商描述                        |
| ~~isAppExist~~      | boolean   | 是   | -      | 已废弃,判断服务供应商依赖的App是否安装(仅支持微信支付) |
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
114

W
wanganxp 已提交
115
### UniLocationTencentProvider(腾讯定位)@locationtencentprovider
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
116

WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
117 118 119 120 121
| 名称           | 类型      | 必备 | 默认值 | 描述                                  |
| -------------- | --------- | ---- | ------ | ------------------------------------- |
| id             | string    | 是   | -      | 服务供应商标识                        |
| description    | string    | 是   | -      | 服务供应商描述                        |
| ~~isAppExist~~      | boolean   | 是   | -      | 已废弃,判断服务供应商依赖的App是否安装(仅支持微信支付) |
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
122 123


WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
124
## 自定义定位provider接入到uni API @customprovider
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
125

W
wanganxp 已提交
126 127 128
背景:目前uni-app x引擎已经内置了系统定位、腾讯定位。但还有高德定位等其他定位SDK。

以往这些SDK可以通过独立插件的方式集成到uni-app x中,但需要提供单独的API给开发者使用,无法使用uni.getLocation。
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
129

W
wanganxp 已提交
130 131 132
uni-app x从4.25起,开放了App平台的provider自接入机制,让三方SDK可以以[provider](./provider.md)方式被开发者集成。

开发一个UTS插件,对接uni规范化的API、错误信息描述等实现自己的定位插件,这样插件使用者就可以通过uni的标准API使用三方SDK。
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
133

WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
134
举个例子,用户想使用uni.getLocation()的方式调用高德定位,但是内置定位api不支持,
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
135

WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
136
那只需要按照下面四个步骤实现即可:
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
137

W
wanganxp 已提交
138
第一步,新建一个UTS插件,在interface.uts 中定义接口,继承 UniLocationProvider,代码如下
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
139 140

```ts
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
141
export interface UniLocationAMapProvider extends UniLocationProvider{}
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
142 143 144 145 146
```

第二步,在app-android或者app-ios的index.uts中实现接口,代码如下

```ts
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
147
import { UniLocationAMapProvider } from '../interface';
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
148

WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
149
export class UniLocationAMapProviderImpl implements UniLocationAMapProvider{
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
150

W
wanganxp 已提交
151
	override id : String = 'amap' //id必须有插件作者前缀,避免冲突,避免不同插件作者的插件id重名
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
152

W
wanganxp 已提交
153
	override description : String = "高德地图"
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
154 155 156 157

	override isAppExist : boolean | null = null

	override getLocation(options : GetLocationOptions) {
W
wanganxp 已提交
158
		//todo 具体逻辑,接收uni规范的入参,进行业务处理,返回uni规范的返回值。如遇到错误,按uni的规范返回错误码
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
	}

	constructor() {
	}

}
```

第三步,在manifest.json中配置

```ts
  "app": {
    "distribute": {
      /* android打包配置 */
      "modules": {
        "uni-getLocation":{
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
175
          "amap":{}
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
176 177 178 179 180 181
        }
      }
    }
  }
```

W
wanganxp 已提交
182
第四步,打包自定义基座然后运行
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
183

W
wanganxp 已提交
184
通过以上步骤就可以实现自定义定位provider接入到uni API。
WOSHIMAHAIFENG's avatar
WOSHIMAHAIFENG 已提交
185

W
wanganxp 已提交
186
由于uni-app x自带的腾讯定位,也是基于provider注册机制开发的,可参考[腾讯定位插件的实现源码](https://gitcode.net/dcloud/uni-api/-/tree/alpha/uni_modules/uni-getLocation-tencent)
W
wanganxp 已提交
187 188

App平台,腾讯定位SDK,除了本API封装的功能,还有一些其他功能。如开发者需要调用这些SDK的其他API,可以使用uts直接调用,同样参考上述源码。