uni-app Android 定位接入实战:uni-getLocation 的 system 与 tencent 双引擎配置及源码解析
【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app
本指南聚焦 uni-app 在 Android 端定位能力(uni-getLocation)的接入方式,围绕「系统定位(system)」与「腾讯定位(tencent)」两条提供者链路,完整覆盖本地依赖库、build.gradle / build.gradle.kts 插件注册配置(含 4.61 版本前后差异)、腾讯 AppKey 校验规则与常见错误码。读完本文,你将能够在 VDOM 与 Vapor(蒸汽模式)两种渲染架构下正确注册定位提供者,并能结合仓库源码理解uni.getLocation等接口在 Android 端的真实执行链路,从而自主排查定位失败问题。
一、模块总览:定位能力如何以「提供者」形式落地 Android
在 uni-app 的 Android 工程中,定位并不是一个内置写死的黑盒,而是通过uni-ext-api 提供者(Provider)机制动态注册的。仓库中src/uni_modules/uni-location/package.json定义了服务契约:
service固定为location;- 提供者通过
uni-ext-api声明对外暴露的 API,包括getLocation、startLocationUpdate、stopLocationUpdate、onLocationChange、offLocationChange、startLocationUpdateBackground、onLocationChangeError、offLocationChangeError共 8 个接口(src/uni_modules/uni-location/package.json#L33-L111); - 具体能力由
uni-location-system(系统定位)与uni-location-tencent(腾讯定位)两个插件实现,二者在src/uni_modules/uni-location-system/package.json、src/uni_modules/uni-location-tencent/package.json中通过uni_modules.uni-ext-api.provider声明各自的name(system/tencent)与servicePlugin(uni-location)。
运行时通过UTSRegisterProviders这一BuildConfig字段把实现类注册进定位引擎,业务层调用uni.getLocation(...)时,定位引擎会按注册的name分发到对应实现。因此,能否正常定位,第一步就是正确完成本指南中的注册配置。
适用前提:以下配置均针对 Android 原生工程(离线打包 / 本地打包),需要把 uni-app 提供的 AAR 本地依赖库放入工程并修改主模块的
build.gradle或build.gradle.kts。VDOM 与 Vapor 两种渲染架构均适用。
二、system 系统定位接入
系统定位直接使用 Android 系统自带的LocationManager能力,无第三方 SDK 依赖、无需申请 AppKey,是成本最低的接入方式。
2.1 本地依赖库
接入系统定位需要引入以下两个 AAR(注意命名随版本演进发生过变更,新老名称对比如下):
| 说明 | 本地依赖库名称 |
|---|---|
| 定位通用基础库 | uni-location-release.aar |
| 系统定位提供者 | uni-location-system-release.aar(原为:uni-getLocation-system-release.aar) |
其中
uni-location-release.aar是定位基础库,uni-location-tencent同样依赖它,因此在同时接入多个定位提供者时只需引入一份基础库。
2.2 插件注册(VDOM 与 Vapor 均适用)
以下配置内容添加到主模块的build.gradle(或 KTS 工程对应的build.gradle.kts)中,4.61 版本前后注册类所在包名不同,请严格按版本选择。
4.61 之后配置
build.gradle:
defaultConfig { buildConfigField 'String', 'UTSRegisterProviders', '"[{\"name\":\"system\",\"service\":\"location\",\"class\":\"uts.sdk.modules.DCloudUniLocationSystem.UniLocationSystemProviderImpl\"}]"' }build.gradle.kts:
defaultConfig { buildConfigField("String", "UTSRegisterProviders", "\"[{\\\"name\\\":\\\"system\\\",\\\"service\\\":\\\"location\\\",\\\"class\\\":\\\"uts.sdk.modules.DCloudUniLocationSystem.UniLocationSystemProviderImpl\\\"}]\"") }4.61 之前配置
build.gradle:
defaultConfig { buildConfigField 'String', 'UTSRegisterProviders', '"[{\"name\":\"system\",\"service\":\"location\",\"class\":\"uts.sdk.modules.DCloudUniGetLocationSystem.UniLocationSystemProviderImpl\"}]"' }build.gradle.kts:
defaultConfig { buildConfigField("String", "UTSRegisterProviders", "\"[{\\\"name\\\":\\\"system\\\",\\\"service\\\":\\\"location\\\",\\\"class\\\":\\\"uts.sdk.modules.DCloudUniGetLocationSystem.UniLocationSystemProviderImpl\\\"}]\"") }差异仅在于包名中的DCloudUniLocationSystem(4.61 之后)与DCloudUniGetLocationSystem(4.61 之前),与 AAR 的重命名(去掉getLocation中的get)保持一致,注册 JSON 中其余字段完全一致:name为system,service为location。
2.3 权限与清单声明
系统定位的 Android 权限与前台服务声明定义在插件自带的清单文件中(src/uni_modules/uni-location-system/utssdk/app-android/AndroidManifest.xml),打包时会自动合并,无需手动添加:
android.permission.ACCESS_FINE_LOCATION:通过 GPS 获取精确位置;android.permission.ACCESS_COARSE_LOCATION:通过网络获取粗略位置;android.permission.INTERNET:部分位置信息需从网络服务器获取;android.permission.FOREGROUND_SERVICE与android.permission.ACCESS_BACKGROUND_LOCATION:用于前台 / 后台持续定位;- 同时声明了后台定位服务
uts.sdk.modules.DcloudUniGetBackgroundLocation.UniSystemLocationService,foregroundServiceType为location。
从源码结构看(src/uni_modules/uni-location-system/utssdk/app-android/config.json),该插件要求minSdkVersion不低于 19。运行时权限(ACCESS_FINE_LOCATION)由插件实现类在定位前通过UTSAndroid.requestSystemPermission主动申请,参考src/uni_modules/uni-location-system/utssdk/app-android/index.uts#L33-L49。
2.4 源码级解析:系统定位的执行链路
系统定位的核心实现为UniLocationSystemProviderImpl(src/uni_modules/uni-location-system/utssdk/app-android/index.uts),其关键行为如下:
- 坐标系限制:
getLocationImpl中强制要求type为wgs84,否则直接抛出1505601(不支持的定位类型)错误;geocode(逆地理编码)参数不被支持,置为true会返回1505700(不支持逆地理编码)。 - Provider 选择策略:构造
android.location.Criteria时,若isHighAccuracy为true则设置ACCURACY_FINE,否则为ACCURACY_COARSE;altitude为true时额外设置setAltitudeRequired(true)。默认优先选择gps(以便返回高度信息),若当前设备不可用则回退到getBestProvider(criteria, true);若仍无可用 provider,返回1505701(没有找到具体的定位引擎,请检查系统定位开关)。 - 超时与缓存兜底:默认超时
6000ms;只有当highAccuracyExpireTime >= 3000且isHighAccuracy == true时才会使用该值作为超时时间。定位时先尝试getLastKnownLocation直接返回缓存,同时继续注册位置更新;超时未拿到新位置时,按network → passive → gps顺序回退返回缓存,全部失败则返回1505600(超时)。 - 持续定位:
startLocationUpdate走startSystemLocation,同样仅支持wgs84,请求间隔2000ms;startLocationUpdateBackground则通过bindService绑定到UniSystemLocationService(src/uni_modules/uni-location-system/utssdk/app-android/UniSystemLocationService.kt),该服务在 Android 10(API 29)及以上使用startForeground(1000, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION)启动前台定位服务,保证应用退到后台后定位仍可继续。
三、tencent 腾讯定位接入
腾讯定位基于腾讯位置服务(TencentLBS)Android 定位 SDK,支持 GCJ-02 坐标系、逆地理编码(地址解析)与前后台持续定位,适合对精度、地址信息有更高要求的业务场景。
3.1 添加腾讯定位 SDK 依赖
在项目应用(app 模块)下的build.gradle中添加依赖:
build.gradle:
dependencies { implementation "com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.5.4.8" }build.gradle.kts:
dependencies { implementation("com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.5.4.8") }3.2 本地依赖库
| 说明 | 本地依赖库名称 |
|---|---|
| 定位通用基础库 | uni-location-release.aar |
| 腾讯定位提供者 | uni-location-tencent-release.aar(原为:uni-getLocation-tencent-release.aar) |
3.3 插件注册(VDOM 与 Vapor 均适用)
同样将以下内容添加到主模块的build.gradle,并按版本选择注册类。
4.61 之后配置
build.gradle:
defaultConfig { buildConfigField 'String', 'UTSRegisterProviders', '"[{\"name\":\"tencent\",\"service\":\"location\",\"class\":\"uts.sdk.modules.DCloudUniLocationTencent.UniLocationTencentProviderImpl\"}]"' }build.gradle.kts:
defaultConfig { buildConfigField("String", "UTSRegisterProviders", "\"[{\\\"name\\\":\\\"tencent\\\",\\\"service\\\":\\\"location\\\",\\\"class\\\":\\\"uts.sdk.modules.DCloudUniLocationTencent.UniLocationTencentProviderImpl\\\"}]\"") }4.61 之前配置
build.gradle:
defaultConfig { buildConfigField 'String', 'UTSRegisterProviders', '"[{\"name\":\"tencent\",\"service\":\"location\",\"class\":\"uts.sdk.modules.DCloudUniGetLocationTencent.UniLocationTencentProviderImpl\"}]"' }build.gradle.kts:
defaultConfig { buildConfigField("String", "UTSRegisterProviders", "\"[{\\\"name\\\":\\\"tencent\\\",\\\"service\\\":\\\"location\\\",\\\"class\\\":\\\"uts.sdk.modules.DCloudUniGetLocationTencent.UniLocationTencentProviderImpl\\\"}]\"") }3.4 AppKey 配置与源码级预校验
腾讯定位需要开发者前往腾讯位置服务控制台申请 AppKey,并配置到应用清单的TencentMapSDK元数据中。插件在每次定位前都会执行配置预校验(checkLocationConfig,见src/uni_modules/uni-location-tencent/utssdk/app-android/index.uts#L208-L227):
- 读取应用
metaData中的TencentMapSDK字段,字段不存在则校验失败; - 以
-分割 AppKey,若分段数不超过 5,则认为不符合 AppKey 规则,校验失败; - 校验失败统一返回错误码
1505605(未通过配置预校验,通常是腾讯定位 AppKey 配置错误)。
因此配置 AppKey 后务必确认应用清单中TencentMapSDK元数据已正确写入,且 AppKey 为完整有效的正式 Key(而非测试占位值)。
3.5 源码级解析:腾讯定位的执行链路
腾讯定位核心实现为UniLocationTencentProviderImpl(src/uni_modules/uni-location-tencent/utssdk/app-android/index.uts),关键行为:
- 坐标系限制:单次定位(
getLocationImpl)与持续定位(requestLocation)均只接受GCJ-02/GCJ02(比较时转为大写),传入其他类型返回1505607。getLocation返回的type语义上对应国测局坐标。 - 隐私合规:每次定位前调用
TencentLocationManager.setUserAgreePrivacy(true)声明用户已同意隐私政策,符合腾讯定位 SDK 的合规要求。 - 逆地理编码:
geocode: true时使用TencentLocationRequest.REQUEST_LEVEL_NAME(返回详细地址address),否则使用REQUEST_LEVEL_GEO;与系统定位不同,腾讯定位支持地址解析。 - 高精度与高度:
isHighAccuracy或altitude为true时调用locationRequest.setAllowGPS(true)允许使用 GPS;单次定位通过requestSingleFreshLocation发起,持续定位设置setInterval(2000)并注册监听。 - 后台定位:
startLocationUpdateBackground会设置isBackgroundLocation = true,调用enableForegroundLocation(1001, notif)启用前台定位能力;停止时removeUpdates并disableForegroundLocation(true)。 - 定位状态回调:在
onStatusUpdate中监听gps状态,GPS 被关闭(status 为 0)时通过onLocationChangeError抛出1505003(系统定位未开启)错误。
四、两个提供者的选型对比
| 维度 | system 系统定位 | tencent 腾讯定位 |
|---|---|---|
| 第三方 SDK | 无 | 腾讯位置服务 Android 定位 SDK 7.5.4.8 |
| AppKey | 不需要 | 需要,且要求TencentMapSDK元数据通过预校验 |
| 坐标系(type) | 仅wgs84 | 仅GCJ-02/GCJ02 |
| 逆地理编码(geocode/address) | 不支持,返回1505700 | 支持(REQUEST_LEVEL_NAME) |
| 高度信息 | 支持(优先 GPS provider) | 通过setAllowGPS(true)间接支持 |
| 权限申请 | 运行时申请ACCESS_FINE_LOCATION | 运行时申请ACCESS_FINE_LOCATION,另需 AppKey 配置 |
| 超时控制 | 默认 6000ms,可配置highAccuracyExpireTime(需 ≥3000ms) | 由 SDK 内部处理单次请求 |
选择建议:仅需经纬度、希望免 SDK 免 Key 快速上线,选 system;需要地址信息、偏转坐标(GCJ-02)或对定位稳定性要求更高,选 tencent。两种提供者可在同一工程中并存,通过UTSRegisterProviders注册的name区分,业务侧无需改代码即可切换。
五、错误码速查表
定位相关错误码集中定义在src/uni_modules/uni-location/utssdk/interface.uts(LocationErrorCode),以下为 Android 端常用错误码:
| 错误码 | 含义 |
|---|---|
1505003 | 系统定位未开启,请在系统设置中开启系统定位 |
1505004 | 应用定位权限未开启 |
1505600 | 超时 |
1505601 | 不支持的定位类型 |
1505602 | 捕获定位失败 |
1505603 | 逆地理编码捕获失败 |
1505604 | 服务供应商获取失败 |
1505605 | 未通过配置预校验,通常是腾讯定位 AppKey 配置错误 |
1505700 | 不支持逆地理编码(系统定位调用geocode时触发) |
1505701 | 没有找到具体的定位引擎(GPS / NETWORK / PASSIVE 等),请确认系统定位是否开启 |
1505800 | 应用高精度定位权限未开启 |
其中1505005、1505021~1505026等旧错误码在源码注释中标明自 4.25 起已废弃,实际排查以1505xxx系列新码为准。
六、验证与进一步探索
完成配置后,可通过以下仓库路径验证与深入学习:
- 提供者契约与错误码:src/uni_modules/uni-location/utssdk/interface.uts、src/uni_modules/uni-location/package.json;
- 系统定位实现:src/uni_modules/uni-location-system/utssdk/app-android/index.uts、src/uni_modules/uni-location-system/utssdk/app-android/AndroidManifest.xml、src/uni_modules/uni-location-system/utssdk/app-android/UniSystemLocationService.kt;
- 腾讯定位实现:src/uni_modules/uni-location-tencent/utssdk/app-android/index.uts(含 AppKey 校验逻辑);
- API 文档:docs/api/get-location.md。
验证步骤建议:先确认 AAR 已放入工程且UTSRegisterProviders中注册类名与 HBuilderX 版本匹配(4.61 前后包名不同);再调用uni.getLocation({ type: 'wgs84' | 'gcj02', success, fail }),若返回1505605检查腾讯 AppKey,若返回1505701检查系统定位开关与权限。注意:仓库内src/pages/API目录(如 src/pages/API/location/location.uvue)提供了定位相关示例页面源码,可作为调用方式参考。
七、常见问题(FAQ)
- 两个提供者都要接入,
UTSRegisterProviders如何写?该字段是 JSON 数组字符串,多个提供者用,分隔,例如同时注册 system 与 tencent 时构造[{"name":"system",...},{"name":"tencent",...}]的转义形式即可,service均为location。 - 4.61 前后配置选哪个?以你使用的 HBuilderX / 打包基座版本为准:4.61 及之后使用
DCloudUniLocationSystem/DCloudUniLocationTencent包名,之前使用DCloudUniGetLocationSystem/DCloudUniGetLocationTencent。 - 系统定位想返回地址(address)怎么办?系统定位不支持逆地理编码,如需地址信息请改用腾讯定位(
geocode: true),或在业务层对wgs84坐标自行调用逆地理编码服务。 - 定位一直超时(1505600)?优先确认系统定位开关已开启、
ACCESS_FINE_LOCATION已授权;室内环境 GPS 首定位较慢时可先依赖缓存兜底逻辑,或适当调大highAccuracyExpireTime(注意需 ≥3000ms 且配合isHighAccuracy: true才生效)。 - 腾讯定位返回 1505605?检查应用清单
TencentMapSDK元数据是否配置、AppKey 是否完整有效(源码要求以-分段后超过 5 段),并确认已按腾讯位置服务要求开启对应服务。
【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考