赞
踩
本项目使用工厂模式来编写代码,其中包括指令工厂和设备工厂,使用工厂模式的目的是为了让各模块代码更加独立,并且让C语言具有所谓的面向对象的属性;
本项目使用树莓派作为主控芯片,开发环境选择ubuntu下的Linux,通过使用交叉编译工具链,将x86架构下的代码,交叉编译成为arm架构下可执行程序,置于树莓派中;
控制方案采用socket网络控制线程和串口控制线程,其中串口控制使用的是LD3320语音模块,通过对该模块的二次开发,使其成为能够在特定语音环境下向串口输出特定的字符串,与树莓派通过串口进行通信,在树莓派获得LD3320发送的数据后经过相应的处理,来对设备进行控制;socket网络控制采用TCP协议,通过IP地址和端口号与树莓派建立连接,通过向树莓派发送数据,树莓派接收到相应数据之后进行处理,实现对设备的控制;
为了实现可以使用Android手机进行控制,在eclipse中使用java开发手机app,利用java的socket类实现手机和服务端相连,通过按钮发送特定的字符串到服务端,服务端接收到字符串,解析字符串并调用相关函数对设备进行操作;
指令工程头文件:inputCommand.h
#include <stdio.h> #include <wiringPi.h> #include <wiringSerial.h> #include <unistd.h> #include<stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include<arpa/inet.h> #include <netinet/in.h> #include<string.h> #include<pthread.h> struct InputCommand{ char commandName[128]; //命令控制名(串口控制/语音控制) char deviceName[128]; //用于调用open函数传递设备名称 char command[32]; //获得命令后存放于command中 int (*init)(struct InputCommand *device ,char * ipAddress,char *port); //对串口和socket进行初始化的init()函数 int (*getCommand)(struct InputCommand *device); //通过串口和socket获取命令函数 int fd; //用于socket()返回的文件描述符 char port[12]; //用于socket连接时的端口号 char ipAddress[32]; //用于socket连接时的IP地址 char log[1024]; //用于记录命令记录 struct InputCommand *next; }; struct InputCommand *addVoiceIntoCommandLink(struct InputCommand *head); //将语音控制加入到指令工厂链表中,让main.c调用 struct InputCommand *addSocketIntoCommandLink(struct InputCommand *head); //将socket命令加入到指令链表中,好让main.c调用
设备工厂头文件 controlDevice.h
#include <stdio.h> #include <wiringPi.h> struct Devices{ char deviceName[128]; //设备名称 int status; //谁被当前状态 int pinNum; //设备连接到树莓派的引脚 int (*open)(int pinNum); //开启设备函数指针 int (*close)(int pinNum); //关闭设备函数指针 int (*deviceinit)(int pinNum); //初始化设备函数指针 int (*readStatus)(); //获取当前设备状态指针 int (*changeStatus)(int status,int pinNum); //改变当前设备状态函数指针 struct Devices* next; }; struct Devices *addBathRoomIntoLink(struct Devices *head); //将设备放入到设备工厂中,方便后面main函数调用 struct Devices *addBedRoomIntoLink(struct Devices *head); struct Devices *addlockIntoLink(struct Devices *head); struct Devices *addtoiletIntoLink(struct Devices *head); struct Devices *addFireIntoLink(struct Devices *head);
设备1源文件 :bathroom.c
#include "controlDevice.h" int bathRoomInit(int pinNum) //设备初始化函数 { pinMode(pinNum,OUTPUT); //配置引脚为输出模式 digitalWrite(pinNum,HIGH); //初始化状态 return 0; } int bathRoomopen(int pinNum) //开启设备函数 { digitalWrite(pinNum,LOW); //将引脚置低 return 0; } int bathRoomClose(int pinNum) //关闭设备函数 { digitalWrite(pinNum,HIGH); return 0; } int bathroomchange(int status,int pinNum) //改变设备状态函数 { return 0; } struct Devices bathRoom = { .pinNum = 22, //设备引脚为22 .deviceName = "bathRoomLight", //设备名称 .deviceinit = bathRoomInit, //为设备初始化函数指针赋值 .open = bathRoomopen, //设备开启函数指针 .close = bathRoomClose, //设备关闭函数指针 .changeStatus = bathroomchange //设备状态改变函数指针 .next = NULL; }; struct Devices *addBathRoomIntoLink(struct Devices *head) //将设备放入链表函数实现 { if(head == NULL){ head = &bathRoom; }else{ bathRoom.next = head; head = &bathRoom; } return head; }
设备2源文件:bedroom.c
#include "controlDevice.h" int bedRoomInit(int pinNum) //设备初始化函数 { pinMode(pinNum,OUTPUT); digitalWrite(pinNum,HIGH); return 0; } int bedRoomopen(int pinNum) //开启设备函数 { digitalWrite(pinNum,LOW); return 0; } int bedRoomClose(int pinNum) //关闭设备函数 { digitalWrite(pinNum,HIGH); return 0; } int bedroomchange(int status,int pinNum) //改变状态函数 { return 0; } struct Devices bedRoom = { .pinNum = 23, //连接到树莓派的引脚 .deviceName = "bedRoomLight", //设备名 .deviceinit = bedRoomInit, //设备初始化 .open = bedRoomopen, //开启设备 .close = bedRoomClose, //关闭设备 .changeStatus = bedroomchange //改变设备状态 .next = NULL; }; struct Devices *addBedRoomIntoLink(struct Devices *head) //将设备放入到设备链表中 { if(head == NULL){ head = &bedRoom; }else{ bedRoom.next = head; head = &bedRoom; } return head; }
设备3源文件 fire.c
#include "controlDevice.h" int fireInit(int pinNum) //设备初始化 { pinMode(pinNum,INPUT); digitalWrite(pinNum,HIGH); } int fireReadStatus(int pinNum) //读取当前设备状态 { return digitalRead(pinNum); } struct Devices fire = { .pinNum = 4, //连接到树莓派引脚 .deviceName = "fireDetect", //设备名 .deviceinit = fireInit, //设备初始化 .readStatus = fireReadStatus //读取设备状态 .next = NULL; }; struct Devices *addFireIntoLink(struct Devices *head) //将设备放入到设备链表中 { if(head == NULL){ head = &fire; }else{ fire.next = head; head = &fire; } return head; }
设备4源文件:lock.c
#include "controlDevice.h" int lockInit(int pinNum) //初始化设备 { pinMode(pinNum,OUTPUT); digitalWrite(pinNum,HIGH); } int lockopen(int pinNum) //打开设备 { digitalWrite(pinNum,LOW); } int lockClose(int pinNum) //关闭设备 { digitalWrite(pinNum,HIGH); } int lockchange(int status,int pinNum) //改变设备状态 { } struct Devices lock = { .pinNum = 24, //连接到树莓派的引脚 .deviceName = "lock", //设备名称 .deviceinit = lockInit, //初始化设备 .open = lockopen, //打开设备 .close = lockClose, //关闭设备 .changeStatus = lockchange //改变设备状态 .next = NULL; }; struct Devices *addlockIntoLink(struct Devices *head) //将设备放入到设备链表中 { if(head == NULL){ head = &lock; }else{ lock.next = head; head = &lock; } return head; }
socket网络控制源文件 socketComand.c
#include "inputCommand.h" int socketInit(struct InputCommand* socketMsg ,char * ipAddress,char *port) //socket网络初始化,IP地址和端口号在结构体struct InputCommand* socketMsg中 { int s_fd; //socket()函数的文件描述符 int bind_ret; //bind()函数的返回值 struct sockaddr_in s_addr; //用于定义连接信息的结构体 memset(&s_addr,0,sizeof(struct sockaddr_in)); //将上述结构体先清空 s_fd = socket(AF_INET,SOCK_STREAM,0); //socket函数,定义网络协议 if(s_fd ==-1){ //判断是否创建成功 perror("socket"); exit(-1); } s_addr.sin_family = AF_INET; //选择协议簇为IPV4 s_addr.sin_port = htons(atoi(socketMsg->port)); //设置端口号,由于结构体中是字符串,所以需要转换整型,并且将字节序转换为网络字节序 inet_aton(socketMsg->ipAddress,&s_addr.sin_addr); //对结构体总的IP地址进行定义 bind_ret = bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in)); //绑定 if(bind_ret == -1){ //判断是否绑定成功 perror("bind"); exit(-1); } int listen_ret; listen_ret = listen(s_fd,10); //监听 if(listen_ret == -1){ //判断监听是否成功 perror("listen"); exit(-1); }else{ printf("listening....\n"); } socketMsg->fd = s_fd; //将socket函数返回的文件描述符赋值给socket命令的结构体中,方便之后应用 return s_fd; } int socketGetCommand(struct InputCommand* socketMsg) //socket获取命令函数 { struct sockaddr_in c_addr; memset(&c_addr,0,sizeof(struct sockaddr_in)); int c_addr_len = sizeof(struct sockaddr_in); int c_fd = accept(socketMsg->fd,(struct sockaddr *)&c_addr,&c_addr_len); //接受完成三次握手的连接 if(c_fd == -1){ //判断是否接受成功 perror("accept"); exit(-1); } printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr)); //read memset(socketMsg->command,'\0',sizeof(socketMsg->command)); //将结构体中的命令清空,防止上一次的命令影响下一次命令 int nread = read(c_fd,socketMsg->command,sizeof(socketMsg->command)); //读取信息 if(nread ==-1){ printf("read failure\n"); }else if(nread >0){ printf("read from client %d byte,context:%s",nread,sizeof(socketMsg->command)); //打印信息 }else{ printf("client quit!\n"); } return nread; } struct InputCommand socketControl = { //初始化socket命令结构体 .commandName = "socketServer", //命令名称 .command = {'\0'}, //调用getCommand函数得到的命令赋值给command .ipAddress = "192.168.43.80", //树莓派IP地址 .port = "8088", //端口号 .init = socketInit, //socket初始化函数 .getCommand = socketGetCommand, //获取指令函数 .log = {'\0'}, //命令记录 .next = NULL }; struct InputCommand *addSocketIntoCommandLink(struct InputCommand *head) //将指令放入到指令工厂中 { if(head == NULL){ head = &socketControl; }else{ socketControl.next = head; head = &socketControl; } }
语音指令源文件voiceControl.c
#include "inputCommand.h" int voiceInit(struct InputCommand* voice ,char * ipAddress,char *port) //语音控制初始化 { int fd; //串口打开文件描述符 if((fd = serialOpen(voice->deviceName,9600)) == -1){ //打开串口 exit(-1); } voice->fd = fd; //将文件描述符赋值到语音控制结构体中的fd return fd; } int voiceGetCommand(struct InputCommand* voice) //语音获取命令函数 { int nread = 0; memset(voice->command,'\0',sizeof(voice->command)); //这里将结构体中的命令清除是防止上一次的命令遗留,影响下一次命令 nread = read(voice->fd,voice->command,sizeof(voice->command)); //读取命令 return nread; } struct InputCommand voiceControl = { .commandName = "voiceControl", //命令名 .command = {'\0'}, //调用getCommand函数获取的指令存放于这 .deviceName = "/dev/ttyAMA0", //调用open打开串口是需要用的串口文件路径 .init = voiceInit, //串口初始化函数 .getCommand = voiceGetCommand, //获取命令函数 .log = {'\0'}, //命令记录 .next = NULL }; struct InputCommand *addVoiceIntoCommandLink(struct InputCommand *head) //将命令放入到指令工厂中 { if(head == NULL){ head = &voiceControl; }else{ voiceControl.next = head; head = &voiceControl; } }
主函数main.c
#include "controlDevice.h" #include "inputCommand.h" #include <string.h> struct Devices *deviceHead = NULL; //因为函数中会用到这些变量,而且使用的是多线程,尽量避免传参,因此使用全局变量 struct InputCommand *commandHead = NULL; struct InputCommand *socketHandler = NULL; int c_fd; struct Devices *findDeviceInLink(char *name,struct Devices *head) //根据设备名从设备工厂链表中找到对应设备 { if(head == NULL){ printf("the link is empty\n"); return NULL; } while(head != NULL){ if(strcmp(head->deviceName,name)==0){ return head; } head = head->next; } return NULL; } struct InputCommand *findCommandDeviceInLink(char *name,struct InputCommand *head) //从命令工厂中找到对应命令 { if(head == NULL){ printf("the link is empty\n"); return NULL; } while(head != NULL){ if(strcmp(head->commandName,name)==0){ return head; } head = head->next; } return NULL; } void controlDeviceDoCommand(char *command) //语音线程和socket线程在接收到客户端的命令的时候调用这个函数,会对设备进行操作 { if(strstr(command,"bath") != NULL){ //判断是否为bathroom的命令 struct Devices *BathRoom = findDeviceInLink("bathRoomLight",deviceHead); //在设备工厂链表中找到该设备 BathRoom->deviceinit(BathRoom->pinNum); //初始化设备 if(strstr(command,"open") != NULL){ //判断获得的指令是不是开 BathRoom->open(BathRoom->pinNum); //如果是开就调用设备open函数指针 }else if(strstr(command,"close") != NULL){ BathRoom->close(BathRoom->pinNum); //如果是关则调用设备close函数指针 } }else if(strstr(command,"bed") != NULL){ //bedroom struct Devices *BedRoom = findDeviceInLink("bedRoomLight",deviceHead); BedRoom->deviceinit(BedRoom->pinNum); //init device; if(strstr(command,"open") != NULL){ //open command BedRoom->open(BedRoom->pinNum); }else if(strstr(command,"close") != NULL){ //close command BedRoom->close(BedRoom->pinNum); } }else if(strstr(command,"lock") != NULL){ //bedroom struct Devices *Lock = findDeviceInLink("lock",deviceHead); Lock->deviceinit(Lock->pinNum); //init device; if(strstr(command,"open") != NULL){ //open command Lock->open(Lock->pinNum); }else if(strstr(command,"close") != NULL){ //close command Lock->close(Lock->pinNum); } }else{ //如果收到的指令并没有对应的设备,则打印信息 printf("no such device\n"); } } void *voice_threadFunc(void *data) //语音线程函数 { struct InputCommand *voiceHandler = NULL; int nread; voiceHandler = findCommandDeviceInLink("voiceControl",commandHead); //在指令工厂中寻找语音控制指令 if(voiceHandler == NULL){ //判断是否找到命令结构体 printf("find voiceHandler error\n"); pthread_exit(NULL); }else{ if(voiceHandler->init(voiceHandler,NULL,NULL)<0){ //找到结构体后对命令进行初始化 printf("voice init error\n"); pthread_exit(NULL); //初始化不成功退出线程 }else{ printf("%s init success\n",voiceHandler->commandName); //调试信息 } while(1){ //为了能够一直读信息使用死循环 nread = voiceHandler->getCommand(voiceHandler); //读取指令 if(nread == 0){ printf("no data from voice\n"); }else{ printf("get command:%s\n",voiceHandler->command); //打印读取的信息用于调试 controlDeviceDoCommand(voiceHandler->command); //获取到命令后调用控制设备的函数 } } } } void * socketReadFunc(void *data) { while(1){ //为了让socket能够持续读取加一个死循环 memset(socketHandler->command,'\0',sizeof(socketHandler->command)); int nread = read(c_fd,socketHandler->command,sizeof(socketHandler->command)); if(nread == 0){ printf("no data from voice\n"); }else if(nread<0){ printf("socket read error\n"); pthread_exit(NULL); }else{ printf("get command:%s\n",socketHandler->command); controlDeviceDoCommand(socketHandler->command); //获取到客户端的命令之后调用处理函数 } } } void *socket_threadFunc(void *data) //socket网络命令控制线程 { struct sockaddr_in c_addr; memset(&c_addr,0,sizeof(struct sockaddr_in)); int c_addr_len = sizeof(struct sockaddr_in); pthread_t socketRead; //socket读信息线程 socketHandler = findCommandDeviceInLink("socketServer",commandHead); //在指令链表中按照指令明寻找到对应的命令 if(socketHandler == NULL){ //判断是否找到socket命令 printf("find socketHandler error\n"); pthread_exit(NULL); }else{ printf("%s init success\n",socketHandler->commandName); //打印读取信息进行调试 } int s_fd = socketHandler->init(socketHandler,NULL,NULL); //初始化命令 while(1){ c_fd = accept(socketHandler->fd,(struct sockaddr *)&c_addr,&c_addr_len); //获取完成三次握手的连接 pthread_create(&socketRead,NULL,socketReadFunc,NULL); //线程读取信息函数创建 } } int main() { if(wiringPiSetup() == -1){ return -1; } pthread_t voice_thread; pthread_t socket_thread; pthread_t camera_thread; pthread_t fire_thread; char name[128]; deviceHead = addBathRoomIntoLink(deviceHead); //添加设备进设备工厂链表 deviceHead = addBedRoomIntoLink(deviceHead); deviceHead = addtoiletIntoLink(deviceHead); deviceHead = addlockIntoLink(deviceHead); deviceHead = addFireIntoLink(deviceHead); commandHead = addVoiceIntoCommandLink(commandHead); //添加指令进指令工厂链表 commandHead = addSocketIntoCommandLink(commandHead); pthread_create(&voice_thread,NULL,voice_threadFunc,NULL); //创建语音控制线程 pthread_create(&socket_thread,NULL,socket_threadFunc,NULL); //创建网络控制线程 pthread_join(voice_thread,NULL); //线程等待 pthread_join(socket_thread,NULL); return 0; }
使用Qt实现的串口调试助手,用于串口控制设备
界面布局:
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QSerialPort> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); bool getPortInfo(); //设置串口信息,返回是否打开串口 private slots: void on_openButton_clicked(); //串口开关槽函数 void on_sendButton_clicked(); //发送按钮槽函数 void on_SerialPoirtReadyRead(); //串口接收数据槽函数 private: Ui::Widget *ui; bool buttonStatus; //定义打开按钮状态 QString m_PortName; //定义端口名字 QString m_Baudrate; //定义波特率 QString m_databit; //定义数据位 QString m_checkbit; //定义校验位 QString m_stop; //定义停止位 QSerialPort m_serialPort; //定义串口 }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" #include <QSerialPortInfo> #include <QList> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); buttonStatus = false; ui->sendButton->setEnabled(false); //当串口是关闭状态时发送按钮不能点击 QList<QSerialPortInfo>ListPort =QSerialPortInfo::availablePorts(); //将可用的串口设置为List int cnt =ListPort.count(); //统计有多少个可用的串口 for(int i = 0;i<cnt;i++){ ui->portBox->addItem(ListPort.at(i).portName()); //将串口智能添加到portBox中 } //接收区数据不能认为输入 ui->receive->setEnabled(false); connect(&m_serialPort,SIGNAL(readyRead()),this,SLOT(on_SerialPoirtReadyRead())); //清空接收区数据 connect(ui->cleanreceive,&QPushButton::clicked,[=](){ ui->receive->clear(); }); //清空发送区数据 connect(ui->cleansend,&QPushButton::clicked,[=](){ ui->send->clear(); }); } Widget::~Widget() { delete ui; } bool Widget::getPortInfo(){ //获取串口配置 m_PortName = ui->portBox->currentText(); m_Baudrate = ui->baudBox->currentText(); m_databit = ui->dataBit->currentText(); m_checkbit = ui->checkBit->currentText(); m_stop = ui->stopBit->currentText(); //设置串口配置 m_serialPort.setPortName(m_PortName); //设置串口 if(m_Baudrate == "9600"){ //ui界面中波特率是字符串形式,所以要进行判断,然后在设置的时候设置成int形式 m_serialPort.setBaudRate(9600); }else if(m_Baudrate == "19200"){ m_serialPort.setBaudRate(19200); }else if(m_Baudrate == "115200"){ m_serialPort.setBaudRate(115200); } if(m_databit == "5"){ //设置数据位 m_serialPort.setDataBits(QSerialPort::Data5); }else if(m_databit == "6"){ m_serialPort.setDataBits(QSerialPort::Data6); }else if(m_databit == "7"){ m_serialPort.setDataBits(QSerialPort::Data7); }else if(m_databit == "8"){ m_serialPort.setDataBits(QSerialPort::Data8); } if(m_checkbit == "None"){ //设置校验位 m_serialPort.setParity(QSerialPort::NoParity); }else if(m_checkbit == "Odd"){ m_serialPort.setParity(QSerialPort::OddParity); }else if(m_checkbit == "Even"){ m_serialPort.setParity(QSerialPort::EvenParity); } if(m_stop == "1"){ //设置停止位 m_serialPort.setStopBits(QSerialPort::OneStop); }else if(m_stop == "2"){ m_serialPort.setStopBits(QSerialPort::TwoStop); } m_serialPort.open(QSerialPort::ReadWrite); return m_serialPort.isOpen(); } void Widget::on_openButton_clicked() //打开串口槽函数 { if(buttonStatus == true){ //串口助手处于打开状态时按下按钮 m_serialPort.close(); ui->openButton->setText("打开"); buttonStatus = false; ui->baudBox->setEnabled(true); //因为处于关闭状态所以将设置使能 ui->dataBit->setEnabled(true); ui->portBox->setEnabled(true); ui->checkBit->setEnabled(true); ui->stopBit->setEnabled(true); ui->sendButton->setEnabled(false); }else{ //串口助手处于关闭状态时按下按钮 if(getPortInfo() == true){ ui->openButton->setText("断开"); buttonStatus = true; ui->baudBox->setEnabled(false); //因为处于开启状态所以将设置失能 ui->dataBit->setEnabled(false); ui->portBox->setEnabled(false); ui->checkBit->setEnabled(false); ui->stopBit->setEnabled(false); ui->sendButton->setEnabled(true); }else{ buttonStatus = false; //设置按钮状态为关闭 } } } void Widget::on_sendButton_clicked() //发送数据槽函数 { if(buttonStatus == true){ //当串口是打开状态 m_serialPort.write(ui->send->toPlainText().toStdString().c_str()); //转换成字符串指针 } } void Widget::on_SerialPoirtReadyRead() //接收数据槽函数 { if(buttonStatus == true){ //当串口是打开状态 QByteArray recvData = m_serialPort.readAll(); ui->receive->append(QString(recvData)); //追加到之前的信息之后防止之前的信息被覆盖掉 } }
使用JAVA在eclipse中创建Android程序实现手机控制:
监控使用的是mjpg-stream,利用花生壳,对其实现了一个内外那个穿透,让外网可以访问到我的局域网;
UI界面布局:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/abc" tools:context=".MainActivity" > <WebView //网页,用于打开监控界面 android:id="@+id/wb" android:layout_height="650dp" android:layout_width="match_parent" android:layout_marginTop="10dp" /> <LinearLayout //线性布局按钮 android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="30dp" android:orientation="vertical" android:layout_centerHorizontal="true" > <LinearLayout android:layout_width="match_parent" android:id="@+id/openbutton" android:layout_height="80dp" android:layout_weight="1" android:orientation="horizontal" android:layout_centerHorizontal="true" > <Button android:id="@+id/bedopen" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="sendMes" //按钮点击时的函数,类似于Qt中的信号 android:text="开卧室灯" /> <Button android:id="@+id/bathopen" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="sendMes" android:text="开卫生间灯" /> <Button android:id="@+id/lockopen" android:layout_weight="1" android:layout_width="wrap_content" android:onClick="sendMes" android:layout_height="wrap_content" android:text="开厨房灯" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_below="@id/openbutton" android:layout_height="80dp" android:layout_weight="1" android:orientation="horizontal" android:layout_centerInParent="true" > <Button android:id="@+id/bedclose" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="sendMes" android:text="关卧室灯" /> <Button android:id="@+id/bathclose" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="sendMes" android:text="关卫生间灯" /> <Button android:id="@+id/lockclose" android:layout_weight="1" android:layout_width="wrap_content" android:onClick="sendMes" android:layout_height="wrap_content" android:text="关厨房灯" /> </LinearLayout> </LinearLayout> </RelativeLayout>
MainAcitvity.java
package com.example.caohai; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.webkit.WebView; import android.webkit.WebViewClient; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WebView wb = (WebView) findViewById(R.id.wb); //创建的网页访问,使用网页控件需要取AndroidManifest.xml中把使用网络权限打开 wb.loadUrl("http://4d1842z006.zicp.vip"); //设置网页访问的内容 wb.setWebViewClient(new WebViewClient()); //防止网页先进入默认网址 } public void sendMesHandler(final String deviceCommand){ //封装的向服务端发送信息的函数 new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Socket client; try { client = new Socket("192.168.43.80",8088); OutputStream out = client.getOutputStream(); out.write(deviceCommand.getBytes()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }){}.start(); } public void sendMes(View V){ switch(V.getId()){ //不同按钮按下之后对应的发送命令处理函数 case R.id.bathclose : sendMesHandler("bathclose"); break; case R.id.bathopen: sendMesHandler("bathopen"); break; case R.id.bedclose: sendMesHandler("bedclose"); break; case R.id.bedopen: sendMesHandler("bedopen"); break; case R.id.lockclose: sendMesHandler("lockclose"); break; case R.id.lockopen: sendMesHandler("lockopen"); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。