地理围栏 最后更新时间: 2022年04月24日
以下内容自定位 SDK V3.2.0 版本后支持。
第一步,创建地理围栏
地理围栏没有最大个数限制,您可以无限制的创建围栏。但请您根据业务需求合理的创建围栏,控制围栏个数可以有效的保证程序执行效率。定位 SDK 提供根据高德POI、行政区划,自定义圆形、多边形四种方式创建地理围栏。
注意:当用户将应用定位权限设置为“模糊定位”时,地理围栏功能无法正常工作。
1、创建地理围栏对象
这里还包括设置一些基本参数:
//实例化地理围栏客户端
GeoFenceClient mGeoFenceClient = new GeoFenceClient(getApplicationContext());
//设置希望侦测的围栏触发行为,默认只侦测用户进入围栏的行为
//public static final int GEOFENCE_IN 进入地理围栏
//public static final int GEOFENCE_OUT 退出地理围栏
//public static final int GEOFENCE_STAYED 停留在地理围栏内10分钟
mGeoFenceClient.setActivateAction(GEOFENCE_IN|GEOFENCE_OUT|GEOFENCE_STAYED);
2、创建高德POI地理围栏
提供两个创建高德POI围栏的接口,一个是根据关键字创建POI围栏,另一个是根据经纬度进行周边搜索创建POI围栏。
根据关键字创建围栏
通过以下方法执行POI关键字搜索并创建高德POI地理围栏。
mGeoFenceClient.addGeoFence(String keyword, String poiType, String city, int size,String customId);
参数说明
参数 | 说明 | 示例 |
---|---|---|
keyword | POI关键字 | 例如:首开广场 |
poiType | POI类型 | 例如:写字楼 |
city | POI所在的城市名称 | 例如:北京 |
customId | 与围栏关联的自有业务Id |
示例代码
mGeoFenceClient.addGeoFence("首开广场","写字楼","北京",1,"000FATE23(考勤打卡)");
根据周边POI创建围栏
通过以下方法执行POI周边搜索并创建高德POI地理围栏。
mGeoFenceClient.addGeoFence(String keyword, String poiType, DPoint point, float aroundRadius, int size,String customId);
参数说明
参数 | 说明 | 示例 |
---|---|---|
keyword | POI关键字 | 例如:首开广场 |
poiType | POI类型 | 例如:写字楼 |
point | 周边区域中心点的经纬度,以此中心点建立周边地理围栏 | 例如:北京 |
aroundRadius | 周边半径,0-50000米,默认3000米 | |
customId | 与围栏关联的自有业务Id |
示例代码
//创建一个中心点坐标
DPoint centerPoint = new DPoint();
//设置中心点纬度
centerPoint.setLatitude(39.123D);
//设置中心点经度
centerPoint.setLongitude(116.123D);
//执行添加围栏的操作
mGeoFenceClient.addGeoFence("肯德基","餐饮",centerPoint,1000F,10,"自有ID");
3、创建行政区划围栏
可根据行政区划关键字创建行政区划围栏。
根据关键字创建围栏
mGeoFenceClient.addGeoFence(String keyword, String customId);
参数说明
参数 | 说明 | 示例 |
---|---|---|
keyword | 行政区划关键字 | 例如:朝阳区 |
customId | 与围栏关联的自有业务Id |
示例代码
mGeoFenceClient.addGeoFence("海淀区","00FDTW103(在北京海淀的化妆品促销活动)");
4、创建自定义围栏
自定义围栏包含圆形围栏、多边形围栏两种,自定义围栏一次接口调用只可以创建一个围栏,创建多个自定义围栏需要多次调用创建接口。
圆形围栏
圆形围栏需要提供中心点,以及半径。
mGeoFenceClient.addGeoFence(Point point,float radius, String customId);
参数说明
参数 | 说明 | 示例 |
---|---|---|
point | 围栏中心点 | |
radius | 要创建的围栏半径 ,半径无限制,单位米 | |
customId | 与围栏关联的自有业务Id |
示例代码
/创建一个中心点坐标
DPoint centerPoint = new DPoint();
//设置中心点纬度
centerPoint.setLatitude(39.123D);
//设置中心点经度
centerPoint.setLongitude(116.123D);
mGeoFenceClient.addGeoFence (centerPoint,500F,"自有业务Id");
多边形围栏
mGeoFenceClient.addGeoFence(List<DPoint> points, String customId);
参数说明
参数 | 说明 | 示例 |
---|---|---|
points | 多边形的边界坐标点,最少传3个 | |
customId | 与围栏关联的自有业务Id |
示例代码
List<DPoint> points = new ArrayList<DPoint>();
points.add(new DPoint(39.992702, 116.470470));
points.add(new DPoint(39.994387, 116.472498));
points.add(new DPoint(39.994478, 116.474161));
points.add(new DPoint(39.993163, 116.474504));
points.add(new DPoint(39.991363, 116.472605));
mGeoFenceClient.addGeoFence(points,"自有业务ID");
第二步,开始定位
当围栏创建完毕,且围栏创建成功时会启动定位,这部分无需您来设置,SDK内部执行。
启动的定位机制:通过“远离围栏时的超低频定位策略”来降低电量消耗,“离近围栏会逐渐提高定位频率”,保证有足够的定位精度来完成围栏位置检测。
需要注意,如果您希望程序在后台持续检测围栏触发行为,您务必要在应用本地服务中启动 GeoFenceClient,且确保这个本地服务一直存活。
下面介绍如何知道创建围栏是成功还是失败。
第三步,接收围栏创建后的回调
围栏创建完毕的信息会通过 GeoFenceListener 进行回调。可以在回调中知道创建围栏成功与否,以及查看所创建围栏的具体内容。
//创建回调监听
GeoFenceListener fenceListenter = new GeoFenceListener() {
@Override
public void onGeoFenceCreateFinished(List<GeoFence> geoFenceList,
int errorCode) {
if(errorCode == GeoFence.ADDGEOFENCE_SUCCESS){//判断围栏是否创建成功
tvReult.setText("添加围栏成功!!");
//geoFenceList是已经添加的围栏列表,可据此查看创建的围栏
} else {
tvReult.setText("添加围栏失败!!");
}
}
};
mGeoFenceClient.setGeoFenceListener(fenceListenter);//设置回调监听
第四步,接收围栏触发行为广播
用户与围栏位置发生变化的行为称为围栏触发行为,围栏触发行为也是用户进入围栏、退出围栏、在围栏内停留这三种行为的统称,行为的触发是通过Android 的广播进行发送的。
围栏触发行为的广播内容是可选性的,在第一步“创建地理围栏对象”中讲到可以应用 setActiveAction(int[] actions) 方法设置希望侦测到的围栏触发行为。
当定位启动后会马上得到符合希望的所有围栏的状态检测广播,这些广播会告诉上层逻辑每个围栏和当前用户位置的初始状态究竟是IN(定位点在围栏里)还是OUT(定位点在围栏外),这种广播不是围栏触发行为广播,是每个围栏的初始状态广播,不会经常收到,在有新的围栏被创建,或者希望侦测的Action改变时会收到。接下来的每次广播都是围栏触发行为广播(当然,触发前提是位置和围栏的关系发生了改变)。
1、创建并设置PendingIntent
//定义接收广播的action字符串
public static final String GEOFENCE_BROADCAST_ACTION = "com.location.apis.geofencedemo.broadcast";
//创建并设置PendingIntent
mGeoFenceClient.createPendingIntent(GEOFENCE_BROADCAST_ACTION);
2、创建广播监听
private BroadcastReceiver mGeoFenceReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(GEOFENCE_BROADCAST_ACTION)) {
//解析广播内容
}
}
};
3、注册广播
IntentFilter filter = new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(GEOFENCE_BROADCAST_ACTION);
registerReceiver(mGeoFenceReceiver, filter);
4、解析广播内容
当上一步完成之后,可以在第2步创建的监听器中在 onReceive 方法中对广播内容进行解析。广播内容是通过 Bundle 进行传递的。
//获取Bundle
Bundle bundle = intent.getExtras();
//获取围栏行为:
int status = bundle.getInt(GeoFence.BUNDLE_KEY_FENCESTATUS);
//获取自定义的围栏标识:
String customId = bundle.getString(GeoFence.BUNDLE_KEY_CUSTOMID);
//获取围栏ID:
String fenceId = bundle.getString(GeoFence.BUNDLE_KEY_FENCEID);
//获取当前有触发的围栏对象:
GeoFence fence = bundle.getParcelable(GeoFence.BUNDLE_KEY_FENCE);
最后,清除所有围栏
当不再需要使用围栏时,可以调用以下代码对已经设定的围栏进行清除操作。
//会清除所有围栏
mGeoFenceClient.removeGeoFence();