-
1 学习目的
-
2 引导训练
学习目的
1.掌握Android终端温度、光照、火焰、烟雾等数据采集方法
2.掌握Android的UI应用程序开发
3.熟悉C/S架构应用程序的开发


1.Android布局管理与初始化
家居环境监控界面,主要包括温度、湿度光照和火焰传感器的实时数据。在SmartHomeDemo工程的res\layout目录下添加room.xml布局资源。
表2-6房间场景界面控件属性
案例2-12 家居环境监控界面布局。
本系统采用线性布局(LinearLayout),具体代码如下所示:
1.<LinearLayout
2. android:layout_width= "match_parent"
3. android:layout_height=”360px"
4. android:orientation= "horizontal">
5. <com.smarthome. view. Text3DView
6. android: layout_width= "500px"
7. android: layout_height= "360px"/>
8. </LmearLayout>
9. <LmearLayout
10. android:layout_width= "match_parent"
11. android:layout_height= "120px"
12. android:gravity="center">
13. <Button
14. android:id="@+id/buttonBack"
15. android:layout_width="40dp"
16. android:layout_height="40dp"
17. android:background="@drawable/button_style"/>
18. <Button
19. android : id = ' @ + id/buttonShawQR"
20. android : layout_width = "45dp"
21. android : layout_height = "45dp"
22. android : layout_marginLeft = "30px"
23. android : background ="@drawable/button_style_showqr/>
24. <Button
25. android : id = "@ + id/buttonSetIP"
26. android : layout_width = ' 55dp"
27. android : layout_height= " 55dp'
28. android : layout_marginLeft = "30px"
29. android : background = " @drawable/button_style_setip"/>
30. <Button
31. android : id = "@ + id/buttonExit"
32. android : layout_width = "60dp"
33. android : layout_height= "60dp"
34. android : layout_marginLeft="480px"
35. android : background=" @drawable/button_style_exit"/>
36. </LinearLayout>
案例2-13 家居环境监控界面控件初始化。
初始化控件,具体代码如下所示:
1. private void initView( ) {
2. buttonExit = (Button) findViewById(R.id.buttonExit);
3. buttonBack = (Button) findViewById(R id.buttoriBack);
4. buttonQR = (Button) findViewById(R id.buttonShowQR);
5. buttonSET =(Button) findViewById(R.id.buttonSetIP);
6. // PC变互线程开启
7. buttonBack. setOnClickListener( new OnClickListener( ) {
8. public void onClick(View v) {
9. final AlertDialog. Builder builder = new AlertlDialog. Builder(
10. Room. this);
11. builder.setTitle( "提示 " )
12. .setMessage ( "确定要退出房间,返回到刷卡验证吗? " )
13. .setCancelable(true)
14. .setPositiveButton( "确定”',
15. new Dialogjnterface. OnClickListener( ) {
16. public void onClick( Dialoglnterface dialog,
17. int id) {
18. dialog. cancel( );
19. mHandler. removeCallbacks(update);
20. Main.dooropen = false;
21. flag = false;
22. finish();
23. }
24. })
25. .setNegativeButton("取消",
26. new DialogInterface.OnClickListener(){
27. public void onClick(DialogInterface dialog,
28. int id){
29. dialog.cancel();
30. }
31. });
32. AlertDialog alert = builder.create();
33. alert.show();
34. }
35. });
36. //二维码
37. buttonQR.setOnClickListener(new OnClickListener() {
38. public void onClick(View v){
39. startActivity(new INtent().setClass(Room.this,
40. QR_IP_Activity.class));
41. }
42. });
43. //设置
44. buttonSET.setOnClickListener(new OnClickListener(){
45. public void onClick(view v){
46. startActivity(new Intent().setClass(Room.this,
47. SetIPActivity.class));
48. }
49. });
50. //退出
51. buttonExit.setOnClickListener(new OnClickListener(){
52. public void onClick(View v){
53. exit();
54. }
55. });
56. }
57.
2.环境传感器数据采集与显示的实现
实现环境传感器数据监控界面初始化,实时获取房间温度、光照、火焰与烟雾情况,根据阈值判断是否出现火灾。
案例2-14 环境传感器数据采集与显示的实现
1.public class Room extends Activity{
2. private ReceiveThread rt;
3. private Button buttonExit, buttonBack, buttonQR, buttonSET;
4. public static String temp_toshow = "温度:20℃";
5. public static String light_toshow ="光照:30 lx";
6. public static String flame_toshow ="火焰:正常";
7. public static String smoke_toshow ="烟雾:正常";
8. @Override
9. protected void onCreate(Bundle savedInstanceState){
10. super.onCreate(savedInstanceState);
11. requestWindowFeature(Window.FEATURE_NO_TITLE);//设置标题为空
12. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
13. WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏
14. setContentView(R.layout.room);
15. initView();
16. ShareData.Request = getCRCChar(ShareData.Request);
17. ShareData.Request_String = String.valueOf(ShareData.Request);
18. ShareData.mdata = new MyData(0,0,0,0,0,0,0,0,0,0,0,0,0,0,
19. 0,0,0,0,"",System.currentTimeMillis());
20. ShareData.modbusData = new ModbusData(0,0,0,0,0);
21. final SerialPort sPort = new SerialPort();
22. //打开串口,设置波特率
23. Global.com_modbus = sPort.openPort(1,0,3);
24. mHandler = new Handler();
25. mHandler.post(uptate);
26. rt = new ReceiveThread();
27. rt.execute(0,0,0);
28. }
29. private int ms = 800;
30. private Handler mHandler = null;
31. private Runnable update = new Runnable(){
32. public void run(){
33. mHandler.postDelayed(update,ms);
34. upDataUI();
35. }
36. }
37. //界面更新
38. public void upDataUI(){
39. //向工控模块发送请求命令
40. String strKLHA = "#0196010oo\r";//最后面需要加换行
41. Linuxc.sendMsgUart(Global.com_modbus, strKLHA);
42. try{
43. Thread.sleep(200);
44. }catch(InterruptedException e){
45. }
46. //发送数据,出发工控木块设备,返回串口数据
47. Linuxc.sendMsgUartHex(Global.com_modbus,ShareData.Request_String,
48. ShareData.Request_String.length());
49. //工控模块设备数据采集
50. MainAssist.getinstance().setADAM4117Data(0,true);
51. //获取温度传感器值
52. String strT = DataConvert.getdataConvert().ConvertTemperature(
53. MainAssit.getinstance().datatemp1,
54. MainAssit.getinstance().datatemp2,999,200,50);
55. MainAssist.getinstance().setADAM4117Data(1,false);
56. if(!strT.trim().equals("")){
57. if(Double.parseDouble(strT.trim())<=100
58. &&Double.parseDouble(strT.trim())! = 0){
59. ShareData.modbusData.strTemp = strT;
60. }
61. temp_toshow = "温度:"+ ShareData.modbusData.strTemp + "℃";
62. }
63. //获取光照传感器值
64. String strLight = DataConver.getdataConvert().ConvertTemperature(
65. MainAssist.getinstance().datalight1,
66. MainAssist.getinstance().datalight2,9999,5000,0);
67. if(!strLight.trim().equals("")){
68. if(Double.parseDouble(strLight.trim())!= 0)
69. ShareData.modbusData.strLight = strLight;
70. light_toshow = "光照:" + ShareData.modbusData.strLight + "lx";
71. }
72. //获取烟感火焰开关值.这里连接取值为工控模块设备的第5通道
73. if(MainAssist.getinstance().setADAM4150(5) ==‘1’){
74. ShareData.fire = true;
75. flame_toshow = "火焰:着火";
76. }else{
77. ShareData.fire = false;
78. flame_toshow ="火焰:正常";
79. }
80. //获取烟感火焰开关值.这里连接取值为工控模块设备的第6通道
81. if(MainAssist.getinstance().setADAM4150(6)==‘1'){
82. ShareData.smoke = true;
83. smoke_toshow = "烟感:冒烟";
84. }else{
85. ShareData.smoke = false;
86. smoke_toshow = "烟感:正常";
87. }
88. }
89. protected void onDestroy(){
90. super.onDestroy();
91. if(Global.com_modbus>0)
92. Linuxc.closeUart(Global.com_modbus);
93. if(flag)}
94. android.os.Process.killProcess(android.os.Process.myPid());
95. System.exit(0);
96. }
97. }
98. private boolean flag = true;
99. public boolean onKeyDown(int keyCode, KeyEvent event){
100. if(keyCode = = KeyEvent.KEYCODE_BACK && event.getRepeatCount() = = 0){
101. exit();
102. }
103. return false;
104. }
105.}
3.静态变量存储ShareData类的实现
在Android系统中,最简单的数据存储方法是SharedPreferences。这是一种轻量级的数据保存方式,通过SharedPreferences开发人员可以将NVP(Name、Value、Pair,名称、值对)保存在Android的文件系统中,而且SharedPreferences完全屏蔽对文件系统的操作过程,开发人员仅通过调用SharedPreferences对NVP进行保存和读取。
案例2-15 静态变量存储
在智能家居系统中,ShareDate类定义了常用的静态变量,关键代码如下所示:
1.public class ShareDate {
2. public static MyDate mdata =null;//modbus通道数据存储
3. public static ModbusDate modbusDate =null;//modbus数据存储
4. public static byte addressByte =0x01;//工控模块指令地址码
5. public static byte functionInByte =0x01;//工控模块输入功能码
6. public static char[]Request={(char)addressByte,
7. (char)functionInByte,0x00,0x00,0x00,0x07};//工控模块请求指令,未加后面两位验位
8. public static String Request_String=String.value0f(Request);
9. public static int current_status=0;//当前状态值
1O. public static boolean fire= false;//火焰
11. public static boolean smoke= false;//烟感
12. public static SharedPreferEnces spPreferences;//轻量级存储类
13. public static Editor editor;
14. public static boolean dooropen= false;//开门,关门
15. public static int com_mocbus=-1;//有线传感串口值
16.}
4.传感器数据采集ReceiveThread类的实现
Modbus是由Modicon(现为施耐德电气公司的一个品牌)在1979年发明的,是全球第一个真正用于工业现场的总线协议。
目前的通信方式是232串口,使用modbus通信协议。在android上只需完成人机界面、指令下发并接受反馈。
1、modbus工业控制总线传感器值接口,包括光照线性值、温度线性值、霍尔开关值、接近开关值、光电开关值:
public String getModbus(String strType);
2、高频RFID
public void setCard(String str);
public string getCard(String strType);
案例2-16传感器数据采集。
Modbus通过线程ReceiveThread. java实时获取传感器数据。
1. protected Integer doInBackground( Integer. . . params) {
2. int len = O;
3. char d[ ] = new char[1024];
4 String str_receive = null;
5. while(Global. com_modbus > o) {
6. if (!islen) {
7. str_receive = Linuxc.receiveMsgUartHex(Global.com_modbus);
8. }
9. if (this. isCancelled()) {
10. break;
11. }
12. try{
13. Thread currentThread( ) .sleep( 45 ) ;
14. }catch (InterruptedExcption e) {
15. e.printStackTrace();
16. }
17. if (str_receive = = null) {
18. continue;
19. }
20. if ( str_receive. indexOf( " - + ")> = O) {
21. try {
22. ShareData. mdata. firsttime = System. currentTimeMillis( ) ;
23. //获取 Kl M4000通道值
24. String ValueString = str_receive;
25. ShareData. mdata. data01 = judge(ValueString. substring(
26. ValueString. indexOf ( "= " ) + 1,
27. ValueString. indexOf( "@" ))) ;
28. ValueString = ValueString. substring(ValueString
29. .indexOf( "@" ) +2);
30. ShareData. mdata. datall = judge(ValueString. substring(
31. ValueString. indexOf ( " = " ) + 1.
32. ValueString. indexOf( "@" ))) ;
33. ValueString = ValueString. substring(ValueString
34. .indexOf( "@" ) +2);
35. ShareData mdata. data21 = judge(ValueString. substring(
36. ValueString. indexOf ( " -. " ) + 1,
37. ValueString. indexOf( "@" ))) ; ;
38. ValueString - ValueString. substring(ValueString
40. ShareData mdata. data31 = judge(ValueString. substring(
41. ValueString. indexOf ( " = " ) + 1.
42. ValueString. indexOf( "@" ))) ;
43. ValueString = ValueString. substring(ValueString
44. .indexOf( "@" ) +2);
45. ShareData mdata. data41 = judge(ValueString. substring(
46. ValueString. indexOf ( " = " ) + 1,
47. ValueString. indexOf( "@" ))) ;
48. ValueString = ValueString. substring(ValueString
49. .indexOf( "@" ) +2);
50. ShareData mdata. data51 = judge(ValueString. substring(
51. ValueString. indexDf( " = " ) + 1.
52. ValueString. indexOf( "@" ))) ;
53. ValueStnng = ValueString. substring(ValueStriW
54. .indexOf( "@" ) +2);
55. ShareData mdata. data61 = judge(ValueString. substring(
56. ValueString. indaOf ( " = " ) + 1,
57. ValueString. indexOf( "@" ))) ;
58. ValueString = ValueString. substring(ValueString
59 .indexOf("@") + 2);
60. ShareData. mdata. data71 = judge(ValueString. substring(
61. ValueString.indexOf(" =") + 1,
62. ValueString.indexOf ( "@"))) ;
63. } catch (Exception e) {
64. e. printStackTrace( ) ;
65. }
66. }
67. len = str_ receive.length();
68. count = len + count;
69. if (len = = 0) {
70. continue;
71. }
72. d=str_receive. toCharArray();
73. System.arraycopy(d,0,data, datalen, len);
74. datalen + = len;
75. while (true){
76. islen = false;
77. mark_head=findCharInReceiveData(0.(char) Ox01);
78. if (mark_head<0)//查找不到,把所有的数据丢掉
79. {
80. datalen=0;
81. break;
82. }
83. lengthcount=6j
84. if (datalen<lengthcount){//数据量小于6个,不判断
85. break;
86. }
87. funCode=(char) Ox01;
88. int length=1;
89. if (data[mark_head+1]!=funCode){
90. if (datalen>=lengthcount){
91. datalen=datalen - lengthcount - mark_head;
92. if (datalen>0){
93. System. arraycopy(data, mark_head+lengthcount,
94. data, 0,datalen);
95. }
96. }
97. comtinue;
98. }else{
99. //正确执行命令的返回数据
100. if(datelen-mark_head<lengthcount){
101. //数据有接收完;等待接收完再处理
102. break;
103. }
104. if (data[mark_head + 2] ! = length) {
105. datalen = datalen - lengthcount - mark_head;
106. System. arraycopy(data, mark_head + lengthcount. data.
107. O, datalen);
108. break;
109. }
110. ShareData mdata firsttime = System currentTimeMillis(>;
111. ShareData mdatt丑 length = data[mark_head + 2J;
112. ShareDatt色 mdata data4150 = datatmark_head + 3J;
113. datalen = datalen - lengthcount - mark_head;
114. System. arraycopy(data, mark_head + lengthcount, data, O,
115. datalen) ;
116. if (datalen > = lengthcount) {
117. islen = true;
118. } else {
119. islen = false;
120. }
121. count = 0;
122. }
123. }
124. }
125. return l;
126. }
5.传感器数据转换DataConvert类的实现
modbus传感器值转换DataConvert.java类,功能是实现温度、光照值转换与校验。
ConvertTemperature(int data01, int data02, intValueRange, intTemperatureRange, intNegativeTemperature)
参数:data01十六进制值byte1;data02十六进制值byte2;ValueRange量值;TemperatureRange温度范围值总和;NegativeTemperature温度负数值。
返回值:return 温度值。
案例2-17 传感器数据转换。
1.public String ConvertTemperature( int data01, int data02,int ValueRange
2. int TemperatureRange,int NegativeTemperature){
3. //未连接设备时,ADAM4117返回值为”EF”
4. if (data01= = 255&&data02 = = 255)
5. return”未连接”;
6. //两个十六进制值相加,转换成十进制值
7. string sValue=Integer. toHexString(data01)
8. + Integer. toHexString(data02);
9. int TemValue = Integer. parseInt(sValue. 16);
10. //模拟值换算公式:温度T = 模拟值/量值×温度范围值总和一温度负数值
11. float vl=(float) data01/(float) ValueRange;//强制转化成float型取得小数位
12. float fValue = vl * TemperatureRange一NegativeTemperature;
13. //温度出现异常时,返回空值
14. if (fValue<- 40)
15. return "O";
16. else if (fValue>500)
17. return "500";
18. else {
19. DecimalFormat df = new DecimalFormat("0.0");//格式化小数,不足的补0
20. String strtemValue=df.format(fValue);
21. return strTemValue;
22. }
23. }
案例2-18 与PC服务器通信的线程类。
l. public class SendPCThread. extends Thread{
2. public.static String IP = "192.168.1.2";
3. public.static int PORT=9999;
4. private ButfferedWriter myBufferedtriter;
5. @Override
6.public void run()(
7. super. run();
8. Socket mySocket = new Socket();
9. IP = Global. spPreferences. getString("dormIP","192. 168.0.1");
10. While (!Main system_exit){
11. if (ShareData. fire || ShareData. smoke){
12. try{
13. mySocket = new Socket(IP, PORT);
14. myBufferedWriter= new BufferedWriter(
15. new OutputStreamWriter(mySocket. getOutputStream()));//通过TCP
向PC端以JSon格式发送报警信息
16. myHufferedWriter.write( new JSONObject( )
17. . put( "warning". "on" ). toString() + "\r\n" );
ia. myBufferedWriter. flush( );
19. sleep( 15000);
20. } catch (UnknownHostException e) {
21. } catch (IOException e) {
22. } catch (JSONException e) {
23. } catch (InterruptedException e) {
24. }
25. } else {
26. try {
27. sleep(200);
28. } catch (lnterruptedException e) {
29. }
30. }
31. }
32. interrupt( ) ;
33. }
34.
35.}
案例2-19 与PC服务器通信消息的获取
1. public class SendMessage extends Thread{
2. private Socket mySocket;
3. private BufferedReader myBufferedReader;
4. private JSONObject myInput_JsonObject;
5. private JSONObject myoutput_JsonObject;
6. public SendMessage(Socket socket){
7. mySocket = socket;
8. }
9. @Override
1O. public void run( ) {
11. super. run( ) ;
12. while ( ! Main. system_.exit) {
13. try {
14. if (getResponse() ! = null) {
15. BufferedWriter bw = new BufferedWriter(
16. new OutputStreamWriter(mySocket.getOutStream( ))) ;
17. bw.write(myOutput_JsonObject. toString() + "\n");
18. bw.flush( ) ;
19. }
20. } catch (Exception e) {
21. }
22. }
23. interrupt ( ) ;
24. }
25. //获取响应数据
26. private JSONObject getResponse( ){
27. myOutput_JsonObject = null;
28. try {
29. myOutput_JsanObject = new JSONObject( );
30. myOutput_JsonObiect put( " temp", Dorm. temp_toshow) ;
31. myOutput_JsanObject put( "light", Dorm. light_toshow);
32. myOutput_JsorObject put( "flame", Dorm. flame_toshow);
33. myOutpUt_JsorObject put( "smoke", Dorm. smoke_toshow);
34. } catch (Exception e) {
35. myOutput_JsonObject =null;
36. }
37. return myOutput_JsonObject;
38. }
39. }
同步训练与考核评价