ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

uni-app 持续定位 API 全解析:onLocationChange、startLocationUpdate 与后台定位实战

uni-app 持续定位 API 全解析:onLocationChange、startLocationUpdate 与后台定位实战 uni-app 持续定位 API 全解析onLocationChange、startLocationUpdate 与后台定位实战【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app本篇技术指南围绕 uni-app跨端框架基于 Vue.js的持续定位实时位置变化监听API 体系展开系统讲解uni.onLocationChange/uni.offLocationChange、uni.onLocationChangeError/uni.offLocationChangeError、uni.startLocationUpdate/uni.stopLocationUpdate与uni.startLocationUpdateBackground七个 API 的签名、参数、返回值、错误码与各端兼容性并结合仓库内 UTS 源码与自动化测试验证其底层实现。读完本文你将掌握在 Web、微信小程序、Android、iOS、HarmonyOS 五端正确实现进入前台接收位置消息、进入后台仍持续定位、异常监听与资源释放的完整方案并理解坐标系wgs84/gcj02与定位服务提供商system/tencent的约束关系。一、持续定位 API 全景从一次性定位到实时位置流与一次性的uni.getLocation不同持续定位location change系列 API 解决的是位置持续变化时需要实时感知的场景典型应用包括运动轨迹记录、导航跟随、配送员实时位置上报、地理围栏Geo-fencing等。它通过开启更新 事件监听 关闭更新三个步骤协作完成| 步骤 | API | 作用 | | :- | :- | :- | | 开启更新 |uni.startLocationUpdate(options)| 开启应用进入前台时接收位置消息 | | 开启更新后台 |uni.startLocationUpdateBackground(option)| 应用进入前后台均接收实时位置消息 | | 监听位置 |uni.onLocationChange(callback)| 注册实时地理位置变化事件回调返回监听 IDnumber | | 监听失败 |uni.onLocationChangeError(callback)| 监听持续定位接口返回失败时触发 | | 移除监听 |uni.offLocationChange(callback)/uni.offLocationChangeError(callback)| 移除对应事件监听 | | 关闭更新 |uni.stopLocationUpdate(options)| 关闭监听实时位置变化前后台都停止消息接收 |仓库中对应接口的声明位于 src/uni_modules/uni-location/utssdk/interface.uts其中逐一给出了每个 API 的完整 JSDoc 与跨平台能力标注例如onLocationChange(listener: OnLocationChangeCallback): number、offLocationChange(listener?: number | OnLocationChangeCallback | null): void。从源码结构可以确认on/off系列返回/接受的是监听 IDnumber 类型off时也允许直接传入回调函数或nullnull表示移除全部监听。二、监听与反监听onLocationChange / offLocationChange2.1 uni.onLocationChange(callback)监听实时地理位置变化事件。兼容性| Web | 微信小程序 | Android | iOS | HarmonyOS 系统版本 | HarmonyOS | | :- | :- | :- | :- | :- | :- | | 4.0 | 4.41 | 4.81 | 4.81 | 5.0.0(11) | 4.81 |参数| 名称 | 类型 | 必填 | | :- | :- | :- | | listener | (res: OnLocationChangeResult) void | 是 |返回值number监听 ID可用于offLocationChange精确移除。2.2 OnLocationChangeResult 属性回调参数res包含位置核心数据各属性说明如下| 名称 | 类型 | 必备 | 默认值 | 描述 | | :- | :- | :- | :- | :- | | latitude | number | 是 | 0 | 纬度浮点数范围 -90~90负数表示南纬 | | longitude | number | 是 | 0 | 经度范围 -180~180负数表示西经 | | speed | number | 是 | 0 | 速度浮点数单位 m/s | | accuracy | number | 是 | 无 | 位置的精确度 | | altitude | number | 是 | 0 | 高度单位 m | | verticalAccuracy | number | 是 | 0 | 垂直精度单位 mAndroid 无法获取返回 0 | | horizontalAccuracy | number | 是 | 0 | 水平精度单位 mAndroid、HarmonyOS 无法获取返回 0 | | address | string | 否 | null | 地址信息 |字段的端侧兼容性差异在文档与源码中均有一致体现verticalAccuracy在 HarmonyOS 4.81 起可用horizontalAccuracy在 Android、HarmonyOS 返回 0address地址信息仅 Android 3.9.0、iOS 4.11 起提供。仓库 Android 系统定位实现 src/uni_modules/uni-location-system/utssdk/app-android/index.uts 中onLocationChanged回调直接透传系统Location对象的latitude/longitude/speed/accuracy/altitude并将verticalAccuracy置 0、horizontalAccuracy复用accuracy、address置 null与文档描述完全吻合。2.3 uni.offLocationChange(callback)移除实时地理位置变化事件。兼容性| Web | 微信小程序 | Android | iOS | HarmonyOS 系统版本 | HarmonyOS | | :- | :- | :- | :- | :- | :- | | 4.0 | 4.41 | 4.81 | 4.81 | 5.0.0(11) | 4.81 |参数| 名称 | 类型 | 必填 | | :- | :- | :- | | listener | number | (res: OnLocationChangeResult) void | 否 |不传或传null时移除全部位置变化监听。示例工程src/pages/API/location-change/location-change.uvue中即使用uni.offLocationChange(null)先清理旧监听再注册新监听避免重复注册导致回调叠加。三、失败监听onLocationChangeError / offLocationChangeError3.1 接口定义uni.onLocationChangeError(callback)用于监听持续定位接口返回失败时触发uni.offLocationChangeError(callback)用于移除该监听。兼容性两者一致| Web | 微信小程序 | Android | iOS | HarmonyOS 系统版本 | HarmonyOS | | :- | :- | :- | :- | :- | :- | | 4.0 | 4.41 | 4.81 | 4.81 | 5.0.0(11) | 4.81 |参数| 名称 | 类型 | 必填 | | :- | :- | :- | | listeneron | (listener: IGetLocationFail) void | 是 | | listeneroff | number | (listener: IGetLocationFail) void | 否 |3.2 IGetLocationFail 错误对象失败回调统一返回IGetLocationFail结构| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | errCode | number | 是 | 错误码 | | errSubject | string | 是 | 统一错误主题模块名称 | | data | any | 否 | 错误信息中包含的数据 | | cause | Error | 否 | 源错误信息可以包含多个错误详见 UniError 规范 | | errMsg | string | 是 | 错误信息 |3.3 持续定位错误码全表这是排查持续定位问题最关键的对照表按当前有效码与已废弃码分类当前有效错误码| 合法值 | 描述 | 兼容性 | | :- | :- | :- | | 1505023 | 不支持逆地理编码 | Web: 4.0; Android: 3.9.0; iOS: 4.11; HarmonyOS 系统版本: 5.0.0(11); HarmonyOS: 4.61 | | 1505003 | 系统定位未开启请在系统设置中开启系统定位 | Android: 4.25; iOS: 4.25; HarmonyOS 系统版本: 5.0.0(11); HarmonyOS: 4.81 | | 1505004 | 应用定位权限未开启 | Android: 4.25; iOS: 4.25; HarmonyOS 系统版本: 5.0.0(11); HarmonyOS: 4.81 | | 1505600 | 超时 | Android: 4.25; iOS: 4.25 | | 1505601 | 不支持的定位类型 | Android: 4.25; iOS: 4.25; HarmonyOS 系统版本: 5.0.0(11); HarmonyOS: 4.81 | | 1505602 | 捕获定位失败 | Android: 4.25; iOS: 4.25; HarmonyOS 系统版本: 5.0.0(11); HarmonyOS: 4.81 | | 1505603 | 逆地理编码捕获失败 | Android: 4.25; iOS: 4.25; HarmonyOS: x | | 1505604 | 服务供应商获取失败 | Android: 4.25; iOS: 4.25; HarmonyOS: x | | 1505700 | 不支持逆地理编码 | Android: 4.25; iOS: 4.25; HarmonyOS: x | | 1505701 | 没有找到具体的定位引擎GPS_PROVIDER、NETWORK_PROVIDER、PASSIVE_PROVIDER 等请确定系统定位是否开启 | Android: 4.25; iOS: 4.25; HarmonyOS: x | | 1505800 | 应用高精度定位权限未开启 | Android: 4.25; iOS: 4.25; HarmonyOS: x | | 1505605 | 未通过配置预校验通常是腾讯定位 api key 配置错误 | Android: 4.25; iOS: 4.25; HarmonyOS: x | | 1505607 | 腾讯定位只支持 GCJ-02 | Android: 4.25; iOS: 4.25; HarmonyOS: x | | 1505608 | 同一时间只能单个 provider 开启持续定位 | Android: 4.81; iOS: 4.81; HarmonyOS: x | | 1505702 | iOS plist 文件中缺少后台定位配置UIBackgroundModes-location | Android: 4.81; iOS: 4.81; HarmonyOS: x |已废弃错误码自 4.25 起废弃兼容旧代码| 合法值 | 描述 | | :- | :- | |1505005| 缺失高精度权限授权iOS 特有 | |1505021| 超时 | |1505022| 不支持的定位类型 | |1505024| 没有找到具体的定位引擎请确认定位开关是否已打开 | |1505025| 逆地理编码捕获失败 | |1505026| 捕获定位失败 |这些错误码在仓库 src/uni_modules/uni-location/utssdk/interface.uts 中通过LocationErrorCode类型逐一枚举定义废弃项均带有deprecated 从4.25开始已经废弃标注与文档表格一一对应。Android 系统定位实现中type不为wgs84时直接构造GetLocationFailImpl(1505601)报错、无可用 provider 时构造GetLocationFailImpl(1505701)均可作为错误码实际触发的源码佐证。四、开启与关闭持续定位startLocationUpdate / stopLocationUpdate4.1 uni.startLocationUpdate(options)开启应用进入前台时接收位置消息。兼容性| Web | 微信小程序 | Android | iOS | HarmonyOS 系统版本 | HarmonyOS | | :- | :- | :- | :- | :- | :- | | 4.0 | 4.41 | 4.81 | 4.81 | 5.0.0(11) | 4.81 |options 参数| 名称 | 类型 | 必填 | 描述 | | :- | :- | :- | :- | | provider | string | 否 | 定位服务提供商通过uni.getProvider获取目前支持系统定位system、腾讯定位tencentweb 端暂不支持 provider 机制 | | type | string | 否 | 坐标系默认为wgs84返回 GPS 坐标gcj02返回可用于uni.openLocation的坐标web 端需配置定位 SDK 信息才支持 gcj02 | | success | (result: StartLocationUpdateSuccess) void | 否 | 接口调用成功的回调 | | fail | (result: IGetLocationFail) void | 否 | 接口调用失败的回调 | | complete | (result: any) void | 否 | 接口调用结束的回调成功、失败都会执行 |type 合法值| 合法值 | 描述 | | :- | :- | | wgs84 | wgs84 坐标系系统定位默认取值 wgs84且系统定位仅支持 wgs84 坐标系 | | gcj02 | gcj02 坐标系腾讯定位默认取值 gcj02且腾讯定位仅支持 gcj02 坐标系 |这是一个非常关键的约束系统定位system只认 wgs84腾讯定位tencent只认 gcj02交叉组合会直接触发错误码1505601 或 1505607。Android 端源码 src/uni_modules/uni-location-system/utssdk/app-android/index.uts 中startSystemLocation对type ! wgs84的请求直接fail(1505601)同时它优先使用 GPS provider 以获得高度信息并通过requestLocationUpdates(providerName, 2000, 0.0f, this)以约 2 秒间隔持续上报位置。4.2 uni.stopLocationUpdate(options)关闭监听实时位置变化前后台都停止消息接收。兼容性同上表Web 4.0 / 微信 4.41 / Android、iOS 4.81 / HarmonyOS 4.81。options 参数| 名称 | 类型 | 必填 | | :- | :- | :- | | success | (result: StopLocationUpdateSuccess) void | 否 | | fail | (result: IGetLocationFail) void | 否 | | complete | (result: any) void | 否 |在示例页面onUnload生命周期中会依次调用uni.stopLocationUpdate({})、uni.offLocationChange(null)、uni.offLocationChangeError(null)完成资源清理这是页面销毁时避免持续定位泄漏的标准写法。Android 实现中stopLocationUpdate会清空回调引用、unbindService解除后台定位服务绑定并removeUpdates移除系统定位监听。五、后台持续定位startLocationUpdateBackground5.1 接口说明开始监听实时地理位置信息变化事件应用进入前后台时均接收实时地理位置信息。兼容性| Web | 微信小程序 | Android | iOS | HarmonyOS 系统版本 | HarmonyOS | | :- | :- | :- | :- | :- | :- | | 4.0 | 4.41 | 4.81 | 4.81 | 5.0.0(11) | 4.81 |options 参数与startLocationUpdate完全一致provider / type / success / fail / complete其中 type 的合法值同样为wgs84系统定位默认与gcj02腾讯定位默认。5.2 iOS 后台定位配置必读iOS 平台若需要后台定位能力必须在info.plist中配置UIBackgroundModes的location且需在 Xcode 工程中开启对应 Capabilities 的 Background Modes 并勾选Location updates?xml version1.0 encodingUTF-8? !DOCTYPE plist PUBLIC -//Apple//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd plist version1.0 keyUIBackgroundModes/key array stringlocation/string /array /plist仓库根目录的 src/Info.plist 即为 uni-app x 示例工程的 plist 文件。缺少该配置时后台持续定位会触发错误码1505702iOS plist 文件中缺少后台定位配置UIBackgroundModes-location。5.3 HarmonyOS 权限要求HarmonyOS 端使用startLocationUpdateBackground需要以下权限声明ohos.permission.APPROXIMATELY_LOCATION模糊定位ohos.permission.LOCATION精确定位ohos.permission.LOCATION_IN_BACKGROUND后台定位对startLocationUpdate而言HarmonyOS 需要前两项权限如果后续调用startLocationUpdateBackground且已有 watchId会额外检查后台定位权限。HarmonyOS 实现见 src/uni_modules/uni-location-system/utssdk/app-harmony/locationChange.utsstartLocationUpdateBackground会先调用checkBackgroundPermission()无后台权限时以PERMISSION_ERROR拒绝底层通过geolocationWatchPosition注册位置监听enableHighAccuracy: true后台模式附带background: true位置变化回调同时转发给onLocationChange监听者失败则转发给onLocationChangeError。六、完整实战示例多 Provider、多坐标系持续定位页面文档给出的示例与仓库源码 src/pages/API/location-change/location-change.uvue 完全一致是一个可独立运行的持续定位演示页覆盖本文全部 API。核心逻辑如下template !-- #ifdef APP -- scroll-view stylemax-height: 300px; text stylemargin: 2px; padding: 2px; border: 1px solid #000000;{{ data.log }}/text /scroll-view !-- 选择定位服务提供商radio-group 绑定 providerList -- !-- 选择坐标系radio-group 绑定 types -- !-- #endif -- button classbtnstyle typeprimary tapstartLocationUpdate点击连续定位/button button classbtnstyle typeprimary tapstartLocationUpdateBackground后台点击连续定位/button button classbtnstyle typeprimary tapstopLocationUpdate点击关闭定位/button button classbtnstyle typeprimary taponLocationChangeonLocationChange/button button classbtnstyle typeprimary tapoffLocationChangeoffLocationChange/button button classbtnstyle typeprimary taponLocationChangeErroronLocationChangeError/button button classbtnstyle typeprimary tapoffLocationChangeErroroffLocationChangeError/button /template script setup languts type LocationType wgs84 | gcj02 export type LocationItem { id : string, name : string, provider ?: UniProvider } // 通过 uni.getProviderSync({ service: location }) 获取可用 provider 列表 const getProvider () { // #ifdef APP let provider uni.getProviderSync({ service: location } as GetProviderSyncOptions) provider.providerObjects.forEach((value : UniProvider) { data.providerList.push({ name: value.description, id: value.id, provider: value } as LocationItem) }) // #endif } const onLocationChange () { uni.offLocationChange(null) // 先清理避免重复监听 uni.onLocationChange((e) { console.log(onLocationChange持续监听回调: , e) data.log provider data.providerList[data.currentSelectedProvider].id \n JSON.stringify(e) \n\n }) } const startLocationUpdate () { // #ifdef APP if (data.providerList.length 0) { uni.showToast({ title: 未获取到provider请确定基座中包含location功能, icon: error }) return } // #endif const currentProvider data.providerList[data.currentSelectedProvider] uni.startLocationUpdate({ provider: currentProvider.id, type: types.value[data.currentSelectedType].value, success: () { data.startSuccess true }, fail: (err) { data.startSuccess false; data.errCode err.errCode } }) } const stopLocationUpdate () { uni.stopLocationUpdate({ success: () { data.stopSuccess true } }) } onLoad(() { /* #ifdef APP */ getProvider() /* #endif */ }) onUnload(() { uni.stopLocationUpdate({}) uni.offLocationChange(null) uni.offLocationChangeError(null) }) /script实现要点说明Provider 动态获取App 端通过uni.getProviderSync({ service: location })获取当前运行环境实际可用的定位服务提供商system / tencent默认选中system。坐标系联动选择 provider 为system时强制切到wgs84为tencent时强制切到gcj02从 UI 层面规避系统定位配 gcj02 / 腾讯定位配 wgs84的非法组合。错误码可观测startLocationUpdate的fail回调中记录err.errCode便于对照错误码表排查如 1505601、1505607、1505608。生命周期清理页面onUnload时统一停止定位并移除全部监听防止页面退出后定位服务仍在后台运行。七、测试驱动验证自动化测试如何锁定行为仓库为持续定位功能提供了完整的自动化测试 src/pages/API/location-change/location-change.test.js直接验证了文档中描述的坐标系约束与错误码行为| 测试用例 | 组合 | 期望结果 | | :- | :- | :- | | system typewgs84 | 系统定位 wgs84 | success各端均通过Android 需先用 adb 授予 FINE/COARSE/BACKGROUND 定位权限 | | system typegcj02 | 系统定位 gcj02 | 非 HarmonyOS 端 fail 且 errCode 1505601系统定位不支持 gcj02HarmonyOS 端 success | | tencent typewgs84 | 腾讯定位 wgs84 | fail 且 errCode 1505607腾讯定位只支持 GCJ-02 | | tencent typegcj02 | 腾讯定位 gcj02 | success | | tencentsystem 互切 | 先 tencent 后 system | 切换时失败 errCode 1505608同一时间只能单个 provider 开启持续定位先 stop 后再启动则成功 |测试通过program.reLaunch(PAGE_PATH)进入示例页用page.$(#startLocationUpdate)等选择器点击按钮再读取页面data中的startSuccess/errCode断言结果微信、Web 与 HarmonyOS 模拟器因有权限弹框干扰测试中直接跳过。这套测试既是对示例页面的回归保障也从侧面印证了provider 与坐标系强绑定、单 provider 互斥这两个持续定位的核心约束。八、最佳实践与常见问题8.1 最佳实践清单先监听、后开启典型顺序是uni.onLocationChange→uni.startLocationUpdate或startLocationUpdateBackground确保开启更新后能立刻收到回调。重复注册保护注册前先uni.offLocationChange(null)清理旧监听避免多个回调叠加导致重复处理。页面卸载必清理在onUnload中调用uni.stopLocationUpdate、uni.offLocationChange(null)、uni.offLocationChangeError(null)这是避免定位服务与回调泄漏的关键。按场景选 API仅前台业务如页面内的轨迹展示用startLocationUpdate需要息屏/切后台继续上报如骑行、配送才用startLocationUpdateBackground并务必配置 iOS 的UIBackgroundModes与 HarmonyOS 的LOCATION_IN_BACKGROUND权限。监听失败事件持续定位是长时间运行的能力务必同时注册onLocationChangeError处理系统定位被关闭1505003、权限被回收1505004等运行期异常。8.2 高频问题速查为什么系统定位传了 gcj02 报 1505601系统定位只支持 wgs84 坐标系gcj02 需切换腾讯定位tencent。为什么腾讯定位传 wgs84 报 1505607腾讯定位只支持 GCJ-02。为什么后台定位在 iOS 无效未在 src/Info.plist 配置UIBackgroundModes的location对应错误码 1505702且需在 Xcode Capabilities 中勾选 Background Modes → Location updates。为什么连续启动两个 provider 失败同一时间只允许单个 provider 开启持续定位错误码 1505608需先stopLocationUpdate再切换。Android 端拿不到高度Android 系统定位对verticalAccuracy恒返回 0这是平台能力限制altitude仅在 GPS 可用时才有意义这也是源码中优先选择 GPS provider 的原因。相关 API 声明、错误码定义可进一步阅读 src/uni_modules/uni-location/utssdk/interface.uts、系统定位实现 src/uni_modules/uni-location-system/utssdk/app-android/index.uts 与 HarmonyOS 实现 src/uni_modules/uni-location-system/utssdk/app-harmony/locationChange.uts。【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进