地理围栏

地理围栏是通过划定一个区域范围,如果用户进出这片区域,会通过广播的形式通知上层。用户可以创建多个地理围栏,但是一旦不再使用对应围栏,应当尽快将围栏移除。目前腾讯定位SDK支持划定圆形区域和多边形。

注:自7.5.3版本起定位支持多边形地理围栏添加,地理围栏添加前需要开启连续定位才可生效。


1、创建地理围栏管理类

TencentGeofenceManager mTencentGeofenceManager = new TencentGeofenceManager(this);

this是Context,注意该类并没有实现单例,因此不要反复创建,建议创建一次后全局使用。


2、创建地理围栏

地理围栏分为以下两种:

1.创建圆形地理围栏

TencentGeofence.Builder builder = new TencentGeofence.Builder();
TencentGeofence circlefence = builder.setTag("CircleFence") // 设置 Tag,即围栏别名
      .setCircularRegion(lat, lng, 500) // 设置中心点和半径
      .setExpirationDuration(3 * 3600 * 1000) // 设置有效期
      .build();

2.创建多边形地理围栏

// 构造多边形围栏1
ArrayList<TencentGeofence.FencePoint> points = new ArrayList<>();18
// 传入边界点,不少于3个
points.add(new TencentGeofence.FencePoint(loc.getLatitude()-0.04,
loc.getLongitude()-0.04));
points.add(new TencentGeofence.FencePoint(loc.getLatitude()-0.04,
loc.getLongitude()+0.04));
points.add(new TencentGeofence.FencePoint(loc.getLatitude()+0.04,
loc.getLongitude()-0.04));
points.add(new TencentGeofence.FencePoint(loc.getLatitude()+0.04,
loc.getLongitude()+0.04));
TencentGeofence polygonFence = builder.setTag("PolygonFence")
      .setPolygonRegion(points)
      .setExpirationDuration(30 * 60 * 10000)
      .build();

3、添加地理围栏

// action: 可自定义
Intent receiver = new Intent(ACTION_TRIGGER_GEOFENCE);
receiver.setPackage("包名");
// extra: Tag 字段
receiver.putExtra("KEY_GEOFENCE_ID", geofence.getTag());

// 还可添加其他自定义的 extra 字段, 比如
receiver.putExtra("KEY_GEOFENCE_LAT", geofence.getLatitude());
receiver.putExtra("KEY_GEOFENCE_LNG", geofence.getLongitude());

// 随机产生的 requestCode, 避免冲突
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);
}

// 添加围栏
mTencentGeofenceManager.addFence(circlefence , pi);
//mTencentGeofenceManager.addFence(polygonFence , pi);

注意:在addFence的时候需要传入一个PendingIntent,这个PendingIntent将用于发送广播,通知该围栏的用户进出情况。PendingIntent的内容可以依照用户需求自行添加数据。但PendingIntent必须是用于向广播接收者发送数据的,在构造实例的时候需要使用getBroadcast方法生成。另外PendingIntent的类型建议使用FLAG_UPDATE_CURRENT,提高对象复用率,还可以替换数据。


4、创建广播接收者接收用户出入广播

public class DemoGeofenceEventReceiver extends BroadcastReceiver {

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

      // 进入围栏还是退出围栏
      boolean enter = intent.getBooleanExtra(
            LocationManager.KEY_PROXIMITY_ENTERING, true);
      //解析intent数据,数据内容由用户自己定义,这里只是示例
      // Tag
      String tag = intent.getStringExtra("KEY_GEOFENCE_ID");
      // 其他自定义的 extra 字段
      double lat = intent.getDoubleExtra("KEY_GEOFENCE_LAT", 0);
      double lng = intent.getDoubleExtra("KEY_GEOFENCE_LNG", 0);
   }

}

广播的注册方式取决于用户需求,动态或者静态注册都可以。注意通过解析Intent获取数据,其中进出状态通过LocationManager.KEY_PROXIMITY_ENTERING获得。


5、移除单个地理围栏

通过tag移除

mTencentGeofenceManager.removeFence(tag);

指定围栏对象移除

mTencentGeofenceManager.removeFence(fence);

6、销毁地理围栏

mTencentGeofenceManager.removeAllFences();
mTencentGeofenceManager.destroy();
本页内容