效果:
实现功能:
- 后台定位
- 地图长按添加marker得到当前位置经纬度坐标
- 创建地理围栏(以marker所在位置为中心,半径默认设置为100米)
- 通过BroadcastReceiver监听当前位置与围栏的位置关系
实现过程:
1. 后台定位
为了最大程度的增加定位进程的存活率,百度Android定位SDK提供后台持续定位的能力,可在应用退后台的状态下,持续记录位置信息。
首先初始化定位信息,主要是设置坐标类型等一些基本属性
// 定位初始化
private void initLocationSDK() {
mClient = new LocationClient(this);
LocationClientOption mOption = new LocationClientOption();
mOption.setScanSpan(5000);
mOption.setCoorType("bd09ll");//设置坐标类型
mOption.setIsNeedAddress(true);//设置是否需要地址信息,默认为无地址。
mOption.setOpenGps(true);
mClient.setLocOption(mOption);
mClient.registerLocationListener(myLocationListener);
}
初始化完成后开启后台定位功能,此时将会以5秒/次进行后台定位,及时你的应用处于后台,只要没有被清理依旧会执行定位过程,这样就可实现当应用处于后台仍然会执行的功能,比如在导航过程中进行当前坐标实时实施上传。
private void startBackgroundLocation() {
if (isEnableLocInForeground) {
//关闭后台定位(true:通知栏消失;false:通知栏可手动划除)
mClient.disableLocInForeground(true);
isEnableLocInForeground = false;
mForegroundBtn.setText("前台定位");
mClient.stop();
} else {
//开启后台定位
mClient.enableLocInForeground(1, notification);
isEnableLocInForeground = true;
mForegroundBtn.setText("后台定位");
mClient.start();
}
}
- 为地图设置长按监听事件,在地图上长按选点并将该点设置成为地理围栏的中心点
public void longClickAddMaker() {
mBaiduMap.clear(); //清除地图上的marker标志
mBaiduMap.setOnMapLongClickListener(new BaiduMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
if (latLng != null) {
if (isOnLongClickEnable) {
latitude = latLng.latitude;
longitude = latLng.longitude;
//Dest_BD09LL_End = new LatLng(latLng.latitude, latLng.longitude);
Toast.makeText(DeleveryInfo.this, "" + latitude + " fff " + longitude, Toast.LENGTH_SHORT).show();
mBitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon_openmap_mark); //用来构造InfoWindow
//响应点击的OnInfoWindowClickListener----为marker添加点击事件
InfoWindow.OnInfoWindowClickListener listener = new InfoWindow.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick() {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// popuInfoFlag = 1;
// dhPopupView();
// }
Toast.makeText(DeleveryInfo.this, "点击了添加的marker图标", Toast.LENGTH_LONG).show();
}
};
//构造InfoWindow
//point 描述的位置点 -100 InfoWindow相对于point在y轴的偏移量
InfoWindow mInfoWindow = new InfoWindow(mBitmap, new LatLng(latitude, longitude), -100, listener);
mBaiduMap.showInfoWindow(mInfoWindow);//使InfoWindow生效
isOnLongClickEnable = false; //禁止添加marker
}
}
}
});
}
- 创建地理围栏 (默认半径为100米)
private void initGeoFenceClient() {
fenceClient = new GeoFenceClient(getApplicationContext());// 1 创建地理围栏客户端
IntentFilter filter = new IntentFilter(); //注册
filter.addAction(GEOFENCE_BROADCAST_ACTION);
registerReceiver(mGeoFenceReceiver, filter);
/**
* 创建pendingIntent
*/
fenceClient.createPendingIntent(GEOFENCE_BROADCAST_ACTION);
fenceClient.isHighAccuracyLoc(true); // 在即将触发侦听行为时允许开启高精度定位模式(开启gps定位,gps定位结果优先)
fenceClient.setGeoFenceListener(DeleveryInfo.this);
/**
* 设置地理围栏的触发行为,默认为进入
*/
fenceClient.setActivateAction(GeoFenceClient.GEOFENCE_IN);
}
private void addRoundFence() {
// String customId = etCustomId.getText().toString();
// String radiusStr = etRadius.getText().toString();
if (null == new LatLng(latitude, longitude) || TextUtils.isEmpty("100")||latitude ==0.0) {
Toast.makeText(getApplicationContext(), "参数不全", Toast.LENGTH_SHORT)
.show();
return;
}
DPoint centerPoint = new DPoint(latitude, longitude);
//fenceRadius = Float.parseFloat(radiusStr);
fenceClient.addGeoFence(centerPoint, GeoFenceClient.BD09LL, 100, "1");//fenceRadius, "1");
}
- 创建BroadcastReceiver来监听当前坐标与围栏的关系
private BroadcastReceiver mGeoFenceReceiver = new Bro