简体中文
获取当前的地理位置、速度
注意
Web平台本API调用了腾讯地图的免费gcj02坐标转换接口,该接口从2024年7月18日起被腾讯逐步下线,导致老版本中本API无法使用。请立即升级到 uni-app 4.24版
。
升级后注意:
如果运行在微信浏览器中,可以使用微信的jssdk的定位能力。这个是微信向腾讯地图申请的key,开发者无需配置自己的key。
地图厂商的商业授权较贵,如需购买,请点击获取优惠。
Web | Android | iOS |
---|---|---|
4.0 | 3.9.0 | 4.11 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | GetLocationOptions | 是 | - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
latitude | number | 是 | 0 | 纬度,浮点数,范围为-90~90,负数表示南纬 | |
longitude | number | 是 | 0 | 经度,范围为-180~180,负数表示西经 | |
speed | number | 是 | 0 | 速度,浮点数,单位m/s | |
accuracy | number | 是 | - | 位置的精确度 | |
altitude | number | 是 | 0 | 高度,单位 m | |
verticalAccuracy | number | 是 | 0 | 垂直精度,单位 m(Android 无法获取,返回 0) | |
horizontalAccuracy | number | 是 | 0 | 水平精度,单位 m | |
address | string | 否 | null | 地址信息 |
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
errCode | number | 是 | - | - | 错误码 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
errSubject | string | 是 | - | - | 统一错误主题(模块)名称 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data | any | 否 | - | - | 错误信息中包含的数据 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cause | Error | 否 | - | - | 源错误信息,可以包含多个错误,详见SourceError | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
errMsg | string | 是 | - | - | - |
wgs84坐标是国际GPS坐标系,gcj02是中国国内坐标系。同一个位置,2种坐标系数值不同。
中国的地图厂商(如高德、腾讯),仅能使用gcj02坐标。如果将wgs84坐标显示在中国地图上,就会发现偏移。
同理,将gcj02坐标显示在google地图上,也会偏移。
手机厂商默认预置的都是wgs84坐标,也即入参type设为system或不填时,只能返回wgs84坐标。
iOS设备的系统定位还会返回逆地址解析,即geocode,将坐标转换为城市街道信息。Android设备的系统定位不支持逆地址解析。
某些老型号国产Android Rom(常见于Android6以下)因gms阉割问题不支持系统定位,另部分国产Rom可能不支持高度信息。
如不使用系统定位,而使用专业地图厂商provider,则可以使用gcj02坐标、逆地址解析geocode功能、以及稳定的所有设备均支持的定位服务。
获取gcj02坐标,有2种方式:
不管通过哪种方式获取gcj02坐标,都需要向地图厂商缴纳商业授权费用。DCloud提供了优惠获取地图商业授权的方案,详见
uni-app x的App标准基座定位在4.25前仅支持系统定位,4.25起集成了腾讯定位。
4.25及以下低版本单独可下载腾讯定位插件,在插件中配置key打包后生效。
上述腾讯定位插件属于ext api插件,引用到工程后,会覆盖uni.getLocation的实现,替换掉系统定位。
使用三方定位,需要在地图厂商注册账户、创建应用、获取key。然后将key填写到manifest.json中。
web平台有可视化界面,在manifest的Web配置中寻找定位和地图。填入key后需注意校验,如果在地图厂商后台开启了域名、ip校验,那么如果Web运行或发行后的域名与地图厂商后台配置的不符,就无法获取定位。
app平台目前还没有可视化界面,需要在manifest的源码视图中配置。
uni-getLocation
节点,详见<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
</dict>
</plist>
地图厂商在App端大多会校验包名和证书,请务必保证在地图厂商后台创建的应用,填写的包名、证书摘要,和实际运行的应用匹配,否则无法使用三方定位。
定位属于隐私权限,不管在浏览器、App还是小程序,都需要用户同意授权才可以获取。
获取手机端app是否拥有定位权限,请使用API uni.getAppAuthorizeSetting
除了用户未给app赋予定位权限,有的设备可能直接关闭了定位功能。此时可通过 uni.getSystemSetting 来获取定位开关。
定位包括gps等卫星定位和基站wifi等网络定位。
卫星定位的精度较高,但卫星定位要求手机设备与高空卫星之间没有阻挡,在阴天、室内,卫星定位会受影响。
有时设备可连接的高空卫星数量较少,定位精度就会较差。如果连接不到任何卫星,定位会失败。
而基于基站和wifi路由的网络定位,精度要被卫星定位差很多。网络定位的核心是手机要有网,无需顾忌和高空卫星之间的阻挡。网络定位一般只能知道设备在某个基站周围,但没有很精细的位置。
当设备无法获取定位坐标时,需检查:
当设备可以获取坐标,但在地图上有偏差时,需检查:
Template
Script
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1;">
<!-- #endif -->
<page-head :title="title"></page-head>
<view style="padding: 4px">
<text class="hello-text">
定位功能默认调用操作系统定位API实现, 也支持腾讯定位。\n
部分手机因gms兼容不好可能导致无法使用系统定位, gcj国标、逆地理信息等功能需调用内置腾讯定位。</text>
</view>
<view class="uni-padding-wrap uni-common-mt">
<!-- #ifdef APP -->
<view class="uni-list-cell-db">定位服务商provider(如系统定位,腾讯定位等)</view>
<view class="uni-list" style="margin-bottom: 20px">
<radio-group @change="radioChangePV">
<radio class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in providerList" :key="item.id"
:class="index < providerList.length - 1 ? 'uni-list-cell-line' : ''" :value="item.id"
:checked="index === currentProvider">
{{ item.name }}
</radio>
</radio-group>
</view>
<!-- #endif -->
<view class="uni-list-cell-db">定位类型</view>
<view class="uni-list">
<radio-group @change="radioChange">
<radio class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in items" :key="item.value"
:class="index < items.length - 1 ? 'uni-list-cell-line' : ''" :value="item.value"
:checked="index === current">
{{ item.name }}
</radio>
</radio-group>
</view>
<view class="uni-list-cell uni-list-cell-pd" style="margin-top: 20px">
<view class="uni-list-cell-db">高度信息</view>
<switch :checked="altitudeSelect" @change="altitudeChange" />
</view>
<view class="uni-list-cell uni-list-cell-pd">
<view class="uni-list-cell-db">开启高精度定位</view>
<switch :checked="isHighAccuracySelect" @change="highAccuracySelectChange" />
</view>
<view class="uni-list-cell uni-list-cell-pd">
<view class="uni-list-cell-db">是否解析地址信息</view>
<switch :checked="geocodeSelect" @change="geocodeChange" />
</view>
<text>{{ exeRet }}</text>
<view class="uni-btn-v">
<button class="uni-btn" type="default" @tap="getLocationTap">
获取定位
</button>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
errMsg | string | 是 | - | - | 错误信息 |
UniLocationSystemProvider(系统定位)继承自UniProvider
UniLocationTencentProvider(腾讯定位)继承自UniProvider
背景:目前uni-app x引擎已经内置了系统定位、腾讯定位。但还有高德定位等其他定位SDK。
以往这些SDK可以通过独立插件的方式集成到uni-app x中,但需要提供单独的API给开发者使用,无法使用uni.getLocation。
uni-app x从4.25起,开放了App平台的provider自接入机制,让三方SDK可以以provider方式被开发者集成。
开发一个UTS插件,对接uni规范化的API、错误信息描述等实现自己的定位插件,这样插件使用者就可以通过uni的标准API使用三方SDK。
举个例子,用户想使用uni.getLocation()的方式调用高德定位,但是内置定位api不支持,
那只需要按照下面四个步骤实现即可:
第一步,新建一个UTS插件,在interface.uts 中定义接口,继承 UniLocationProvider,代码如下
export interface UniLocationAMapProvider extends UniLocationProvider{}
第二步,在app-android或者app-ios的index.uts中实现接口,代码如下
import { UniLocationAMapProvider } from '../interface';
export class UniLocationAMapProviderImpl implements UniLocationAMapProvider{
override id : String = 'amap' //id必须有插件作者前缀,避免冲突,避免不同插件作者的插件id重名
override description : String = "高德地图"
override isAppExist : boolean | null = null
override getLocation(options : GetLocationOptions) {
//todo 具体逻辑,接收uni规范的入参,进行业务处理,返回uni规范的返回值。如遇到错误,按uni的规范返回错误码
}
constructor() {
}
}
第三步,在manifest.json中配置
"app": {
"distribute": {
/* android打包配置 */
"modules": {
"uni-getLocation":{
"amap":{}
}
}
}
}
第四步,打包自定义基座然后运行
通过以上步骤就可以实现自定义定位provider接入到uni API。
由于uni-app x自带的腾讯定位,也是基于provider注册机制开发的,可参考腾讯定位插件的实现源码
App平台,腾讯定位SDK,除了本API封装的功能,还有一些其他功能。如开发者需要调用这些SDK的其他API,可以使用uts直接调用,同样参考上述源码。