局域网控制系统-上位机-Android手机

Posted weifeng727

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了局域网控制系统-上位机-Android手机相关的知识,希望对你有一定的参考价值。

.java文件源码(供参考,请使用前自行作修改):

  1 package com.example.hello;
  2 
  3 import java.io.DataInputStream;
  4 import java.io.DataOutputStream;
  5 import java.io.IOException;
  6 import java.net.Socket;
  7 import java.util.Timer;
  8 import java.util.TimerTask;
  9 
 10 import android.os.Bundle;
 11 import android.os.Handler;
 12 import android.os.Message;
 13 import android.app.Activity;
 14 import android.view.KeyEvent;
 15 import android.view.Menu;
 16 import android.view.View;
 17 import android.view.View.OnClickListener;
 18 import android.widget.Button;
 19 import android.widget.CompoundButton;
 20 import android.widget.EditText;
 21 import android.widget.ImageView;
 22 import android.widget.Switch;
 23 import android.widget.TextView;
 24 
 25 public class MainActivity extends Activity {
 26 
 27     private Switch light00,light01,light02;
 28     private TextView current_ip,socketstate,notice1;
 29     private int[] temperature=new int[1];
 30     private TextView[] tv_temperature=new TextView[temperature.length];
 31     
 32     private EditText et_ip1,et_ip2,et_ip3,et_ip4,et_port;
 33     //private EditText et_deviceID;
 34     private Button btn_set_ip,delete_socket,fengmingqi1,jdq_off,jdq_on;
 35     private ImageView light_00,light_01,light_02;
 36     private ImageView jidianqi1;
 37     
 38     private int port = 8080;
 39     private String IP="";
 40     private Socket socket=null;
 41     Thread thread1=null,thread2=null;
 42     private byte[] tcp_receive_buf=new byte[DataPackage_Length];
 43     private static final int DataPackage_Length=15;   //只接收15个字符(数据包长度为15)
 44     private DataInputStream dataInputStream=null;
 45     private DataOutputStream dataOutputStream=null;
 46     
 47     private static final String deviceID = "03";                              //用于串口通信时,定义本地设备ID
 48     private static final String datapackage_headflag = "A";          //用于串口通信时,定义数据包头部的验证标记
 49     
 50     //----------通信监测----------//
 51     private boolean NeedToCheckTCP = false;
 52     private boolean heartbeat = false;      //心跳包(用来协助监测通信是否断开)
 53     private Timer timer_TCPMonitor=null;   
 54     
 55     //----------产生发送数据的间隔----------//
 56     private boolean SendCMD_WaitFlag = false;
 57     private Timer timer_SetSendCMD_Interval=null;
 58     void SetSendCMD_Interval(int Interval)
 59     {      
 60         timer_SetSendCMD_Interval=new Timer();
 61         timer_SetSendCMD_Interval.schedule(new TimerTask() {  
 62             @Override
 63             public void run() {                        
 64                 SendCMD_WaitFlag = false;    
 65             }
 66         },Interval,600000);   //定时器开始工作
 67     }
 68     
 69     //----------定时器控制指令的发送----------//
 70     private Timer timer_SendCMD=null;
 71 
 72     //----------------------------通信协议----------------------------//
 73     /*
 74     客户端数据包格式解释(长度恒为15):
 75     例如:A01_fmq_01Off___#
 76     A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种)
 77     01-----设备代号
 78     fmq_01Off___--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部
 79     #---------数据包的结束标记
 80 
 81     服务器端数据包格式解释(长度恒为15):
 82     例如:A02_SenT010250#
 83     A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种)
 84     02-----设备代号
 85     SenT010250--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部
 86     #---------数据包的结束标记
 87      */
 88 
 89     //---------------------------------固定发送数据包集------------------------------//
 90     private static final String tcp_data_try=datapackage_headflag+deviceID+"_Try!______#";   
 91     private static final String tcp_data_SenT00=datapackage_headflag+deviceID+"_SenT00____#"; 
 92     private static final String tcp_data_fmq00off=datapackage_headflag+deviceID+"_fmq_00Off_#"; 
 93     private static final String tcp_data_fmq00on=datapackage_headflag+deviceID+"_fmq_00On__#"; 
 94     private static final String tcp_data_jdq00off=datapackage_headflag+deviceID+"_jdq_00Off_#"; 
 95     private static final String tcp_data_jdq00on=datapackage_headflag+deviceID+"_jdq_00On__#"; 
 96     private static final String tcp_data_light00on=datapackage_headflag+deviceID+"_Ligt00On__#"; 
 97     private static final String tcp_data_light00off=datapackage_headflag+deviceID+"_Ligt00Off_#"; 
 98     private static final String tcp_data_light01on=datapackage_headflag+deviceID+"_Ligt01On__#"; 
 99     private static final String tcp_data_light01off=datapackage_headflag+deviceID+"_Ligt01Off_#"; 
100     private static final String tcp_data_light02on=datapackage_headflag+deviceID+"_Ligt02On__#"; 
101     private static final String tcp_data_light02off=datapackage_headflag+deviceID+"_Ligt02Off_#"; 
102     private static final String tcp_data_socketoff=datapackage_headflag+deviceID+"_SockOff__#";
103     
104     private boolean connectflag=false;
105     private boolean openfmq00=false;
106 
107     @Override
108     protected void onCreate(Bundle savedInstanceState) {
109         super.onCreate(savedInstanceState);
110         setContentView(R.layout.activity_main);
111         
112         current_ip=(TextView)findViewById(R.id.tv_current_ip);
113         socketstate=(TextView)findViewById(R.id.tv_socketstate);
114         notice1=(TextView)findViewById(R.id.tv_notice1);
115         tv_temperature[0]=(TextView)findViewById(R.id.tv_temperature00);
116         et_ip1=(EditText)findViewById(R.id.et_ip1);
117         et_ip2=(EditText)findViewById(R.id.et_ip2);
118         et_ip3=(EditText)findViewById(R.id.et_ip3);
119         et_ip4=(EditText)findViewById(R.id.et_ip4);
120         et_port=(EditText)findViewById(R.id.et_port);
121         //et_deviceID=(EditText)findViewById(R.id.et_deviceID);
122         btn_set_ip=(Button)findViewById(R.id.btn_setip);
123         delete_socket=(Button)findViewById(R.id.btn_deletesocket);
124         fengmingqi1=(Button)findViewById(R.id.btn_fmq1);
125         jdq_off=(Button)findViewById(R.id.btn_jidianqi_off);
126         jdq_on=(Button)findViewById(R.id.btn_jidianqi_on);
127         light00=(Switch)findViewById(R.id.sw_light00);
128         light01=(Switch)findViewById(R.id.sw_light01);
129         light02=(Switch)findViewById(R.id.sw_light02);
130         light_00=(ImageView)findViewById(R.id.image_light00);
131         light_01=(ImageView)findViewById(R.id.image_light01);
132         light_02=(ImageView)findViewById(R.id.image_light02);
133         jidianqi1=(ImageView)findViewById(R.id.image_jidianqi1);
134         
135        current_ip.setText("暂无");
136        
137        light00.setTextOff("关闭");
138        light00.setTextOn("打开");
139        light01.setTextOff("关闭");
140        light01.setTextOn("打开");
141        light02.setTextOff("关闭");
142        light02.setTextOn("打开");
143 
144        light00.setEnabled(false);
145        light01.setEnabled(false);
146        light02.setEnabled(false);
147        
148        //控制light
149        light00.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {  
150            @Override  
151            public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { 
152                light00.setEnabled(false);
153                    if(light00.isChecked()){
154                         if(tcp_send_data(tcp_data_light00on,4)){
155                             light_00.setImageDrawable(getResources().getDrawable(R.drawable.open_light));
156                             light00.setEnabled(true);  //涉及到UI操作,但此行代码是主线程执行的,所以不会导致程序崩毁
157                         }
158                    }
159                    else{
160                        if(tcp_send_data(tcp_data_light00off,4)){
161                            light_00.setImageDrawable(getResources().getDrawable(R.drawable.close_light));
162                            light00.setEnabled(true);
163                        }               
164                 }       
165            }
166        });
167        //控制light
168        light01.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {  
169            @Override  
170            public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { 
171                light01.setEnabled(false);
172                    if(light01.isChecked()){
173                         if(tcp_send_data(tcp_data_light01on,4)){
174                             light_01.setImageDrawable(getResources().getDrawable(R.drawable.open_light));
175                             light01.setEnabled(true);
176                         }                    
177                    }
178                    else{
179                        if(tcp_send_data(tcp_data_light01off,4)){
180                            light_01.setImageDrawable(getResources().getDrawable(R.drawable.close_light));
181                            light01.setEnabled(true);
182                        }               
183                 }
184            }
185        });
186        //控制light
187        light02.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {  
188            @Override  
189            public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { 
190                light02.setEnabled(false);
191                    if(light02.isChecked()){
192                         if(tcp_send_data(tcp_data_light02on,4)){
193                             light_02.setImageDrawable(getResources().getDrawable(R.drawable.open_light));
194                             light02.setEnabled(true);
195                         }                    
196                    }
197                    else{
198                        if(tcp_send_data(tcp_data_light02off,4)){
199                            light_02.setImageDrawable(getResources().getDrawable(R.drawable.close_light));
200                            light02.setEnabled(true);
201                        }               
202                 }
203            }
204        });
205        //测试蜂鸣器
206        fengmingqi1.setOnClickListener(new OnClickListener() {        
207             @Override
208             public void onClick(View arg0) {        
209                 if(connectflag==true){
210                     if(openfmq00==true){                
211                         if(tcp_send_data(tcp_data_fmq00off,3000)){
212                             openfmq00=false;
213                             fengmingqi1.setText("启动蜂鸣器");
214                         }
215                     }
216                     else{
217                         if(tcp_send_data(tcp_data_fmq00on,4)){
218                             openfmq00=true;
219                             fengmingqi1.setText("关闭蜂鸣器");
220                         }
221                     }
222                 }
223             }
224         });
225        //控制继电器
226         jdq_off.setOnClickListener(new OnClickListener() {        
227             @Override
228             public void onClick(View arg0) {        
229                 if(connectflag==true){
230                     if(tcp_send_data(tcp_data_jdq00off,4)){
231                         jidianqi1.setImageDrawable(getResources().getDrawable(R.drawable.jidianqi_off));
232                     }
233                 }
234             }
235         });
236       //控制继电器
237         jdq_on.setOnClickListener(new OnClickListener() {        
238             @Override
239             public void onClick(View arg0) {        
240                 if(connectflag==true){
241                     if(tcp_send_data(tcp_data_jdq00on,4)){
242                         jidianqi1.setImageDrawable(getResources().getDrawable(R.drawable.jidianqi_on));
243                     }
244                 }
245             }
246         });
247       //建立socket连接      
248         btn_set_ip.setOnClickListener(new OnClickListener() {        
249             @Override
250             public void onClick(View arg0) {        
251                 setsocket();  
252             }
253         });
254        //删除socket
255        delete_socket.setOnClickListener(new OnClickListener() {        
256             @Override
257             public void onClick(View arg0) {        
258                 if(connectflag==true){
259                      tcp_send_data(tcp_data_socketoff,4);
260                      DeleteSocket();
261                      Message message=new Message();
262                      message.what=5;
263                      handler.sendMessage(message);    //发送Messgae给与主线程绑定的handler,让主线程来作出响应,主要是让主线程做一些UI的操作
264                 }         
265             }
266         });
267     }
268     
269     /*----------------设置按返回键会将程序后台运行而不是关闭-------------------*/
270     public boolean onKeyDown(int keyCode, KeyEvent event) {  
271         if (keyCode == KeyEvent.KEYCODE_BACK) {  
272             moveTaskToBack(false);   //false保留后台运行  true不保留后台运行
273             return true;  
274         }  
275         return super.onKeyDown(keyCode, event);  
276     }
277     /*---------------------------------------------------------------------------*/
278     
279     /*------------------------------自定义函数---------------------------------*/
280   //TCP发送数据,返回一个布尔值,用来确定是否发送数据成功
281     boolean tcp_send_data(String str,int MinInterval){
282         while(SendCMD_WaitFlag);    //等待结束上一次发送数据所要求的间隔,以保证每次发送出去的数据包都能被正确接收处理        try{
283         if(timer_SetSendCMD_Interval != null){
284             timer_SetSendCMD_Interval.cancel();    //注意:timer对象在没有工作的时候,不能对其进行cancel,否则会导致程序崩毁
285             timer_SetSendCMD_Interval=null;
286         }    
287         //SendCMD_WaitFlag = true;
288         try{
289                 dataOutputStream.write(str.getBytes());
290                 dataOutputStream.flush();             
291                 SetSendCMD_Interval(MinInterval);
292                 return true;
293         }
294         catch(IOException e){        
295             Message message=new Message();
296             message.what=3;
297             message.obj="socket连接失败!";
298             handler.sendMessage(message);
299             DeleteSocket();
300             SendCMD_WaitFlag = false; 
301             return false;            
302         }  
303     }
304     
305     void DeleteSocket(){
306          connectflag=false;
307          SendCMD_WaitFlag = false;
308          if(timer_TCPMonitor!=null){timer_TCPMonitor.cancel();timer_TCPMonitor=null;}
309          if(timer_SendCMD!=null){timer_SendCMD.cancel();timer_SendCMD=null;}
310          if(socket!=null) {    try{socket.close();}catch(IOException a){}}
311          if(thread2!=null) { thread2.interrupt(); thread2=null;}    //destroy和stop方法对于thread类对象来说都是不可取的 
312          if(thread1!=null) { thread1.interrupt(); thread1=null;}  //先暂停线程的运行,然后再解除线程映射
313     }
314      private void startConnected()     
315      {
316         //建立连接前进行初始化
317          DeleteSocket();
318          
319          thread2=new Thread(new Runnable() {    //创建一个没有标识符映射的子线程,因为创建socket是不能交给主线程来实现的
320              public void run() {
321                 try{
322                     socket=new Socket(IP,port);    //建立SOCKET连接
323                     socket.setSoTimeout(1000);     //在对socket输入流进行读操作的时候,会尝试进行1000ms的读取操作
324                     
325                     dataInputStream=new DataInputStream(socket.getInputStream());    //创建输入数据流
326                     dataOutputStream=new DataOutputStream(socket.getOutputStream());  //创建输出数据流
327                 }
328                 //catch(SocketTimeoutException e){}
329                 catch (IOException e) {
330                     Message message=new Message();
331                     message.what=3;
332                     message.obj="socket连接失败!";
333                     handler.sendMessage(message);        
334                     return;
335                 }
336                 
337                 //刚开始创建连接,进行一次连接测试,检查是否连接成功
338                 if(tcp_send_data(tcp_data_try,30)){  
339                     Message message=new Message();
340                     connectflag=true;
341                     message.what=4;
342                     handler.sendMessage(message);
343                 }
344                 else{
345                     return;
346                 }
347                 
348                 //--------------------------建立连接后进行初始化--------------------------//    
349                  //不断尝试读取接收缓冲区的数据    
350                 TryRead_ReceivedBuffer();                     
351                 //每隔1000ms获取一次温度值数据
352                 timer_SendCMD=new Timer();
353                 timer_SendCMD.schedule(new TimerTask() {           //定时器要执行的任务尽可能在以这种方式设定,以免出现麻烦
354                     @Override
355                     public void run() {                        
356                         tcp_send_data(tcp_data_SenT00,60);  //建议获取一次温度值后产生60ms发送间隔
357                     }
358                 },100,1000);                
359                 //循环发送特定数据包出去,根据反馈以确定是否断开连接,如果反馈到心跳包,则表明连接没有断开    
360                 NeedToCheckTCP = false;
361                 timer_TCPMonitor=new Timer();
362                 timer_TCPMonitor.schedule(new TimerTask() {           //定时器要执行的任务尽可能在以这种方式设定,以免出现麻烦
363                     @Override
364                     public void run() {                        
365                         Message message=new Message();
366                         if (NeedToCheckTCP)    //检查是否接收到心跳包
367                         {
368                             NeedToCheckTCP = false;
369                             if (heartbeat)
370                             {
371                                 heartbeat = false;
372                             }
373                             else
374                             {
375                                 DeleteSocket();                                
376                                 message.what=3;
377                                 message.obj="已断开连接,因为没有接收到心跳包!";                         
378                                 handler.sendMessage(message); 
379                             }
380                         }
381                         else        //请求接收者反馈心跳包,以确认连接是否出现异常 
382                         {
383                             NeedToCheckTCP = true;                                     
384                             tcp_send_data(tcp_data_try,25);   
385                         } 
386                     }
387                 },2000,2000);
388             }
389          });
390          thread2.start();
391      }
392      //更新UI这种操作必须由主线程来实现,否则会导致程序崩毁
393      private Handler handler = new Handler(){   
394          @Override
395          public void  handleMessage(Message msg){
396              switch(msg.what){
397                  case 1:             
398                      if(temperature[msg.arg1]<0){
399                          tv_temperature[msg.arg1].setText(Integer.toString(temperature[msg.arg1] / 10) + "." + Integer.toString((temperature[msg.arg1] % 10)*(-1)) + "℃");    
400                      }
401                      else{
402                          tv_temperature[msg.arg1].setText("+"+Integer.toString(temperature[msg.arg1] / 10) + "." + Integer.toString((temperature[msg.arg1] % 10)) + "℃");    
403                      }
404                      notice1.setText(msg.obj.toString()); 
405                      break;
406                  case 2:
407 
408                     break;
409                  case 3:
410                      light00.setEnabled(false);
411                     light01.setEnabled(false);
412                     light02.setEnabled(false);
413                     notice1.setText(msg.obj.toString()); 
414                     socketstate.setText(" 未连接!");
415                     break;
416                  case 4:
417                      notice1.setText("socket连接成功!");
418                      socketstate.setText(" 已连接!");
419                     light00.setEnabled(true);
420                     light01.setEnabled(true);
421                     light02.setEnabled(true);
422                     break;
423                  case 5:
424                      light00.setEnabled(false);
42

以上是关于局域网控制系统-上位机-Android手机的主要内容,如果未能解决你的问题,请参考以下文章

基于51设计的宠物防丢系统(蓝牙+Android上位机)

开源应用QT—TCP网络上位机的设计

家居环境监測系统设计(PC上位机版)(手机APP版待定)

5-网络芯片CH395Q学习开发-模块使用Socket0作为TCP客户端和电脑上位机TCP服务器局域网通信

新版H7-TOOL开始支持外网控制,用户可以在任何地方使用TOOL上位机访问处于外网其它地方的TOOL,展示外网远程控制H7-TOOL脱机下载效果展示

智能小车七《上位机android》