安防小应用总结 第一季
来源:互联网 发布:工业数据采集器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) 布局
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"}]}}
{"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连接超时时间
设置转屏,支持高分辨率大屏幕
- 安防小应用总结 第一季
- 安防小应用总结 第二季
- 安防小应用总结 第三季
- hibernate--->张国亮总结第一季
- java基础总结---第一季
- Hibernate3学习总结——第一课时 简单应用演示
- 我的第一个安卓应用出生过程及总结
- MVC---张国亮总结心得第一季
- JSP自定义标签---->张国亮总结第一季
- hibernate 高级映射 -->张国亮总结第一季
- Hibernate高级---张国亮总结心得第一季
- The Simpsons第一季简要总结
- Android常用知识总结---第一季
- 第一个Qt应用的实现-总结移植之后的步骤
- 第一个Servlet应用
- Hibernate第一个应用
- 第一个小应用
- 第一个struts应用
- c#截取字符窜问题
- C语言 流程控制语句
- ORACLE学习笔记
- ORA-12519: TNS:no appropriate service handler found 解决
- Android4.2.1源码下载
- 安防小应用总结 第一季
- java.sql.SQLException: 结果集已耗尽
- Linux C编程--线程操作1--线程概述和简单的线程操作
- 数据库开发的一些常识(SQL)
- 马云说,“如果我今天开始创业,首先想的是如何利用好腾讯或阿里巴巴”
- UIFont
- ios后台在线
- 中断屏幕恢复
- 《参考消息》:360是如何炼成的