更新记录
1.0.1(2026-10-21)
修复类型转换导致打包失败
1.0.0(2026-10-21)
1.0.0 首次发布。基于 AMap 定位 SDK 的双端持续定位插件,支持 Android 前台服务保活、iOS Background Modes,兼容 uni-app 与 uni-app x。
平台兼容性
uni-app(5.24)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| - | √ | - | - | - | - | - | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(5.24)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | × | √ |
AMap 持续定位保活(UTS 版)
一套 API 同时支持 Android 与 iOS 的前后台持续定位插件,基于 AMap 定位 SDK 封装。 同时兼容 uni-app 与 uni-app x。
为什么是 UTS 版
原 App 原生语言插件(nativeplugin)形式已停止维护、市场不再受理新增。
UTS 插件是官方主推方案,可同时运行于 uni-app 与 uni-app x。
特性
| 能力 | 说明 |
|---|---|
| 双端统一 API | 一套代码,iOS / Android 无需区分 |
| 持续定位 | 自定义间隔、逆地理编码、传感器测速 |
| 后台保活 | Android 前台服务 + WakeLock 自动续期;iOS Background Modes |
| 权限自检 | 一次检查 GPS、定位、后台定位、通知权限 |
| 集成自检 | 未集成 SDK 或未配置 Key 时明确提示,不静默失败 |
| 坐标转换 | 内置 GCJ02 ↔ WGS84 双向转换 |
| 单次定位 | 带 15 秒超时保护,失败可捕获 |
| 开机自启 | Android 重启后恢复定位(可选) |
平台支持
| 平台 | 最低版本 | 说明 |
|---|---|---|
| Android | 5.0 (API 21) | 支持 armeabi-v7a / arm64-v8a |
| iOS | 12.0 | 需配置 Background Modes |
| HBuilderX | 4.25+ | 使用 UTS 原生混编(hybrid.kt / hybrid.swift) |
快速开始
1. 安装
将插件放入项目 uni_modules/forever-location-uts/ 目录。
2. 集成 AMap SDK(必读)
✅ Android 端无需手动放 jar:插件已在
utssdk/app-android/config.json中通过 Maven 仓储声明com.amap.api:location:11.2.000,云端打包时自动拉取。 ✅ iOS 端无需手动集成:插件已在utssdk/app-ios/config.json中声明 podAMapLocation 2.12.2,自动拉取。你只需要申请 Key 并配置,不需要下载任何 SDK 文件。
Android
- 到 AMap 开放平台 申请 Android Key(需填包名 + SHA1)
- 在主工程的
AndroidManifest.xml(uni-app 项目中为manifest.json→app-plus→distribute→android→manifestPlaceholders) 的<application>内配置 Key:
<meta-data android:name="com.amap.api.v2.apikey" android:value="你的Android Key" />
⚠️ Key 必须配在主工程,不能配在插件里,否则会与插件声明冲突。
iOS
- 申请 iOS Key
- Info.plist 配置:
<key>AMapServices</key>
<dict>
<key>apiKey</key>
<string>你的iOS Key</string>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要获取您的位置信息以提供持续定位服务</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>需要在后台持续获取位置信息</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
- 勾选 Capabilities → Background Modes → Location updates
- AppDelegate 中初始化:
AMapServices.shared().apiKey = "你的iOS Key"
3. 使用
import * as fl from '@/uni_modules/forever-location-uts'
// 1. 先监听,再启动(避免漏掉最先到达的位置)
fl.onLocationChange((data) => {
console.log(data.latitude, data.longitude, data.address)
})
fl.onLocationError((err) => {
console.error(err.errCode, err.errMsg)
})
// 2. 检查权限与环境
const res = fl.checkPermission()
// 兼容旧版 checkPermission 的返回风格
if (!res.sdkAvailable) {
console.error(res.sdkMessage || '未集成 AMap SDK')
return
}
if (!res.apiKeyConfigured) {
console.error(res.apiKeyMessage || '未配置 AMap Key')
return
}
if (!res.gpsEnabled || !res.locationEnabled || !res.backLocationEnabled) {
fl.openLocationPermissionGroup()
return
}
// 3. 启动持续定位
fl.startLocation({
setInterval: 2,
needAddress: true,
foregroundServiceTitle: '持续定位中',
foregroundServiceContent: '位置服务正在后台运行',
success: (r) => {
console.log('已启动', r.isRunning)
if (r.warning) console.warn(r.warning)
if (r.notificationWarning) console.warn(r.notificationWarning)
},
fail: (e) => console.error('启动失败', e.errCode, e.errMsg),
})
// 4. 单次定位
fl.onGetCurrentLocation(true, (data, err) => {
if (err) {
console.error('单次定位失败', err.errMsg)
} else {
console.log('当前位置', data.latitude, data.longitude)
}
})
// 5. 停止
fl.stopLocation()
fl.destroyLocation()
API 一览
| 方法 | 说明 |
|---|---|
checkPermission() |
权限 + 环境自检(同步返回) |
startLocation(options) |
启动持续定位 |
stopLocation(options?) |
停止定位(释放 WakeLock) |
destroyLocation(options?) |
销毁客户端,彻底释放 |
isLocationRunning() |
是否运行中(同步返回 boolean) |
onLocationChange(cb) |
监听位置更新 |
onLocationError(cb) |
监听错误 |
offLocationChange() / offLocationError() |
移除监听 |
onGetCurrentLocation(needAddress, cb) |
单次定位,回调 (data, err) |
openLocationPermissionGroup(options?) |
引导开启定位权限 |
requestAlwaysAuthorization(options?) |
申请「始终允许」(iOS) |
setBatteryOptimizations(options?) |
引导电池优化白名单(Android) |
goToAppSettings(options?) |
打开应用设置 |
gcj02ToWgs84(lng, lat) |
坐标转换 |
wgs84ToGcj02(lng, lat) |
坐标转换 |
on开头且只有一个回调参数的方法(onLocationChange/onGetCurrentLocation) 会持续回调,符合 UTS 的持续回调约定。
位置数据
{
"latitude": 39.908823,
"longitude": 116.397470,
"accuracy": 15,
"speed": 0,
"bearing": 0,
"altitude": 45,
"timestamp": 1720000000000,
"provider": "amap",
"address": "北京市东城区...",
"province": "北京市",
"city": "北京市",
"district": "东城区",
"adCode": "110101"
}
坐标为 GCJ02(火星坐标),地图展示可直接使用;上报国际标准请先用
gcj02ToWgs84转换。
错误码
| 错误码 | 说明 |
|---|---|
| 9010001 | 定位权限未授予 |
| 9010002 | 定位服务未开启 |
| 9010003 | AMap SDK 错误 |
| 9010004 | 后台定位权限未授予 |
| 9010006 | 参数无效 |
| 9010007 | 未检测到 AMap SDK 或未配置 Key |
| 9099999 | 未知错误 |
错误对象结构
失败回调返回的是普通对象(不是 UniError):
{
errCode: number // 见上表
errMsg: string // 已本地化的错误文案
detail?: string // 补充说明,如引导用户去哪设置
}
为什么不用
UniError:UniError.errCode是 Objective-C 的@objc dynamic NSNumber属性, Swift 子类无法 override,且 uts 的联合类型 / 泛型Map在 Swift 侧行为与 Kotlin 不一致, 会触发一系列编译错误。改用普通对象后,双端行为完全一致、零平台差异。
能力边界
- iOS 无法防止用户手动杀进程,系统限制,无解。
- Android 12+ 后台启动前台服务受限,建议引导用户开启「自启动」权限。
- 国产 ROM 需用户在系统设置中单独允许自启动。
- 系统权限弹窗无法静默授予,只能引导用户操作。
- iOS 后台定位频率由系统调度,不能保证固定时间间隔。
重要声明
- 插件封装的 AMap 定位 SDK 由各权利方所有,使用前请阅读并同意 高德地图开放平台服务条款与隐私政策。
- AMap Key 由使用者自行申请与保管。
- 本插件为独立第三方作品,与高德(AMap)官方无隶属、合作或背书关系。
- 因使用者违反 AMap 服务条款产生的责任,由使用者自行承担。

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