更新记录

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 中声明 pod AMapLocation 2.12.2,自动拉取。

你只需要申请 Key 并配置,不需要下载任何 SDK 文件。

Android

  1. 到 AMap 开放平台 申请 Android Key(需填包名 + SHA1)
  2. 在主工程的 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

  1. 申请 iOS Key
  2. 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>
  1. 勾选 Capabilities → Background Modes → Location updates
  2. 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 不一致, 会触发一系列编译错误。改用普通对象后,双端行为完全一致、零平台差异。

能力边界

  1. iOS 无法防止用户手动杀进程,系统限制,无解。
  2. Android 12+ 后台启动前台服务受限,建议引导用户开启「自启动」权限。
  3. 国产 ROM 需用户在系统设置中单独允许自启动。
  4. 系统权限弹窗无法静默授予,只能引导用户操作。
  5. iOS 后台定位频率由系统调度,不能保证固定时间间隔。

重要声明

  1. 插件封装的 AMap 定位 SDK 由各权利方所有,使用前请阅读并同意 高德地图开放平台服务条款与隐私政策。
  2. AMap Key 由使用者自行申请与保管。
  3. 本插件为独立第三方作品,与高德(AMap)官方无隶属、合作或背书关系。
  4. 因使用者违反 AMap 服务条款产生的责任,由使用者自行承担。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION、ACCESS_BACKGROUND_LOCATION、FOREGROUND_SERVICE、FOREGROUND_SERVICE_LOCATION、WAKE_LOCK、INTERNET、ACCESS_NETWORK_STATE、ACCESS_WIFI_STATE、CHANGE_WIFI_STATE、RECEIVE_BOOT_COMPLETED、REQUEST_IGNORE_BATTERY_OPTIMIZATIONS、POST_NOTIFICATIONS

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

本插件自身不采集、不上报任何数据。插件仅通过回调将位置数据(经纬度、精度、速度、方向、海拔、时间戳及逆地理编码结果)返回给调用方 App,不落盘、不缓存。插件封装的 AMap 定位 SDK 会将定位请求发往高德地图开放平台服务器,SDK 由使用者自行集成,具体规则见 https://lbs.amap.com/home/terms

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

本插件不包含任何广告,不集成广告SDK。

暂无用户评论。