更新记录
1.0.0(2026-08-15)
- 首次发布。
- 提供 Android / iOS / Harmony / Web / 微信小程序系统定位能力:权限申请、后台定位、最近一次缓存读取、实时监听(含
realtime事件驱动模式,忽略intervalMs节拍,静止设备不再空转心跳)。 - 动作类 API 采用单一
options入参,同步取值类直接返回值。 - 错误码 7 位(GPS 专属段
92开头),错误对象为GpsFailure接口(含errSubject/errCode/errMsg/details),由GpsFailureImpl显式实现。 intervalMs/distanceMeters传负数时统一报错9201006。GpsLocation提供horizontalAccuracy与verticalAccuracy成对字段(命名与 iOS CoreLocation 一致)。- 文档包含「定位模式」章节,明确
startWatch默认持续定位(intervalMs默认1000)需手动stopWatch停止;单次定位须显式传intervalMs: 0。 startWatch内部自动申请定位权限:backgroundMode: false时申请前台权限(拒绝则fail返回9201001),backgroundMode: true时额外申请后台定位权限(拒绝则fail返回9201004)。调用方无需先调requestPermission/requestBackgroundPermission,二者均为可选 API(仅在你需提前单独控制申请时机时使用)。Web 端由浏览器 / uni 自动处理,无需调用方额外处理。
平台兼容性
uni-app(5.12)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | 5.0 | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(5.12)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | 5.0 | √ | √ | √ |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| √ | √ | √ |
lime-gps 系统定位
为 uni-app / uni-app x 提供的系统定位 UTS API 插件,同时支持 Android / iOS / Harmony / Web / 微信小程序。UTS 原生插件。
功能特性
- 定位权限申请:前台定位权限与后台定位能力,权限名由插件按平台兜底,调用方无需处理平台差异。
- 实时定位监听:持续回调最新位置,靠
intervalMs区分单次 / 持续两种模式。 - 最近一次定位读取:随时取回缓存中的上一次定位结果。
- 运行环境查询与设置跳转:获取当前平台能力档案,并可跳转系统定位设置页。
安装
插件市场导入,在页面引入,自定义基座
自定义基座说明:
- 本插件使用 UTS 原生能力,APP必须在自定义基座中运行,标准基座无法使用
- CLI 项目特别注意:请检查根目录
package.json,确保所有@dcloudio/*相关包的版本号一致,且与当前 HBuilderX 版本对齐。版本不一致会导致自定义基座编译失败或运行异常
快速示例
import * as gps from '@/uni_modules/lime-gps'
import type {
GpsLocation,
GpsReadOptions,
GpsWatchOptions
} from '@/uni_modules/lime-gps'
// startWatch 内部会自动申请定位权限,无需先调用 requestPermission
gps.startWatch({
backgroundMode: true,
cachedFirst: true,
success: (location: GpsLocation) => {
console.log(location.latitude, location.longitude)
},
fail: (err) => {
console.error(err.errCode, err.errMsg)
},
complete: () => {}
} as GpsWatchOptions)
// 任意时刻读取最近一次定位
gps.readLastLocation({
success: (location: GpsLocation) => {
console.log(location.stage, location.latitude, location.longitude)
},
fail: (err) => console.error(err.errMsg)
} as GpsReadOptions)
类型导入与
as标注:非 TS 环境(uni-app Vue / uni-app x vapor)下无需import type导入类型、也无需as标注,照示例去掉类型部分即可;只有 uni-app x 非 vapor 模式(默认 UTS 编译)这种强类型环境,才建议保留import type与as GpsWatchOptions以拿到准确提示。
定位模式:单次 vs 持续(必读)
startWatch 是同一个函数,靠 intervalMs 的值决定是「单次」还是「持续」。
单次定位示例
gps.startWatch({
intervalMs: 0, // 关键:0 = 单次
success: (location: GpsLocation) => {
console.log('单次结果', location.latitude, location.longitude)
// 这里 success 通常只进来一次(cachedFirst: true 时会有 cached + live 两次),之后引擎自动停止,无需 stopWatch
},
fail: (err: GpsFailure) => {
console.error(err.errCode, err.errMsg)
}
// 注意:单次模式不要依赖 complete 做收尾
} as GpsWatchOptions)
持续定位示例
gps.startWatch({
intervalMs: 1000, // 关键:> 0 = 持续,默认就是 1000
backgroundMode: true,
cachedFirst: true,
success: (location: GpsLocation) => {
console.log('实时', location.latitude, location.longitude)
},
fail: (err: GpsFailure) => {
console.error(err.errCode, err.errMsg)
},
complete: () => {
console.log('监听已停止(stopWatch 或出错)')
}
} as GpsWatchOptions)
// 不再需要时务必停止,否则引擎持续持有监听、后台也会耗电
gps.stopWatch()
realtime 事件驱动示例
gps.startWatch({
realtime: true, // 忽略 intervalMs 节拍,完全由系统定位事件驱动(静止设备/模拟器可能不再回吐)
success: (location: GpsLocation) => {
console.log('实时事件', location.latitude, location.longitude)
},
fail: (err: GpsFailure) => {
console.error(err.errCode, err.errMsg)
}
} as GpsWatchOptions)
对照表
| 维度 | 单次定位(intervalMs: 0) |
持续定位(intervalMs: 1000,默认) |
|---|---|---|
| 触发方式 | 拿到一次坐标即停 | 每隔约 intervalMs 推一次 |
success 回调次数 |
通常 1 次(cachedFirst: true 时先回 cached 再回 live,共 2 次) |
反复多次,直到 stopWatch |
complete 回调 |
不触发(引擎自动停,不在 complete 收尾) |
stopWatch() 或出错时触发 |
distanceMeters |
无效 | 有效(位移阈值) |
是否需要 stopWatch |
不需要(自动停) | 必须手动 stopWatch 否则一直跑 |
| 典型用途 | 「现在在哪」「打卡一次」 | 导航、运动轨迹、实时跟随 |
想从单次切到持续:直接再调一次
startWatch({ intervalMs: 1000 })即可,引擎会先清掉上一次监听再重新注册。
API 参考
同步取值类(直接返回值)
| 函数 | 说明 |
|---|---|
getRuntimeProfile() : GpsRuntimeProfile |
平台能力档案(平台名 / 是否支持跳转设置 / 后台定位 / 系统定位) |
hasPermission(permissionName? : string) : boolean |
是否已授权定位权限(不传则用平台默认定位权限) |
isLocationEnabled() : boolean |
系统定位总开关是否开启 |
openSystemSettings() : void |
跳转系统定位设置页(Harmony 端为请求系统弹窗开启定位总开关,非跳转设置页) |
动作类(options 入参)
| 函数 | 说明 |
|---|---|
requestPermission(options) |
申请定位权限(可选,仅当你需要提前确认授权状态或单独控制时机时调用;startWatch 内部已自动申请):options.permissionName? 可选;options.success(granted) |
requestBackgroundPermission(options) |
申请后台定位能力(可选,仅当你需要提前单独控制时机时调用;startWatch 的 backgroundMode: true 内部已自动申请):options.success(granted) |
readLastLocation(options) |
读最近一次定位:options.success(location) / options.fail(err) |
startWatch(options) |
启动定位监听(默认 intervalMs: 1000 = 持续定位,需手动 stopWatch 停止;内部自动申请定位权限,未授权时弹系统框,用户拒绝则 fail 返回 9201001;backgroundMode: true 时内部也会自动申请后台定位权限,用户拒绝则 fail 返回 9201004):success(location) 按 intervalMs 单次或持续回调 / fail(err) / complete()(仅持续模式 stopWatch 或出错时触发,见上方「定位模式」) |
stopWatch(options?) |
停止监听(持续模式用):options.dismissNotification? 是否移除通知;options.complete() |
类型与返回值
GpsLocation(startWatch 回调 / readLastLocation 返回值)
| 字段 | 类型 | 说明 |
|---|---|---|
message |
string |
状态描述文本,如 已收到实时定位 / 已返回最近一次缓存定位 / 错误原因 |
stage |
"cached" \| "live" \| "error" |
数据阶段:cached=缓存结果、live=实时结果、error=失败 |
latitude |
number |
纬度,范围 -90~90(负数表示南纬),WGS84 |
longitude |
number |
经度,范围 -180~180(负数表示西经),WGS84 |
speed |
number |
速度,单位 m/s |
altitude |
number |
海拔,单位 m |
heading |
number |
朝向,单位度(0 为正北);Web / 小程序端恒为 0(uni 不返回该字段) |
horizontalAccuracy |
number |
水平精度,单位 m(值越小越准) |
verticalAccuracy |
number |
垂直精度,单位 m;Android 无法获取时返回 0 |
GpsRuntimeProfile(getRuntimeProfile 返回值)
| 字段 | 类型 | 说明 |
|---|---|---|
platformName |
string |
当前平台名,如 Android / iOS / Harmony / Web |
supportsOpenSettings |
boolean |
是否支持跳转系统定位设置页(Web / 小程序为 false) |
supportsBackgroundMode |
boolean |
是否支持后台定位(Web / 小程序为 false) |
usesSystemLocation |
boolean |
是否使用系统原生定位(Web / 小程序为 false,走 uni 兜底) |
各 Options 入参字段
startWatch 的 options(GpsWatchOptions):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
notificationTitle |
string? |
— | Android 前台服务通知标题(持续 / 后台定位时展示) |
notificationText |
string? |
— | Android 前台服务通知内容 |
notificationIconName |
string? |
— | Android 通知图标名称 |
intervalMs |
number? |
1000 |
定位模式开关(毫秒):0 = 单次定位(只回调一次后自动停止);> 0 = 持续定位(按此间隔反复回调,直到 stopWatch)。默认值 1000 即持续模式 |
distanceMeters |
number? |
0 |
最小位移距离(米)触发更新;iOS 映射为 distanceFilter。单次模式下此参数无效 |
backgroundMode |
boolean? |
false |
是否后台持续定位 |
cachedFirst |
boolean? |
false |
启动监听时先回吐一次缓存结果 |
realtime |
boolean? |
false |
实时事件驱动模式(全平台生效,仅连续定位):为 true 时忽略 intervalMs,改为由系统定位事件驱动、一产生新定位就尽快回吐(适合导航/运动轨迹等极致跟手场景)。代价与差异:iOS / Android / Harmony 在 realtime 下行为一致——均由系统按定位事件尽快回吐、静止设备/模拟器可能不再回吐(无新定位事件,无节拍心跳;Harmony 传 interval=0,同样去掉了 1 秒天花板);distanceMeters 各端仍生效。默认 false 按 intervalMs 节拍回吐。注意:本选项与 intervalMs: 0(单次)不冲突——单次模式会忽略 realtime、只回吐一次(cachedFirst: true 时为 cached+live 两次,见上方对照表);只想拿一次定位时直接传 intervalMs: 0 即可(无需也不建议同时传 realtime) |
success |
(location: GpsLocation) => void |
— | 成功回调(定位结果;触发次数见上方 intervalMs 说明) |
fail |
(err: GpsFailure) => void |
— | 失败回调 |
complete |
() => void |
— | 结束回调(仅持续模式在 stopWatch 或出错时触发) |
其余 options(readLastLocation / requestPermission / requestBackgroundPermission / stopWatch)仅含上述对应的 success / fail / complete 或 dismissNotification?(stopWatch,是否移除通知),语义相同。
GpsFailure(fail 回调入参)
| 字段 | 类型 | 说明 |
|---|---|---|
errSubject |
string |
错误主题,本插件固定为 lime-gps |
errCode |
number |
错误码(见下方错误码表,如 9201001) |
errMsg |
string |
错误描述文本 |
cause |
Error? |
源错误(可选) |
错误码
| 码 | 含义 | 触发场景 |
|---|---|---|
9201001 |
定位权限尚未授予 | requestPermission 被拒、或 startWatch / readLastLocation 前未授权 |
9201002 |
定位服务当前不可用 | 系统定位总开关关闭、或 GPS / 网络定位 provider 均不可用 |
9201003 |
暂时没有可用的定位结果 | 缓存为空且单次定位失败、监听过程中出错 |
9201004 |
后台定位能力未获授权 | backgroundMode: true 但未授予后台定位权限 |
9201005 |
当前平台不支持此操作 | 调用了当前平台未实现的路径 |
9201006 |
定位参数不合法 | intervalMs / distanceMeters 为负数、permissionName 为空等 |
9201007 |
运行环境暂不可用 | Android 上 UTSAndroid.getUniActivity() 返回 null(多发生在非 Activity 上下文调用) |
fail 回调收到 GpsFailure(即 IUniError):{ errSubject: 'lime-gps', errCode, errMsg, ... }。
注意事项
permissionName不传时各平台使用默认定位权限(AndroidACCESS_FINE_LOCATION/ iOSlocation/ Harmonyohos.permission.LOCATION),无需调用方写平台分支。- iOS 连续定位模式同样按
intervalMs节拍回吐(因 iOS 的CLLocationManager原生不支持时间节流,内部用定时器模拟,对齐 Android 的系统级原生支持);distanceMeters映射为 iOS 的distanceFilter;单次定位仍用intervalMs: 0。若需要极致跟手、完全由系统定位事件驱动(无视intervalMs节拍),传realtime: true即可,代价是静止设备不再回吐心跳。 - Android 11+(API 30+)后台定位:系统要求
ACCESS_BACKGROUND_LOCATION必须在前台定位权限已授予后单独申请,且会引导用户去系统设置选择「始终允许」。requestBackgroundPermission已按此顺序串联调用,但最终是否授权仍取决于用户在系统设置中的选择。 - Harmony 后台定位:Harmony 要求
APPROXIMATELY_LOCATION必须先于LOCATION申请,插件内部已处理;openSystemSettings通过系统弹窗请求开启定位总开关,与其它端「跳转设置页」略有不同。 readLastLocation在 Android / iOS 优先返回应用内最近一次定位缓存,若从未启动过监听则回退到系统最近一次定位;Harmony 直接读取系统最近一次定位。- 连续定位具备容错:监听过程中偶发的瞬时错误(如信号短暂丢失)不会中断监听,会继续等待下次可用定位;只有定位权限被收回(9201001)或确有错误时才回调
fail。
支持平台
| 平台 | 支持 |
|---|---|
| Android | √(minSdk 21) |
| iOS | √ |
| Harmony | √ |
| Web(Safari / Chrome) | √(走 uni 定位 API 兜底,不支持后台定位与跳转系统设置) |
| 微信小程序 | √(同 Web) |
坐标系说明(type 取值)
底层 uni 定位 API 的 type 参数用于指定坐标系,取值如下:
type 值 |
含义 | 说明 |
|---|---|---|
wgs84 |
国际经纬度标准(GPS 原生坐标) | 系统原生定位默认返回,也是本插件固定返回的坐标系 |
gcj02 |
国测局加密坐标(俗称「火星坐标」) | 国内地图(高德 / 腾讯 / 百度系底图)使用;Web / 小程序端需配置地图厂商 key 与配额才能转换,否则取不到结果 |
本插件所有平台统一返回 wgs84(系统原生 GPS 坐标,未做任何偏移加密)。 我们刻意不暴露 type 入参、固定为 wgs84,以避免引入地图厂商 key 依赖。若业务需叠加国内地图,请自行做 wgs84 → gcj02 / bd09 转换。
各平台原生配置
除标准基座外,各平台还有以下前置配置:
Android
- 所需权限已在插件
utssdk/app-android/AndroidManifest.xml声明:ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION、ACCESS_BACKGROUND_LOCATION、FOREGROUND_SERVICE、FOREGROUND_SERVICE_LOCATION、POST_NOTIFICATIONS。 minSdk需 ≥ 21(见package.json)。- 后台定位需用户在系统设置中将定位权限设为「始终允许」。
iOS
- 插件
utssdk/app-ios/info.plist已声明NSLocationWhenInUseUsageDescription、NSLocationAlwaysAndWhenInUseUsageDescription与UIBackgroundModes → location。 - 后台持续定位前,用户需在系统设置中授予应用「始终」定位权限。
Harmony
- 持续定位(含后台持续):在宿主
EntryAbility声明backgroundModes: ["location"],否则应用退到后台后无法持续获取定位。 - 后台定位权限:Harmony 的后台定位权限无法靠弹窗授予,需用户在系统设置把本应用定位设为「始终允许」(路径:
设置 → 隐私与安全 → 位置 → 具体应用)。未设置时startWatch({ backgroundMode: true })会返回9201004;插件会通过openAppSettings拉起应用设置详情页引导用户跳转。
注意:插件已声明定位相关权限并会自动合并进宿主
entry,无需手动补齐;但插件无法声明backgroundModes,需在宿主harmony-configs/entry/src/main/module.json5的EntryAbility上手动加上(也可直接取构建产物unpackage/dist/dev/app-harmony/entry/src/main/module.json5覆盖该目录):
{
"module": {
"abilities": [
{
"name": "EntryAbility",
// 需要持续 / 后台定位时加上
"backgroundModes": ["location"]
}
]
}
}
修改
harmony-configs后必须重新制作自定义基座并重新安装运行包——清单变更不会热更新。本工程已内置该文件,可直接运行。
隐私与权限声明
- 所需系统权限:
ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION、ACCESS_BACKGROUND_LOCATION(Android);定位相关权限(iOS / Harmony 见各平台原生配置)。 - 数据采集与用途:仅在设备本地读取系统定位结果,不上传任何远程服务器,无远程采集与上报逻辑。
后台定位完整示例
后台定位只需在 startWatch 传入 backgroundMode: true,所需的后台权限会由插件内部自动申请(无需先调 requestBackgroundPermission):
import * as gps from '@/uni_modules/lime-gps'
import type {
GpsLocation,
GpsWatchOptions
} from '@/uni_modules/lime-gps'
gps.startWatch({
backgroundMode: true,
cachedFirst: true,
success: (location: GpsLocation) => {
console.log(location.latitude, location.longitude)
},
fail: (err) => console.error(err.errCode, err.errMsg),
complete: () => {}
} as GpsWatchOptions)
后台定位生效的前置条件:① 用户在系统设置授予「始终」定位权限(插件会弹框申请,拒绝则
fail返回9201004);② 宿主应用完成上方「各平台原生配置」(尤其鸿蒙EntryAbility的backgroundModes与 iOS 的info.plist)。两者缺一不可。若需提前单独控制申请时机,仍可显式调用requestBackgroundPermission。
常见问题(FAQ)
-
Q:返回的坐标系是什么? A:统一为
wgs84(系统原生 GPS 坐标,未加密偏移)。需要叠加国内地图时请自行做wgs84 → gcj02 / bd09转换,详见上方「坐标系说明」。 -
Q:退出页面再进入,回调不再触发? A:连续定位是引擎级长连接。页面销毁前务必调用
stopWatch()释放监听;否则引擎仍在后台持有监听,再次进入可能因实例未复位而不触发回调。 -
Q:室内 / 工业设备定位失败或偏差很大? A:本插件依赖系统 GPS,需开阔天空环境。室内、地下、金属遮挡场景下 GPS 信号弱属正常现象,定位精度由设备 GPS 模块决定。
-
Q:Web 端能用吗?需要配 key 吗? A:Web(Safari / Chrome)与微信小程序可用,走 uni 定位 API 兜底;但仅支持
wgs84,gcj02需配地图厂商 key。Web 端不支持后台定位与跳转系统设置。 -
Q:需要第三方地图 Key 吗? A:不需要。本插件直接调用系统原生定位,不依赖高德 / 腾讯 / 百度等三方 Key,也不产生地图服务费用。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 73695
赞赏 594
下载 12509082
赞赏 1943
赞赏
京公网安备:11010802035340号