地理围栏是个服务,所以在manifest中要添加
先说下大致思路:
点击button,显示出popuwindow,在这个popuwindow中有创建围栏的按钮,点击创建围栏button前,先点击地图,获取到经纬度,以点击的点为圆心,画圆形围栏,然后再把实时定位开启,点击查看被监控者状态button,根据实时定位的经纬度,来判断被监控者是在围栏内还是在围栏外
cpw = new CustomPopWindow(MainActivity.this);case R.id.btn_geofence: cpw.showPopupWindow(btn_geofence);
/** * 自定义的popuwindow * @author Administrator */public class CustomPopWindow extends PopupWindow implements OnClickListener { private static final int CHECKSTATUS = 1 ; private Context context; private View view; private MyApplication mApp; private GeoFence geoFence; private LatLng poiLatLng; public static Button custom_popu_btn_server_status; private Button custom_popu_btn_customer_status; private Timer mTimer; private TimerTask mTimerTask; /** * 用于记录服务端状态的按钮是否开启 */ public static boolean flag = false; /** * 上一个服务端地理围栏的坐标 */ private LatLng last; private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { if (null != msg) { switch (msg.what) { case CHECKSTATUS: geoFence.monitoredStatus(); break; default: break; } } }; }; public CustomPopWindow(Context context){ this.context = context; view = LayoutInflater.from(context).inflate(R.layout.custom_view_popu,null); setContentView(view); mApp = (MyApplication) context.getApplicationContext(); init(); initView(); geoFence = new GeoFence(context,mApp); } private void init() { // 设置SelectPicPopupWindow弹出窗体的宽 this.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT); // 设置SelectPicPopupWindow弹出窗体的高, 宽和高必须设置,否则不显示popuwindow this.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); // 设置popuwindow所在的窗体可以点击 this.setFocusable(false); // 刷新状态 this.update(); // 点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ,设置其他控件变化等操作 this.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); this.setOutsideTouchable(false); // 设置SelectPicPopupWindow弹出窗体动画效果 this.setAnimationStyle(R.style.AnimTools); } private void initView() { Button custom_popu_btn_server = (Button) view.findViewById(R.id.custom_popu_btn_server); Button custom_popu_btn_server_delete = (Button) view.findViewById(R.id.custom_popu_btn_server_delete); custom_popu_btn_server_status = (Button) view.findViewById(R.id.custom_popu_btn_server_status); Button custom_popu_btn_customer = (Button) view.findViewById(R.id.custom_popu_btn_customer); custom_popu_btn_customer_status = (Button) view.findViewById(R.id.custom_popu_btn_customer_status); custom_popu_btn_server.setOnClickListener(this); custom_popu_btn_server_delete.setOnClickListener(this); custom_popu_btn_server_status.setOnClickListener(this); custom_popu_btn_customer.setOnClickListener(this); custom_popu_btn_customer_status.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.custom_popu_btn_server: //创建服务端的button //先获取到点击地图的poi时候的LatLng 然后传递到创建服务端围栏中 poiLatLng = MainActivity.poiLatLng; if (GeoFence.serverFenceId>0) { //删除上一个地理围栏 geoFence.deleteServerFence(GeoFence.serverFenceId); } if (null == poiLatLng || "".equals(poiLatLng) || poiLatLng == last) { MyToastUtils.show(context, "请点击地图,选取围栏中心点"); return; } geoFence.creatServerFence(poiLatLng); //为了 防止同一个坐标 一直创建围栏 last = poiLatLng; custom_popu_btn_server_status.setVisibility(View.VISIBLE); //这时候如果报警音乐响着, 但是又创建了个新的围栏, 就把报警关掉 closeMusic(); break; case R.id.custom_popu_btn_server_status: //查看服务端围栏的状态 if (MainActivity.isLoca) { if (flag) { flag = false; cancelTimer(); custom_popu_btn_server_status.setText("查看服务端状态"); //如果报警音乐开着, 就关闭 closeMusic(); }else{ flag = true; startTimer(); custom_popu_btn_server_status.setText("已开启查询端状态按钮"); } }else{ MyToastUtils.show(context, "请先开启实时定位"); } break; case R.id.custom_popu_btn_server_delete: //删除围栏 break; case R.id.custom_popu_btn_customer: //客户端(本地)围栏的按钮 geoFence.createLocalCircularFence(); custom_popu_btn_customer_status.setVisibility(View.VISIBLE); break; case R.id.custom_popu_btn_customer_status: Log.i("哈哈", "客户端状态查询点击"); break; default: break; } } /** * 如果报警音乐开着 ,关闭音乐 */ private void closeMusic() { if (null !=GeoFence.mPlayer) { if (GeoFence.mPlayer.isPlaying()) { GeoFence.mPlayer.stop(); try { GeoFence.mPlayer.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } } private void startTimer(){ if (null == mTimer) { mTimer = new Timer(); } if (null != mTimerTask) { mTimerTask = null; } mTimerTask = new TimerTask() { @Override public void run() { mHandler.obtainMessage(CHECKSTATUS).sendToTarget(); } }; mTimer.schedule(mTimerTask, 100,30*1000); } public void cancelTimer(){ if (null != mTimer) { mTimer.cancel(); mTimer = null; } if (null != mTimerTask) { mTimerTask.cancel(); mTimerTask = null; } } /** * 显示popu * @param parent */ public void showPopupWindow(View parent) { if (!this.isShowing()) { // 以下拉方式显示popupwindow this.showAsDropDown(parent, parent.getLayoutParams().width , parent.getLayoutParams().height);// this.showAsDropDown(parent); } else { this.dismiss(); if (!flag) { custom_popu_btn_server_status.setVisibility(View.GONE); } } } }
public GeoFence(Context mContext,MyApplication mApp){ this.mContext = mContext; this.mApp = mApp; initGeoFence(); }
private void initGeoFence() { geoListener = new OnGeoFenceListener(){ @Override public void onRequestFailedCallback(String message) { // TODO Auto-generated method stub } /** * 创建服务端圆形围栏的回调 */ @Override public void onCreateCircularFenceCallback(String message) { super.onCreateCircularFenceCallback(message); Log.i(TAG, "创建服务端圆形围栏回调信息:"+message); try { JSONObject object = new JSONObject(message); if (null != object) { if (0 ==object.getInt("status")) { serverFenceId = object.getInt("fence_id"); mHandler.obtainMessage(SERVERID, serverFenceId).sendToTarget(); overlayOptions = new CircleOptions() .fillColor(Color.parseColor("#77D7D7D7")) .center(locaPoiLatLng) .stroke(new Stroke(10, Color.BLUE)) .radius(500); if (null != overlayOptions) { mHandler.obtainMessage(ADDMARKER).sendToTarget(); } }else { String msg = (String) object.get("message"); mHandler.obtainMessage(SHOWMESSAGE,msg).sendToTarget(); } } } catch (JSONException e) { e.printStackTrace(); } } /** * 创建客户端圆形围栏回调 */ @Override public void onCreateLocalFenceCallback(CreateLocalFenceResult message) { super.onCreateLocalFenceCallback(message); Log.i(TAG, message.getMessage()+"---创建客户端圆形围栏回调---"+message.toString()); } /** * 查询本地围栏状态的回调(客户端状态 回调) */ @Override public void onQueryLocalFenceStatusCallback(String arg0) { super.onQueryLocalFenceStatusCallback(arg0); Log.i(TAG, "客户端状态回调---"+arg0); } /** * 更新圆形围栏的回调 */ @Override public void onUpdateCircularFenceCallback(String message) { super.onUpdateCircularFenceCallback(message); } /** * 删除围栏的回调 */ @Override public void onDeleteFenceCallback(String message) { super.onDeleteFenceCallback(message); Log.i(TAG, "删除---"+message); } /** * 查询围栏列表的回调 */ @Override public void onQueryFenceListCallback(String message) { super.onQueryFenceListCallback(message); try { JSONObject obj = new JSONObject(message); if (null != obj && obj.getInt("status") == 0) { if (obj.has("size") && obj.getInt("size") != 0) { JSONArray array = obj.getJSONArray("fences"); JSONObject object = array.getJSONObject(0); int shape = object.getInt("shape"); if (1 == shape) { JSONObject center = object.getJSONObject("center"); double latitude = center.getDouble("latitude"); double longitude = center.getDouble("longitude"); LatLng latLng = new LatLng(latitude, longitude); int radius = (int) object.getDouble("radius"); overlayOptions = new CircleOptions() .fillColor(Color.parseColor("#77D7D7D7")) .center(latLng) .stroke(new Stroke(10, Color.BLUE)) .radius(radius); if (null != overlayOptions) { mHandler.obtainMessage(ADDMARKER).sendToTarget(); } } }else{ Log.i(TAG,"查询无此ID"); } } Log.i(TAG, "查询围栏"+obj.toString()); } catch (JSONException e) { e.printStackTrace(); } } /** * 查询监控服务端对象状态的回调 */ @Override public void onQueryMonitoredStatusCallback(String message) { super.onQueryMonitoredStatusCallback(message); try { JSONObject object = new JSONObject(message); Log.i(TAG, "服务端状态---"+message); String status = null; if (null != object && object.getInt("status") == 0) { int size = object.getInt("size"); int mStatus = 0; for (int i = 0; i < size; i++) { JSONArray array = object.getJSONArray("monitored_person_statuses"); JSONObject obj = array.getJSONObject(0); String mPerson = obj.getString("monitored_person"); mStatus = obj.getInt("monitored_status"); if (1 == mStatus) { status = "监控对象[ " + mPerson + " ]在围栏内"; Log.i(TAG, "状态---"+status); } else if (2 == mStatus) { status = "监控对象[ " + mPerson + " ]在围栏外"; Log.i(TAG, "状态---"+status); } else { status = "监控对象[ " + mPerson + " ]状态未知"; Log.i(TAG, "状态---"+status); } } mHandler.obtainMessage(SHOWMESSAGE,status).sendToTarget(); mHandler.obtainMessage(PLAYMUSIC,mStatus).sendToTarget(); } } catch (JSONException e) { e.printStackTrace(); } } /** * 查询历史报警的回调 */ @Override public void onQueryHistoryAlarmCallback(String message) { super.onQueryHistoryAlarmCallback(message); } }; }
/** * 这个是创建服务端的圆形围栏,也就是监控者和被监控者是同一个人 * 用于情景 : 开车司机到到指定地方 */ public void creatServerFence(LatLng poiLatLng){ //轨迹服务ID int serviceID = mApp.getServiceId(); //创建者(entity标识) String creator = mApp.getName(); //围栏名称 (最长128个字节) String fenceName = "test"; //围栏描述 (最长1024个字节) String fenceDesc = "test"; //被监控对象列表 (每个监控对象都是轨迹服务中的entityName,使用英文逗号”,”分割) String monitoredPersons = mApp.getName();// String monitoredPersons = "hgy"; //观察者列表(多个entityName,以英文逗号"," 分割) String observers = mApp.getName(); //生效时间列表(一天中的几点几分到 几点几分生效。多个时间段使用分号”;”分隔。比如:“0820,0930;1030,1130”) String validTimes = "0600,2300"; //生效周期 (参数validTimes是否周期性生效,可以使用如下数值:1:不重复,2:工作日循环,3:周末循环,4:每天循环,5:自定义。当为5时,需要定义validDays,标识在周几生效) int validCycle = 4; //围栏生效日期 (当validCycle为1时必选,例如:"20150908") String validDate = ""; //生效日期列表 (1到7,分别表示周一到周日,格式 : "int,int…") String validDays = ""; //坐标类型 (1:GPS经纬度,2:国测局经纬度,3:百度经纬度) int coordType = 3; //围栏圆心(圆心位置, 格式 : "经度,纬度")// centers = "116.43068560351,39.929830261949"; //围栏半径(单位 : 米) double radius = 500; //报警条件(1:进入时触发提醒,2:离开时触发提醒,3:进入离开均触发提醒) int alarmCondition = 3; //如果传过来的LatLng不为空, 就赋值给要画围栏的参数中 locaPoiLatLng = poiLatLng; double lat = poiLatLng.latitude; double lon = poiLatLng.longitude; String centers = lon+","+lat; mApp.getLBSTraceClient().createCircularFence(serviceID, creator, fenceName, fenceDesc, monitoredPersons, observers, validTimes, validCycle, validDate, validDays, coordType, centers, radius, 0, alarmCondition, geoListener); }
/** * 删除服务端围栏 */ public void deleteServerFence(int fenceId) { mApp.getLBSTraceClient().deleteFence(mApp.getServiceId(), fenceId, geoListener); }
/** * 监控状态(服务端围栏) * 可以查询被监控者服务端存储的最新位置,是在围栏内或围栏外。 */ public void monitoredStatus() { // 围栏ID int fenceId = GeoFence.serverFenceId; // 监控对象列表(多个entityName,以英文逗号"," 分割) String monitoredPersons = mApp.getName(); mApp.getLBSTraceClient().queryMonitoredStatus(mApp.getServiceId(), fenceId, monitoredPersons, geoListener); }
private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { if (null != msg) { switch (msg.what) { case ADDMARKER: mApp.getmBaiduMap().clear(); mApp.getmBaiduMap().addOverlay(overlayOptions); break; case SERVERID: int serverId = (Integer) msg.obj; MyToastUtils.show(mContext, "创建服务端围栏编号: "+serverId); break; case SHOWMESSAGE: String s = (String) msg.obj; MyToastUtils.show(mContext, s); break; case PLAYMUSIC: int status = (Integer) msg.obj; if (1 == status) { playMusic(); } break; default: break; } } }; };