地理围栏是通过划定一个区域范围,如果用户进出这片区域,会通过广播的形式通知上层。用户可以创建多个地理围栏,但是一旦不再使用对应围栏,应当尽快将围栏移除。目前腾讯定位SDK支持划定圆形区域和多边形。
注:自7.5.3版本起定位支持多边形地理围栏添加,地理围栏添加前需要开启连续定位才可生效。
TencentGeofenceManager mTencentGeofenceManager = new TencentGeofenceManager(this);
this是Context,注意该类并没有实现单例,因此不要反复创建,建议创建一次后全局使用。
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();
// 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,提高对象复用率,还可以替换数据。
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获得。
通过tag移除
mTencentGeofenceManager.removeFence(tag);
指定围栏对象移除
mTencentGeofenceManager.removeFence(fence);
mTencentGeofenceManager.removeAllFences();
mTencentGeofenceManager.destroy();
有帮助
没帮助