uni-app x HarmonyOS 系统定位模块集成指南:uni-location-system 原生模块配置与原理
【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app
本篇技术指南聚焦 uni-app x 在 HarmonyOS(鸿蒙)原生工程中集成「系统定位」模块(UTS 插件uni-location-system)的完整流程,覆盖 har 依赖引入、index.generated.ets模块注册(含 VDOM 与蒸汽两种模式)、底层权限模型与坐标系转换原理,以及错误码映射。读完本文,你将能够把系统定位能力(uni.getLocation、持续定位与位置监听)正确接入鸿蒙原生工程,并理解其底层实现机制,便于二次开发与问题排查。
一、模块是什么:系统定位uni-location-system
uni-app x 的定位能力通过 provider 机制实现,鸿蒙端目前支持「系统定位(system)」provider。系统定位模块在仓库中对应 UTS 插件 uni-location-system,其职责是"实现获取当前位置信息(使用系统定位)功能",底层调用 HarmonyOS 的位置服务能力。
模块代码按平台拆分,位于utssdk目录下(见 readme.md 的平台目录说明):
| 目录/文件 | 目标平台 | 实现语言 | 作用描述 | | -- | -- | -- | -- | | utssdk/app-harmony | HarmonyOS(鸿蒙) | UTS、ArkTS | 鸿蒙端系统定位实现 | | utssdk/app-android | Android | UTS、Kotlin、Java | Android 端系统定位实现 | | utssdk/app-ios | iOS | UTS、Swift | iOS 端系统定位实现 | | utssdk/*.uts | 多平台共用 | UTS | 共用实现源码 |
其中鸿蒙端的核心文件包括:
- interface.uts:定义
UniLocationSystemProvider接口,继承自UniLocationProvider; - index.uts:provider 实现类
UniLocationSystemProviderImpl及单次定位逻辑; - locationChange.uts:持续定位(前后台)与位置监听;
- geolocation.uts:封装
@ohos.geoLocationManager的底层定位与权限逻辑。
说明:该插件在 uni-app x 项目内正常开发时由编译器自动处理;本文面向「鸿蒙原生工程混编」场景,需要手动完成依赖配置与模块注册。
二、配置依赖:引入 har 包
系统定位依赖 har 包@uni_modules/uni-location-system。该 har 包未发布到鸿蒙 ohpm 仓库,需要自行从任意 uni-app x 项目编译到鸿蒙的产物中拷贝。
2.1 获取 har 包
在任意 uni-app x 项目编译到鸿蒙后,产物目录中会生成定位模块的 har 包:
unpackage/dist/dev/app-harmony/libs/uni_modules__uni_location_system.har将其拷贝到鸿蒙原生工程内(例如拷贝到工程的libs目录下),作为本地依赖引入。
2.2 声明依赖
在鸿蒙原生工程根目录的oh-package.json5文件的dependencies字段下添加:
"@uni_modules/uni-location-system": "./libs/uni_modules__uni_location_system.har"路径需与实际拷贝位置保持一致,./libs/前缀表明这是本地文件依赖而非 ohpm 线上包。
三、注册模块:index.generated.ets 入口
鸿蒙原生工程内的 uni_modules 入口文件为/entry/src/main/ets/uni_modules/index.generated.ets,如果没有需要自行创建(集成细节可参考 docs/native/use/harmonyuts.md 中"将 uni_modules 入口文件移动到/entry/src/main/ets/uni_modules/index.generated.ets"的步骤,以及模块总览 docs/native/modules/harmony/modules.md)。
在该文件内注册系统定位 API,根据渲染模式不同,代码有 VDOM 与蒸汽两种写法:
VDOM 模式
import { registerUniProvider, uni } from '@dcloudio/uni-app-x-runtime' import { UniLocationSystemProviderImpl } from '@uni_modules/uni-location-system' export function initUniModules() { initUniExtApi() } function initUniExtApi() { registerUniProvider('location', 'system', new UniLocationSystemProviderImpl()) }蒸汽(Vapor)模式
import { registerUniProvider, uni } from '@dcloudio/uni-app-x-vapor-runtime' import { UniLocationSystemProviderImpl } from '@uni_modules/uni-location-system' export function initUniModules() { initUniExtApi() } function initUniExtApi() { registerUniProvider('location', 'system', new UniLocationSystemProviderImpl()) }两种模式的差异仅在于运行时包名:VDOM 使用@dcloudio/uni-app-x-runtime,蒸汽模式使用@dcloudio/uni-app-x-vapor-runtime(蒸汽模式 SDK 需 HBuilderX 5.25+,见 docs/native/README.md)。注册的核心动作一致:通过registerUniProvider('location', 'system', impl)将 provider 实现注册到定位服务提供商的扩展点上,'location'为服务名,'system'为 provider 标识,与uni.getLocation中provider: 'system'参数对应。
3.1 在 EntryAbility 中调用初始化
注册完成后,还需在鸿蒙工程entry/src/main/ets/entryability/EntryAbility.ets文件中调用初始化方法(依据 docs/native/modules/harmony/modules.md 的约定):
import { initUniModules } from '../uni_modules/index.generated' initUniModules()这样应用启动时即完成定位 provider 的注册,uni.getLocation等 API 才能在鸿蒙端被解析到系统定位实现。
四、底层实现原理:UniLocationSystemProviderImpl
注册进 provider 机制的实现类为UniLocationSystemProviderImpl,其完整定义位于 index.uts。从源码结构看,它实现了UniLocationSystemProvider接口并对外暴露以下能力:
| 方法 | 对应业务能力 | | -- | -- | | getLocation(options) | 单次定位,对应uni.getLocation| | startLocationUpdate(options) | 开始持续定位 | | startLocationUpdateBackground(options) | 开始后台持续定位 | | stopLocationUpdate(options) | 停止持续定位 | | onLocationChange(callback) | 注册位置变化监听 | | onLocationChangeError(callback) | 注册定位错误监听 |
provider 的id为"system"、description为"系统定位",与注册时的 provider 标识一致。
4.1 单次定位流程
单次定位的核心逻辑在_getLocation(见 index.uts),流程如下:
- 申请前台权限:默认申请
ohos.permission.APPROXIMATELY_LOCATION(模糊定位);当options.isHighAccuracy为 true 时追加ohos.permission.LOCATION(精确定位); - 发起定位请求:构造
geoLocationManager.CurrentLocationRequest,高精度时priority取ACCURACY,否则取FIRST_FIX; - 超时控制:
highAccuracyExpireTime有值则作为timeoutMs,否则高精度模式下默认 3000ms; - 结果组装:返回
GetLocationSuccess,包含 latitude、longitude、speed、accuracy、altitude、verticalAccuracy、horizontalAccuracy、address 字段; - 逆地理编码:当
options.geocode为 true 时,调用getAddressesFromLocation解析placeName填入 address(注意:虽然 docs/api/get-location.md 兼容性表对 HarmonyOS 逆地理编码标注为 x,但当前鸿蒙源码已实现该分支,实际行为以官方发布版本的兼容性标注为准); - 坐标系转换:当
type === 'gcj02'时,通过map.convertCoordinate将 WGS84 坐标转换为 GCJ02 坐标。
4.2 权限请求与处理
鸿蒙端权限请求封装在requestPermission(见 geolocation.uts),通过abilityAccessCtrl.createAtManager().requestPermissionsFromUser弹窗申请,只要任一权限被拒绝即视为申请失败。
权限类型定义(index.uts):
type Permission = | 'ohos.permission.APPROXIMATELY_LOCATION' | 'ohos.permission.LOCATION' | 'ohos.permission.LOCATION_IN_BACKGROUND'APPROXIMATELY_LOCATION:前台模糊位置权限(默认申请);LOCATION:前台精确定位权限(高精度时申请);LOCATION_IN_BACKGROUND:后台位置权限。
后台权限特殊处理:出于安全隐私要求,应用不能通过弹窗被授予后台位置权限。源码中的处理逻辑是(见 geolocation.uts):调用checkBackgroundPermission用atManager.checkAccessTokenSync检查后台权限,未授权时通过uni.showModal提示用户"需要允许应用在后台获取位置信息方可继续",确认后拉起系统设置页(com.huawei.hmos.settings)引导用户手动授予。用户可在以下路径手动设置:
- 设置 > 隐私和安全 > 位置信息 > 具体应用
- 设置 > 应用和元服务 > 某个应用
4.3 坐标类型校验
持续定位场景下,watchPosition会校验coordsType(见 geolocation.uts):仅支持'wgs84'与'gcj02',其他值直接返回错误COORDS_TYPE_ERROR并返回-1表示创建失败;gcj02模式下每次回调同样经过map.convertCoordinate做坐标转换。
五、API 参数与坐标系说明
系统定位对外暴露的参数与uni.getLocation对齐,完整定义见 docs/api/get-location.md。与鸿蒙系统定位强相关的关键参数:
| 参数 | 类型 | 默认值 | 说明 | | -- | -- | -- | -- | | provider | string | system | 定位服务提供商,目前支持 system(系统定位)、tencent(腾讯定位);注册时以'system'标识 | | type | string | wgs84 |wgs84返回 GPS 坐标;gcj02返回可用于uni.openLocation的坐标 | | isHighAccuracy | boolean | false | 开启高精度定位(鸿蒙端会额外申请LOCATION权限) | | highAccuracyExpireTime | number | 3000 | 高精度定位超时时间(ms),该值 3000ms 以上高精度定位才有效果 | | geocode | boolean | false | 传入 true 解析地址(鸿蒙兼容性以发布版本标注为准) | | altitude | boolean | false | 传入 true 返回高度信息,会减慢接口返回速度 | | success / fail / complete | function | - | 成功 / 失败 / 结束回调 |
GetLocationSuccess主要返回字段:
| 字段 | 说明 | | -- | -- | | latitude | 纬度,范围 -90~90,负数表示南纬 | | longitude | 经度,范围 -180~180,负数表示西经 | | speed | 速度,单位 m/s | | accuracy | 位置精确度 | | altitude | 高度,单位 m | | verticalAccuracy | 垂直精度,单位 m(鸿蒙从altitudeAccuracy取值) | | horizontalAccuracy | 水平精度,单位 m(鸿蒙从directionAccuracy取值,缺失时为 0) | | address | 地址信息,未解析时为 null |
六、持续定位与位置监听
持续定位相关实现位于 locationChange.uts,通过模块级变量保存监听回调与 watchId:
6.1 开始/停止定位
startLocationUpdate:调用底层watchPosition建立监听,底层以interval: 1、PowerConsumptionScenario.HIGH_POWER_CONSUMPTION的LocationRequest订阅geoLocationManager.on('locationChange')(见 geolocation.uts),enableHighAccuracy固定为 true;startLocationUpdateBackground:若已存在 watch,则直接校验后台权限;否则建立带background: true的监听;stopLocationUpdate:调用geoLocationManager.off('locationChange', handler)移除监听,并重置started与watchId。
6.2 监听回调
onLocationChange(callback) // 位置变化回调 onLocationChangeError(callback) // 定位错误回调实现中通过_onLocationChange、_onLocationChangeError两个模块级变量保存回调,底层watchPosition的 success/error 分支分别触发。首次建立监听失败时,startLocationUpdate的 Promise 会 reject 并透传错误给options.fail。
6.3 多小程序实例隔离
值得注意的细节是,geolocation.uts通过getCurrentMP()按appId维护独立的PositionWatchStores,并在beforeClose事件中自动清理对应 watch(见 geolocation.uts),避免多实例场景下位置监听互相干扰。
七、错误码映射
鸿蒙端将系统层错误码统一映射为 uni-app x 规范错误码,映射表在 index.uts 与 geolocation.uts 中定义(两处保持一致):
| 鸿蒙错误 | 映射 errCode | 含义 | | -- | -- | -- | | 3301100 | 1505003 | 系统定位未开启,请在系统设置中开启系统定位 | | PERMISSION_ERROR | 1505004 | 应用定位权限未开启 | | COORDS_TYPE_ERROR | 1505601 | 不支持的定位类型 | | 3301300 | 1505603 | 定位超时 | | 3301000 / default | 1505602 | 捕获定位失败 |
未匹配到的错误码统一落到1505602(defaultErrorCode),业务侧可依据 docs/api/get-location.md 的 errCode 表做统一错误提示。
八、集成步骤速览与注意事项
8.1 操作清单
- 在 uni-app x 项目编译鸿蒙产物,从
unpackage/dist/dev/app-harmony/libs/拷贝uni_modules__uni_location_system.har到鸿蒙原生工程; - 在鸿蒙工程
oh-package.json5的dependencies中添加"@uni_modules/uni-location-system": "./libs/uni_modules__uni_location_system.har"; - 在
/entry/src/main/ets/uni_modules/index.generated.ets中按 VDOM/蒸汽模式注册UniLocationSystemProviderImpl; - 在
EntryAbility.ets中调用initUniModules(); - 在
module.json5中声明ohos.permission.APPROXIMATELY_LOCATION等权限(前台/后台权限按需声明); - 后台定位需引导用户在系统设置中手动授权「始终允许」。
8.2 注意事项
- har 包未发布到 ohpm,升级 uni-app x 版本后需重新从最新编译产物拷贝替换;
- VDOM 与蒸汽模式的运行时依赖包名不同,注册代码需按项目实际模式选择;
- 后台定位权限无法弹窗申请,必须通过设置界面手动授予(源码已内置
uni.showModal引导逻辑); geocode与horizontalAccuracy等字段在鸿蒙端的行为以官方 API 兼容性标注为准,源码实现可能与文档表格存在版本差异;- 坐标系默认返回 wgs84,若需在
uni.openLocation(gcj02)中使用,应显式传type: 'gcj02',转换由底层map.convertCoordinate完成。
【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考