摘要:本文介绍 uni-app UTS 插件 keepalive-track-tool 的完整实战方案。该插件与 keepalive-location 分工协作,负责轨迹的 SQLite 持久化、GPX/CSV 导出、圆形与多边形电子围栏判定,以及 Android、iOS、鸿蒙三端的系统 TTS 语音播报。文中包含三端原生实现架构、安装避坑指南、30 行快速接入代码,以及导出上传对接示例。

一、前言:为什么需要第二个插件?

在 uni-app 做 后台持续定位 时,keepalive-location 已经解决了最难的部分:权限申请、前台服务、iOS Background Modes、鸿蒙后台任务等。但业务往往还需要:

  • 把 GPS 点 持久化 成本地轨迹,进程被杀也能恢复
  • 导出 GPX / CSV 给第三方地图或后台系统
  • 配置 圆形 / 多边形电子围栏,进出区域时回调 + 语音播报
  • 全程 不重复起第二路定位,避免耗电翻倍、权限冲突

keepalive-track-tool 就是为此而生的配套 UTS 插件:定位归 keepalive-location,存储 / 导出 / 围栏 / TTS 归本插件。两者分工清晰,接入代码通常不到 30 行。

二、核心能力一览

模块 能力 说明
轨迹存储 SQLite 原生落库 startTrack / stopTrack 会话管理,自动统计里程、点数、起止时间
批量写入 + 降噪 速度 / 精度阈值过滤脏点,可配置 batchSize
崩溃恢复 进程重启后自动恢复 active 状态的未完成轨迹
历史管理 分页查询、删轨迹、过期自动清理
轨迹导出 GPX / CSV UTC ISO8601 时间,写入沙盒 cache/track_exports/
电子围栏 圆形 + 多边形 消费 keepalive 出点做几何判定,不另起 LocationManager
事件 enter / leave / stay,可选 TTS 文案
系统 TTS 原生语音 Android TextToSpeech、iOS AVSpeechSynthesizer、鸿蒙 CoreSpeechKit

与 keepalive-location 的分工

能力 keepalive-location keepalive-track-tool
后台定位 / 权限
SQLite 轨迹
GPX/CSV 导出
围栏几何判定 ✅(消费点位)
TTS

重要:围栏要在息屏 / 后台触发,必须同时运行 keepalive-location 的 startLocation();本插件不再单独申请定位权限。

三、三端原生实现架构

flowchart TD
    A[Vue / uvue 业务层] -->|onLocationUpdate point| B[keepalive-location 后台定位 / 出点]
    A -->|appendTrackPoint / feedGeofenceLocation| C[keepalive-track-tool SQLite / 围栏 / TTS]
    B -->|GpsPoint| C
    C --> D[Android SQLiteOpenHelper + Haversine + 射线法 + TextToSpeech]
    C --> E[iOS sqlite3 + 几何算法 + AVSpeechSynthesizer]
    C --> F[鸿蒙 relationalStore + 几何算法 + CoreSpeechKit]
平台 存储 围栏 TTS
Android SQLiteOpenHelper Haversine + 多边形射线法 TextToSpeech
iOS sqlite3 同上 AVSpeechSynthesizer
鸿蒙 relationalStore 同上 CoreSpeechKit

数据 仅存本地:轨迹与围栏配置在 SQLite,导出文件在应用沙盒,无网络依赖。

四、安装

4.1 依赖关系

package.json 已声明依赖 keepalive-location,两个插件需 同时 放入 uni_modules/,并 制作包含两者的自定义调试基座 后真机运行。

4.3 版本要求

  • HBuilderX ^3.6.8
  • Android minSdk 26,iOS 12+
  • 支持 app-vue / app-nvue / app-uvue / 鸿蒙
  • Vue2 / Vue3 均可

五、30 行快速接入

5.1 引入 API

import {
  initTrack,
  startLocation,
  onLocationUpdate,
  requestPermissions
} from '@/uni_modules/keepalive-location'
import {
  initTrackTool,
  startTrack,
  stopTrack,
  appendTrackPoint,
  exportTrackGpx,
  addGeofence,
  onGeofenceEvent,
  speak
} from '@/uni_modules/keepalive-track-tool'

5.2 初始化 + 录轨迹 + 围栏

// 1. 初始化(可配置降噪与过期清理)
await initTrackTool({
  filter: { maxAccuracy: 60 },  // 精度 > 60m 的点丢弃
  expireDays: 90                 // 90 天前的已结束轨迹自动清理
})
await initTrack({ enableForegroundService: true })
await requestPermissions()

// 2. 添加圆形围栏 + 进入时 TTS
await addGeofence({
  name: '仓库',
  shape: {
    type: 'circle',
    latitude: 31.2,
    longitude: 121.5,
    radiusMeters: 200
  },
  ttsOnEnter: '已进入仓库区域'
})
onGeofenceEvent((ev) => {
  console.log(ev.event, ev.geofenceId, ev.geofenceName)
})

// 3. 开始轨迹 + 后台定位
const trackId = await startTrack({ name: '外勤巡检' })
await startLocation({ intervalMs: 3000 })

// 4. 一点两用:写轨迹 + 判围栏
onLocationUpdate((point) => {
  appendTrackPoint(point)
})

// 5. 结束并导出 GPX
const summary = await stopTrack()
const gpx = await exportTrackGpx(summary.trackId)
console.log('导出路径:', gpx.filePath)

5.3 仅围栏、不录轨迹

若业务只需要区域告警,无需 startTrack:

onLocationUpdate((point) => {
  feedGeofenceLocation(point)
})

5.4 多边形围栏示例

await addGeofence({
  name: '园区',
  shape: {
    type: 'polygon',
    points: [
      { latitude: 31.230, longitude: 121.470 },
      { latitude: 31.235, longitude: 121.480 },
      { latitude: 31.228, longitude: 121.485 }
    ]
  },
  stayTimeoutMs: 60000,      // 在围栏内满 60s 触发 stay
  notifyOnEnter: true,
  notifyOnLeave: true,
  ttsOnLeave: '已离开园区'
})

六、导出与上传对接

导出结果包含沙盒内绝对路径,可直接 uni.uploadFile 或对接 ebook-select-files 预览:

import { selectFiles } from '@/uni_modules/ebook-select-files'
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐