安防小应用总结 第一季

来源:互联网 发布:工业数据采集器modbus 编辑:程序博客网 时间:2024/05/16 19:19

0. Demo介绍


服务器IP Receiver控制整个安防系统,要求添加移动客户端App,手机用户控制IP Receiver获取安防设备的布撤防信息对其实时监控。

移动端设计:用户登陆->九宫格加密->实时监控

    

1. 设计通信协议

手机通过Http应用层协议的post方式与服务端IP Receiver通信。设计协议须注意添加command命令,通常情况下,客户端需要服务端有一个command的反馈确认,以便解析response.

try {JSONObject jo= new JSONObject(info);r_res = jo.getString("response");// registrationif (r_res.equals("login")) {r_code = jo.getString("code");if (r_code.equals("100")) {r_data = jo.getString("data");

2  实现Http接口函数

程序基于C/S架构,Http通信的实现考虑一个统一的接口函数,把它作为一个独立类的方法。调用时,先new一个该类的对象,再调用方法。

由于通信过程有时间延迟,须更新UI,故sendMessage发送消息给主线程处理UI事件,这里要注意几点,

  • 联网会阻塞,通过消息机制处理滚动条
  • 妥善处理各种ERROR的安置工作
    ws = new WampServer(DeviceActivity.this);Thread connectThread = new Thread(new Runnable() {       public void run() {      ws.connect(registerUrl, pairs1);       }    });
3. 用户登陆
安全性与便捷性往往是鱼和熊掌,不可兼得,这里选择一种折中的策略,即
第一次登陆输入用户密码,服务器响应登陆成功,由SharedPreference保存用户信息于本地,进入九宫格界面设置密码,密码同理保存本地。以后再登陆,则程序检查本地用户信息,若存在则直接进入九宫格界面核对密码,若连续输错三次或者切换用户,则清空SharedPreference用户信息,重新登陆。

4. 滑动开关设计
1) 布局
最外围TableLayout,一行两列呈现设备名和开关,开关为RelativeLayout,分ImageView图标和TextView,TextView为LinearLayout,左右比例1:1.

2) 获取设备信息
编写开关图标的独立新类,客户端得到几个设备,就建立几个该类的对象,构造函数里获取设备编号,发送消息,初始化图标及其位置。
public SwitchView(Context context, String device) {super(context);this.context = context;dev = device;initView();}
每隔5秒发送心跳包从服务端更新设备信息,若有状态变化,则发送消息更新UI,由于涉及多个设备,须逐个检查更新,解决bundle.getString()空指针问题。
                case MSG_UPDATE_DEV: {               for (int i = 0; i < total_count; i++) {            try {            if (!bundle.getString("host_status" + i).isEmpty()) {                sv[i].changeView(bundle.getString("host_status" + i));                System.out.println("update:"+i+" status:"+bundle.getString("host_status"+i));                }            } catch (NullPointerException e) {            e.printStackTrace();            continue;            }            }                    break;
3) 开关控制逻辑设计
滑动开关有延时确认,不惜牺牲用户体验也要防止布撤防误操作。
比如延迟1秒,设置长按钮,超过1秒后改变图标。
1秒内从ACTION_DOWN到ACTION_UP,则在ACTION_MOVE中跳出不执行操作,图标返回原位。
case MotionEvent.ACTION_MOVE: //1s delay to ensure safetyif ((System.currentTimeMillis() - downTime) < 1000) {if (delayFlag == 0) {Toast.makeText(getContext(), "press more than 1s", Toast.LENGTH_SHORT).show();delayFlag = 1;}//prevent the cursor from large movementint dx = (int) event.getRawX() - lastX;if (dx > bg_left + margin) {dx = bg_left + margin;}if (dx < -(bg_left + margin)) {dx = -(bg_left + margin);}//control the cursor movementcursor_left = v.getLeft() + dx;cursor_right = v.getRight() + dx;if(cursor_left <= bg_left + margin) {cursor_left = bg_left + margin;cursor_right = cursor_left + v.getWidth();}if(cursor_right >= bg_right - margin) {cursor_right = bg_right - margin;cursor_left = cursor_right - v.getWidth();} //maintain the cursor in the scopev.layout(cursor_left, cursor_top, cursor_right, cursor_bottom);lastX = (int) event.getRawX();break;}//control the cursor movement
通过一些flag控制逻辑,实现布防撤防操作。
// do arm/disarmif ((isArm ^ isChecked()) && isSet == true) {
如果操作失败,须返回失败前的状态
int result = ws.connect(commandUrl, pairs);      // turn back to the last position      if (result == 0) {      if (isArm)      sendMessageToUI(MSG_LAYOUT_CHANGE, "disarm");      else       sendMessageToUI(MSG_LAYOUT_CHANGE, "arm");      }

5. 多线程同步问题

显示设备有些问题,起初以为是多线程同步的问题,后来发现其实是轮训设备的问题,退出程序后清空了设备信息,而轮训设备的线程由于还在睡眠没有退出,会再执行一次Get Device询问,由于设备信息已被清空,Get Device会再去更新一次界面添加设备,而此时程序已经退出,它会在下一次启动后执行请求更新界面,所以下一次启动时的界面将出错。

6.解析JSONArray
{"response":"info","code":100, 
"data":{"pagination":{"current_page":1,"total_count":3}, 
"host":[{"account":"1000","host_status":"0","group_id":"00"},
{"account":"200000","host_status":"1","group_id":"00"},
{"account":"3000","host_status":"2","group_id":"00"}]}}
JSONArray ja_host = jo_data.getJSONArray("host");JSONObject jo_host;//add deviceif (account.isEmpty()) {for (int i = 0; i < ja_host.length(); i++) {jo_host = (JSONObject) ja_host.get(i);account.add(i, jo_host.getString("account"));host_status.add(i, jo_host.getString("host_status"));group_id.add(i, jo_host.getString("group_id"));}

X. 一些小bug
无menu键:android:minSdkVersion设置过高
EditText无显示:应在onCreate而非onClick里setText().
onDestroy()里要关闭无限循环的线程2
onTouch与onLongClick冲突问题:onTouch返回值设为false
中英文版本设置问题,布撤防失败归位问题
九宫格密码设置标记,应对未设密码退出的情形
设置http连接超时时间
设置转屏,支持高分辨率大屏幕