地理围栏

地理围栏通过划定区域范围,当设备进出该区域时,以广播形式通知应用。支持圆形区域多边形区域行政区划区域三种围栏类型。

自定位 SDK v7.5.3 起支持多边形地理围栏。

自定位 SDK v7.6.1.8 起支持行政区划地理围栏。

前置条件:添加地理围栏前,必须先开启连续定位,围栏才能生效。



开发步骤

1. 创建地理围栏管理器

TencentGeofenceManager 非单例,建议全局创建一次,避免反复实例化。

TencentGeofenceManager mGeofenceManager = new TencentGeofenceManager(this);

2. 创建地理围栏

圆形围栏

通过 TencentGeofence.Builder 设置中心点经纬度、半径和有效期:

TencentGeofence circleFence = new TencentGeofence.Builder()
        .setTag("CircleFence")                    // 围栏别名
        .setCircularRegion(lat, lng, 500)          // 中心点纬度、经度、半径(米)
        .setExpirationDuration(3 * 3600 * 1000)    // 有效期(毫秒)
        .build();

多边形围栏

构造 FencePoint 列表,边界点不少于 3 个

ArrayList<TencentGeofence.FencePoint> points = new ArrayList<>();
points.add(new TencentGeofence.FencePoint(lat1, lng1));
points.add(new TencentGeofence.FencePoint(lat2, lng2));
points.add(new TencentGeofence.FencePoint(lat3, lng3));
points.add(new TencentGeofence.FencePoint(lat4, lng4));

TencentGeofence polygonFence = new TencentGeofence.Builder()
        .setTag("PolygonFence")
        .setPolygonRegion(points)
        .setExpirationDuration(30 * 60 * 1000)
        .build();

行政区划围栏

通过 setDistrictRegion 设置行政区划关键字,支持行政区划名称或 adcode:

TencentGeofence districtFence = new TencentGeofence.Builder()
        .setTag("DistrictFence")
        .setDistrictRegion("北京市")   // 支持名称(如"北京市")或 adcode(如"110000")
        .setExpirationDuration(24 * 3600 * 1000)
        .build();

行政区划围栏数据通过网络异步获取,addFence 调用后不会立即生效。围栏添加结果(成功或失败)会通过广播回调通知,详见下方"创建广播接收器"步骤。

3. 添加地理围栏

通过 PendingIntent 绑定广播,接收围栏触发通知。建议使用 FLAG_UPDATE_CURRENT 提高对象复用率。

Android 12(API 31)及以上需额外添加 FLAG_MUTABLE 标志。

Intent receiver = new Intent(ACTION_TRIGGER_GEOFENCE);
receiver.setPackage(getPackageName());
receiver.putExtra("KEY_GEOFENCE_ID", fence.getTag());
receiver.putExtra("KEY_GEOFENCE_LAT", fence.getLatitude());
receiver.putExtra("KEY_GEOFENCE_LNG", fence.getLongitude());

int requestCode = (int) (Math.random() * 1E7);
PendingIntent pi;
if (Build.VERSION.SDK_INT >= 31) {
    pi = PendingIntent.getBroadcast(context, requestCode,
            receiver, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
} else {
    pi = PendingIntent.getBroadcast(context, requestCode,
            receiver, PendingIntent.FLAG_UPDATE_CURRENT);
}

mGeofenceManager.addFence(fence, pi);

4. 创建广播接收器

通过 LocationManager.KEY_PROXIMITY_ENTERING 判断进入或退出围栏。行政区划围栏还会通过 TencentGeofence.ERROR_CODE 回调添加结果,支持动态或静态注册:

public class GeofenceReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null || !ACTION_TRIGGER_GEOFENCE.equals(intent.getAction())) {
            return;
        }

        if (intent.hasExtra(TencentGeofence.ERROR_CODE)) {
            // 行政区划围栏添加结果回调
            int errorCode = intent.getIntExtra(TencentGeofence.ERROR_CODE, TencentGeofence.ERROR_OK);
            String errorMsg = intent.getStringExtra(TencentGeofence.ERROR_MESSAGE);
            String tag = intent.getStringExtra("KEY_GEOFENCE_ID");
            if (errorCode != TencentGeofence.ERROR_OK) {
                // 添加失败,errorCode 含义见下方错误码说明
            } else {
                // 添加成功,围栏开始生效
            }
        } else if (intent.hasExtra(LocationManager.KEY_PROXIMITY_ENTERING)) {
            // 围栏进入/离开事件
            boolean enter = intent.getBooleanExtra(LocationManager.KEY_PROXIMITY_ENTERING, true);
            String tag = intent.getStringExtra("KEY_GEOFENCE_ID");
            double lat = intent.getDoubleExtra("KEY_GEOFENCE_LAT", 0);
            double lng = intent.getDoubleExtra("KEY_GEOFENCE_LNG", 0);
        }
    }
}

行政区划围栏错误码说明:

错误码常量 说明
ERROR_OK 0 成功
ERROR_KEYWORD_EMPTY -1 关键字为空
ERROR_REQUEST_FAILED -2 网络请求失败
ERROR_POLYGON_INSUFFICIENT -3 返回的边界点不足
ERROR_POLYGON_INVALID -4 边界点无效
ERROR_KEYWORD_INVALID -5 关键字无效(未找到对应行政区划)

5. 移除地理围栏

// 通过 Tag 移除
mGeofenceManager.removeFence(tag);

// 通过围栏对象移除
mGeofenceManager.removeFence(fence);

6. 销毁管理器

不再使用围栏时,移除全部围栏并销毁管理器:

mGeofenceManager.removeAllFences();
mGeofenceManager.destroy();

注意事项

  • 添加围栏前必须先开启连续定位,否则围栏不会生效。
  • 可创建多个围栏,不再使用时应尽快移除以释放资源。
  • TencentGeofenceManager 非单例,建议全局创建一次复用。
  • Android 12+ 创建 PendingIntent 时需添加 FLAG_MUTABLE
  • 行政区划围栏数据通过网络异步获取addFence 后不会立即生效,需通过广播中的 TencentGeofence.ERROR_CODE 确认添加结果。

相关链接

本页内容