地理围栏

地理围栏用于在用户进入或离开某个特定区域时收到回调(例如靠近门店推送、到达目的地提醒、商圈识别等场景)。

本文档介绍 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 事件流通知(事件中的 geofenceIdaddGeofence 传入的原始 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 / dwelldwell 的触发阈值由 dwellDuration 控制,默认 600 秒,最小 60 秒

  • HarmonyOS:支持 enter / exit / dwelldwell 的触发阈值由鸿蒙原生 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 端使用方式

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 端使用方式

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 端使用方式

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
圆形围栏 支持 支持 支持
多边形围栏 支持 支持 不支持,addGeofencegeofenceInvalidRegion
行政区划围栏 支持 支持 不支持,addGeofencegeofenceInvalidRegion
enter / exit 事件 支持 支持 支持
dwell 事件 不支持自定义,自动忽略 支持,阈值通过 dwellDuration 配置 支持,阈值由原生 SDK 内部策略控制
expiration 围栏有效期 支持 不支持,传入会被忽略 支持
onGeofenceCreated 事件 支持(仅行政区围栏异步创建完成时触发) 支持(仅行政区围栏异步创建完成时触发) 订阅成功但不会收到事件
startMonitoring / stopMonitoring / pauseMonitoring / resumeMonitoring / isMonitoring 不支持,调用抛 unsupportedOnThisPlatform 支持 不支持,调用抛 unsupportedOnThisPlatform
getAllGeofences 支持 支持 支持
isCoordinateInside / geofenceRegionsContainingCoordinate 不支持,调用抛 unsupportedOnThisPlatform 支持 不支持,调用抛 unsupportedOnThisPlatform

iOS 围栏专属配置

下列接口仅在 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 不存在

完整错误码列表与处理建议见 错误码

本页内容