# uni.getLocation(options)

获取当前的地理位置、速度

注意

Web平台本API调用了腾讯地图的免费gcj02坐标转换接口,该接口从2024年7月18日起被腾讯逐步下线,导致老版本中本API无法使用。请立即升级到 uni-app 4.24版

升级后注意:

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

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

地图厂商的商业授权较贵,如需购买,请点击获取优惠

# getLocation 兼容性

Web Android iOS
4.0 3.9.0 4.11

# 参数

名称 类型 必填 默认值 兼容性 描述
options GetLocationOptions - -
名称 类型 必备 默认值 兼容性 描述
provider string system
定位服务提供商,通过 uni.getProvider 获取,目前支持系统定位(system)、腾讯定位(tencent)
腾讯定位是4.25版本后支持的;
web端暂不支持provider机制;
type string wgs84
默认为 wgs84 返回 gps 坐标,gcj02 返回可用于uni.openLocation的坐标,web端需配置定位 SDK 信息才可支持 gcj02;
合法值 兼容性 描述
wgs84
wgs84坐标系,系统定位默认取值wgs84,系统定位仅支持wgs84坐标系
gcj02
gcj02坐标系,腾讯定位默认取值gcj02,腾讯定位仅支持gcj02坐标系
altitude boolean false
传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度
geocode boolean false
传入 true 会解析地址;
使用系统定位时平台差异:iOS支持逆地理编码,Android不支持;
highAccuracyExpireTime number 3000
高精度定位超时时间(ms),指定时间内返回最高精度,该值3000ms以上高精度定位才有效果
isHighAccuracy boolean false
开启高精度定位
success (result: GetLocationSuccess) => void -
接口调用成功的回调函数
fail (result: IGetLocationFail) => void -
接口调用失败的回调函数
complete (result: any) => void -
接口调用结束的回调函数(调用成功、失败都会执行)

# GetLocationSuccess 的属性值

名称 类型 必备 默认值 兼容性 描述
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
地址信息

# IGetLocationFail 的属性值

名称 类型 必备 默认值 兼容性 描述
errCode number - - 错误码
合法值 兼容性 描述
1505003
系统定位未开启,请在系统设置中开启系统定位
1505004
应用定位权限未开启
1505023
不支持逆地理编码
1505600
超时
1505601
不支持的定位类型
1505602
捕获定位失败
1505603
逆地理编码捕获失败
1505604
服务供应商获取失败
1505605
未通过配置预校验,通常是腾讯定位 api key 配置错误
1505607
腾讯定位只支持GCJ-02
1505700
不支持逆地理编码
1505701
没有找到具体的定位引擎(GPS_PROVIDER,NETWORK_PROVIDER,PASSIVE_PROVIDER等),请确定系统定位是否开启
1505800
应用高精度定位权限未开启
1505026
捕获定位失败 从4.25开始已经废弃
1505025
逆地理编码捕获失败 从4.25开始已经废弃
1505024
没有找到具体的定位引擎(GPS_PROVIDER,NETWORK_PROVIDER,PASSIVE_PROVIDER等),请定位开关是否已打开 从4.25开始已经废弃
1505022
不支持的定位类型 从4.25开始已经废弃
1505021
超时 从4.25开始已经废弃
1505005
缺失高精度权限授权(iOS特有) 从4.25开始已经废弃
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种方式:

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

不管通过哪种方式获取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的源码视图中配置。

  • app需要在manifest.json文件中配置uni-getLocation节点,详见
  • iOS平台:如果应用需要后台定位能力,需要在 info.plist 中配置 UIBackgroundModes 的 location,注意需Xcode工程中添加相对应 Capabilities 中的 Background Modes,并且勾选 Location updates。
<?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路由的网络定位,精度要被卫星定位差很多。网络定位的核心是手机要有网,无需顾忌和高空卫星之间的阻挡。网络定位一般只能知道设备在某个基站周围,但没有很精细的位置。

  • 当设备无法获取定位坐标时,需检查:

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

    • 是否没有卫星信号,只有网络定位的话精度确实有误差
    • 是否没有高精度定位权限
    • 坐标系是否匹配,把wgs84坐标显示在只支持gcj02的中国地图上肯定是会偏差的

# 参见

# 示例

hello uni-app x

扫码体验(手机浏览器跳转到App直达页)

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>


# 通用类型

# GeneralCallbackResult

名称 类型 必备 默认值 兼容性 描述
errMsg string - - 错误信息

# 定位provider对象描述

UniLocationSystemProvider(系统定位)继承自UniProvider

UniLocationTencentProvider(腾讯定位)继承自UniProvider

# 自定义定位provider接入到uni API

背景:目前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直接调用,同样参考上述源码。