地理围栏用于在用户进入或离开某个特定区域时收到回调(例如靠近门店推送、到达目的地提醒、商圈识别等场景)。
本文档介绍 Flutter 插件中地理围栏的接口、围栏形态、事件类型与典型使用方式。
class TencentGeofenceManager {
// 围栏管理
Future<void> addGeofence(TencentGeofence fence);
Future<void> removeGeofence(String id);
Future<void> removeAllGeofences();
Future<List<TencentGeofence>> getAllGeofences();
// 事件流
Stream<TencentGeofenceEvent> get onEvent;
Stream<TencentGeofenceCreatedEvent> get onGeofenceCreated;
Stream<TencentLocationError> get onError;
// 监控生命周期
Future<void> startMonitoring();
Future<void> stopMonitoring();
Future<void> pauseMonitoring();
Future<void> resumeMonitoring();
Future<bool> isMonitoring();
// 状态查询
Future<bool> isCoordinateInside(String id, TencentLocationCoordinate coordinate);
Future<List<TencentGeofence>> geofenceRegionsContainingCoordinate(
TencentLocationCoordinate coordinate);
}
TencentGeofence 提供三种工厂方法对应三种围栏形态:
提示:Android 端建议显式设置 expiration(围栏有效期)。SDK 对未设置有效期的围栏按 duration=0 处理,会立即判定为过期并清理,导致 getAllGeofences 查不到刚添加的围栏。
final circle = TencentGeofence.circle(
id: 'office',
center: const TencentLocationCoordinate(latitude: 39.984120, longitude: 116.307484),
radius: 200, // 米
monitorTransitions: const {
GeofenceTransition.enter,
GeofenceTransition.exit,
},
);
平台支持:Android / iOS / HarmonyOS 均支持。
final polygon = TencentGeofence.polygon(
id: 'campus',
vertices: const [
TencentLocationCoordinate(latitude: 39.984000, longitude: 116.307000),
TencentLocationCoordinate(latitude: 39.985000, longitude: 116.307500),
TencentLocationCoordinate(latitude: 39.985000, longitude: 116.308500),
TencentLocationCoordinate(latitude: 39.984000, longitude: 116.308500),
],
);
要求顶点数量不少于 3 个且不重复。
平台支持:
Android:支持
iOS:支持
HarmonyOS:不支持,调用 addGeofence 会抛出 TencentLocationError,错误码为 geofenceInvalidRegion
final district = TencentGeofence.district(
id: 'haidian',
keyword: '110108', // adcode 或行政区中文名(如 '海淀区')
);
keyword 可填行政区划编码(adcode)或中文名称。
行政区划围栏在 Android / iOS 上是异步创建的:addGeofence 的 Future 成功仅表示围栏已提交给 SDK,并非已生效。创建成功后通过 onGeofenceCreated 事件流通知(事件中的 geofenceId 为 addGeofence 传入的原始 id;Android 端 getAllGeofences 返回的 id 可能带 adcode 后缀,如 district-1_110108)。创建失败(例如行政区划关键字找不到)时通过 onError 事件流通知。circle / polygon 为同步添加,不触发 onGeofenceCreated。
平台支持:
Android:支持
iOS:支持
HarmonyOS:不支持,调用 addGeofence 会抛出 TencentLocationError,错误码为 geofenceInvalidRegion
TencentGeofence.monitorTransitions 可指定要监听哪些事件,支持以下三种:
| 事件 | 说明 |
|---|---|
enter |
进入围栏 |
exit |
离开围栏 |
dwell |
在围栏内停留达到一定时长 |
各事件的平台支持:
Android:支持 enter / exit;不支持自定义 dwell,传入 dwell 时该事件被忽略,围栏仍然按 enter + exit 监听
iOS:支持 enter / exit / dwell,dwell 的触发阈值由 dwellDuration 控制,默认 600 秒,最小 60 秒
HarmonyOS:支持 enter / exit / dwell;dwell 的触发阈值由鸿蒙原生 SDK 内部策略控制,不接受自定义 dwellDuration
final geofenceManager = TencentGeofenceManager();
geofenceManager.onEvent.listen((event) {
print('围栏事件:id=${event.geofenceId}, '
'transition=${event.transition}, '
'stayed=${event.stayedDuration}');
});
geofenceManager.onError.listen((error) {
print('围栏错误:${error.code} ${error.message}');
});
// 仅行政区划围栏异步创建完成时触发(circle / polygon 不触发)
geofenceManager.onGeofenceCreated.listen((created) {
print('行政区围栏创建完成:id=${created.geofenceId}, '
'userInfo=${created.userInfo}');
});
TencentGeofenceCreatedEvent 字段说明:
geofenceId:已创建围栏的 id,与 addGeofence 传入的原始 id 一致
userInfo:创建时通过 userInfo 携带的自定义附加信息,平台拿不到时为 null
TencentGeofenceEvent 字段说明:
geofenceId:触发事件的围栏 ID
transition:事件类型(enter / exit / dwell)
location:触发事件时的位置(部分平台可能为空)
stayedDuration:仅 dwell 事件有值,表示已停留时长
userInfo:创建围栏时通过 userInfo 携带的自定义附加信息
Android 端的围栏在调用 addGeofence 后即开始生效,无需额外调用 startMonitoring:
final manager = TencentGeofenceManager();
manager.onEvent.listen((event) {
print('围栏事件:${event.geofenceId} -> ${event.transition}');
});
await manager.addGeofence(
TencentGeofence.circle(
id: 'office',
center: const TencentLocationCoordinate(
latitude: 39.984120,
longitude: 116.307484,
),
radius: 200,
),
);
// 不再需要时移除:
// await manager.removeGeofence('office');
// await manager.dispose();
iOS 端在 addGeofence 之后还需要显式调用 startMonitoring 来开始监控;pause / resume / stop 可控制监控生命周期:
final manager = TencentGeofenceManager();
manager.onEvent.listen((event) {
print('围栏事件:${event.geofenceId} -> ${event.transition}');
});
await manager.addGeofence(
TencentGeofence.circle(
id: 'office',
center: const TencentLocationCoordinate(
latitude: 39.984120,
longitude: 116.307484,
),
radius: 200,
),
);
await manager.startMonitoring();
// 暂停 / 恢复:
// await manager.pauseMonitoring();
// await manager.resumeMonitoring();
// 不再需要时停止并释放:
// await manager.stopMonitoring();
// await manager.dispose();
HarmonyOS 端与 Android 类似,addGeofence 后即开始生效,无需调用 startMonitoring;仅支持圆形围栏:
final manager = TencentGeofenceManager();
manager.onEvent.listen((event) {
print('围栏事件:${event.geofenceId} -> ${event.transition}');
});
await manager.addGeofence(
TencentGeofence.circle(
id: 'office',
center: const TencentLocationCoordinate(
latitude: 39.984120,
longitude: 116.307484,
),
radius: 200,
),
);
// 不再需要时移除:
// await manager.removeGeofence('office');
// await manager.dispose();
| 接口 / 字段 | Android | iOS | HarmonyOS |
|---|---|---|---|
| 圆形围栏 | 支持 | 支持 | 支持 |
| 多边形围栏 | 支持 | 支持 | 不支持,addGeofence 抛 geofenceInvalidRegion |
| 行政区划围栏 | 支持 | 支持 | 不支持,addGeofence 抛 geofenceInvalidRegion |
enter / exit 事件 |
支持 | 支持 | 支持 |
dwell 事件 |
不支持自定义,自动忽略 | 支持,阈值通过 dwellDuration 配置 |
支持,阈值由原生 SDK 内部策略控制 |
expiration 围栏有效期 |
支持 | 不支持,传入会被忽略 | 支持 |
onGeofenceCreated 事件 |
支持(仅行政区围栏异步创建完成时触发) | 支持(仅行政区围栏异步创建完成时触发) | 订阅成功但不会收到事件 |
startMonitoring / stopMonitoring / pauseMonitoring / resumeMonitoring / isMonitoring |
不支持,调用抛 unsupportedOnThisPlatform |
支持 | 不支持,调用抛 unsupportedOnThisPlatform |
getAllGeofences |
支持 | 支持 | 支持 |
isCoordinateInside / geofenceRegionsContainingCoordinate |
不支持,调用抛 unsupportedOnThisPlatform |
支持 | 不支持,调用抛 unsupportedOnThisPlatform |
下列接口仅在 iOS 上有效,可用于在围栏检测中平衡定位精度与功耗:
await geofenceManager.setIosAllowsBackgroundLocationUpdates(true);
await geofenceManager.setIosAdaptiveDistanceFilterEnabled(true);
await geofenceManager.setIosDistanceFilter(50);
await geofenceManager.setIosDesiredAccuracy(IosDesiredAccuracy.best);
await geofenceManager.setIosDetectionInterval(const Duration(seconds: 5));
各接口在 Android 上调用会抛出 TencentLocationError,错误码为 unsupportedOnThisPlatform。
| 错误码 | 含义 |
|---|---|
geofenceInvalidRegion |
围栏区域非法(如多边形点数不足、经纬度超范围等)。Android 上行政区划关键字找不到时 SDK 复用该错误码,可通过 message(如 no valid district found)区分 |
geofenceDistrictNotFound |
行政区划关键字未找到(Android 上也可能收到上方的 geofenceInvalidRegion,以 message 为准) |
geofenceDuplicateId |
围栏 ID 与已添加的围栏重复 |
geofenceNetworkFailed |
围栏网络请求失败 |
geofenceLimitExceeded |
单实例围栏数量超限 |
geofenceIdNotFound |
待移除 / 查询的围栏 ID 不存在 |
完整错误码列表与处理建议见 错误码。
有帮助
没帮助