地理围栏 API
Tracelet 提供了一个强大的、离线优先的地理围栏引擎。与限制为 20-100 个地理围栏并且需要操作系统唤醒您的应用程序的标准操作系统地理围栏不同,Tracelet 在 Rust 引擎内部评估地理围栏。这使得无限地理围栏具有零额外电池消耗。
1.圆形与多边形地理围栏
Tracelet 支持标准圆形地理围栏和复杂多边形地理围栏。
圆形地理围栏
圆形地理围栏由中心坐标和半径(以米为单位)定义。
final circular = tl.Geofence(
identifier: 'headquarters',
latitude: 37.7749,
longitude: -122.4194,
radius: 200, // 200 meters
notifyOnEntry: true,
notifyOnExit: true,
notifyOnDwell: true, // Triggers if they stay inside
loiteringDelay: 300, // Trigger dwell after 5 minutes
);多边形地理围栏
多边形地理围栏由勾勒出复杂形状(如公园或建筑物)的坐标数组定义。
final polygon = tl.Geofence.polygon(
identifier: 'golden_gate_park',
vertices: [
tl.Coordinate(latitude: 37.773972, longitude: -122.431297),
tl.Coordinate(latitude: 37.769996, longitude: -122.511055),
tl.Coordinate(latitude: 37.764516, longitude: -122.508566),
],
notifyOnEntry: true,
notifyOnExit: true,
);2. 添加和删除地理围栏
Tracelet 将所有地理围栏存储在本地 SQLite 数据库中。这意味着它们在应用程序重新启动后保持不变。您无需在每次应用程序启动时重新添加它们。
添加地理围栏
您可以添加单个地理围栏或一组地理围栏。
// Add a single geofence
await tl.Tracelet.addGeofence(circular);
// Add multiple geofences efficiently
await tl.Tracelet.addGeofences([circular, polygon]);删除地理围栏
通过其唯一标识符删除它们,或清除整个数据库。
// Remove a specific geofence
await tl.Tracelet.removeGeofence('headquarters');
// Remove all geofences entirely
await tl.Tracelet.removeGeofences();3. 列出活动地理围栏
您可以随时查询SQLite数据库,查看当前正在监控哪些地理围栏。
final geofences = await tl.Tracelet.getGeofences();
for (final fence in geofences) {
print('Monitoring: \${fence.identifier}');
}4. 监听地理围栏事件
当用户跨越地理围栏边界时,Tracelet 会触发 onGeofence 事件。由于评估在位置更新期间发生在 Rust 核心中,因此即使应用程序被终止,这些事件也会触发(触发无头回调)。
tl.Tracelet.onGeofence((evt) {
if (evt.action == tl.GeofenceEventAction.ENTER) {
print('User entered: \${evt.identifier}');
} else if (evt.action == tl.GeofenceEventAction.EXIT) {
print('User exited: \${evt.identifier}');
} else if (evt.action == tl.GeofenceEventAction.DWELL) {
print('User is dwelling inside: \${evt.identifier}');
}
});5. Android:前台服务和 Google Play 政策
Google Play 政策变更 — 2026 年 10 月 28 日生效。 地理围栏不适用
不再是前台服务位置的允许用例。使用的应用程序
仅用于地理围栏的前台服务必须删除
FOREGROUND_SERVICE_LOCATION(和 FOREGROUND_SERVICE,如果未使用的话)
合并清单中的权限。
Tracelet 的 标准 地理围栏模式使用本机 Android 地理围栏 API
(GeofencingClient),它会触发 ENTER/EXIT — 并将您的应用程序重新启动到您的
无头任务 - 当应用程序暂停或终止时,没有
前台服务。在标准模式下调用 startGeofences() 不会**启动
前台服务(从 3.5.x 开始),因此默认情况下是合规的。
激进的 OEM(三星/小米/华为/OnePlus/Oppo/Vivo): 截至 3.6.1,
每台设备都会遵循显式的 geofenceModeHighAccuracy: false。前
3.6.1 这些 OEM 默默地强制采用高精度模式 — 随之而来的是
前台服务及其持久通知 - 即使您设置 false,
这打破了上面兼容的标准模式路径。如果您的目标是这些设备,
使用 3.6.1 或更高版本。在激进的 OEM 上,SDK 现在会记录可靠性警告
(本地地理围栏传输可能会延迟)而不是覆盖您的配置。
如果您仅将 Tracelet 用于地理围栏
-
不启用前台服务:
await tl.Tracelet.ready(const tl.Config( android: tl.AndroidConfig( foregroundService: tl.ForegroundServiceConfig(enabled: false), ), geofence: tl.GeofenceConfig(geofenceModeHighAccuracy: false), )); await tl.Tracelet.startGeofences(); -
Tracelet SDK声明
FOREGROUND_SERVICE/FOREGROUND_SERVICE_LOCATION因其连续跟踪用例。如果你的应用程序从不连续 跟踪,使用清单合并将它们从合并清单中剥离 应用程序的android/app/src/main/AndroidManifest.xml中的remove规则:<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" tools:node="remove" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove" /> </manifest>
如果您使用连续跟踪和地理围栏
您可以保留 FOREGROUND_SERVICE_LOCATION 用于跟踪用例(例如
导航/车队跟踪),但前台服务不得用于
地理围栏。 Tracelet 已经处理了这个问题:FGS 运行以进行连续跟踪
(start()),并切换到仅地理围栏模式(标准中的 startGeofences())
模式)拆除 FGS。
高精度地理围栏模式 (geofenceModeHighAccuracy: true) 使用
连续 GPS 进行严格的应用内边界检测,确实运行
前台服务。这是连续定位——而不是政策中的“地理围栏”
sense - 因此仅当您的应用程序有单独的允许位置使用时才启用它
案件。对于大多数应用程序来说,标准模式是合规且省电的选择。