安卓开发(APP)之智能家电案例教程

智能家电工具介绍与客户端开发:

此文章教程内容:
用安卓手机的APP客户端控制智能家电实现的小案例
本文章所需工具在文章末尾,请君自取,所用工具Android studio。
在这里插入图片描述

家居模拟器程序介绍 本程序实现了客厅、卧室、厨房三个房间的智能设备,包括:光亮传感器、LED灯、温度传感器、风扇等。
本程序模拟现在比较流程的智能设备,能够自动接入WIFI。通过手机、平板等安装的APP,自动发现这些智能设备。智能设备既可以自主广播数据(定时或者自身状态改变),也可以根据请求返回设备的状态。例如:光亮传感器,当光线亮度发生变化时会自动广播自己的当前状态。而温度传感器,则会每隔10秒钟自动广播自己的当前状态。而风扇和LED灯,既可以通过模拟程序控制,也可以通过手机和平板控制。
程序的使用: 运行程序后,点击“启动设备”按钮,启动TCP服务器。 手机、平板通过TCP连接到模拟程序,即可进行通信。 通信协议:
(1)通信协议采用JSON格式
(2)模拟程序广播的数据格式:[{“Device”: “D0001”, “Value”: “50”,
“Value2”: “xx”},> …]。其中,Device为设备编号,D001代表光亮传感器,D0002代表LED灯,D0003代表温度传感器,D0004代表风扇。Value、Value1表示设备状态值。
(3)模拟程序接收的数据格式:[{“Device”: “D0001”, “Value”: “50”}, {“Device”:
“D0001”},
…]。如果存在Value、Value1属性,则表示设置指定的设备状态。如果不存在Value、Value1属性,则表示获取指定设备的状态。
(4)发现设备的数据格式:[]。即可返回智能设备的信息。

此处的智能设备有灯光,厨房的风扇,还有光线传感器,温度
点击启动设备即可启动,现在智能家居等待着客户端的连接,连接成功就会显示接收到某个客户端以及受到客户端发来的消息

客户端测试工具:

在这里插入图片描述
此客户端的协议类型默认为:TCP Client
远程主机默认为分配给智能家电的ip地址,或者用本地ip也可,即127.0.0.1
连接的智能家电的端口为1981,然后点击连接,发送[]\r\n
上面的智能家电显示客户端发送 “[]” 即可返回智能家电的设备信息
\r\n代表的是换行的意思,此客户端也默认发送消息换行
在这里插入图片描述
Device代表的是id号码
type代表设备的类型
value代表的是设备的状态,比如风扇的开关,空调的温度,
valuel代表的是辅助状态,因为空调可以具有温度也可以具有湿度,所以只能家居具有多种状态

下面在eclipse中采用socket的方式建立与智能家电的连接

实现代码(步骤中有有正确的解释):
i


```java
mport java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class TcpClient {
	public static void main(String[] args) {
		try {
//			采用socket建立链接,连接的IP为本地连接
//			用localhost或者127.0.0.1的本地IP地址,端口号为1981
			Socket socket = new Socket("127.0.0.1",1981);
//			读取智能家电传送来的json信息
			BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//			将信息写入到智能家电
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//			采用线程休眠,在读取之后休眠3秒钟
			Thread.sleep(3000);
//			智能家电提示用[]\r\n与其建立连接,此处将其写入
			writer.write("[]\r\n");
//			采用每次的写入进行一次刷新
			writer.flush();
//			刷新一次休眠0.5秒钟
			Thread.sleep(500);
//			将数据的每一行读取出来放到控制台进行显示
			String line = reader.readLine();
			System.out.println(line);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

在这里插入图片描述

举个列子,控制灯泡的打开;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;

public class TcpClient {
	public static void main(String[] args) {
		try {
//			采用socket建立链接,连接的IP为本地连接
//			用localhost或者127.0.0.1的本地IP地址,端口号为1981
			Socket socket = new Socket("127.0.0.1",1981);
//			读取智能家电传送来的json信息
			BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//			将信息写入到智能家电
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//			采用线程休眠,在读取之后休眠3秒钟
			Thread.sleep(3000);
//          向智能家电传入json数据来控制灯的开启(on:开启;off:关闭;)   
			writer.write("[{\"Device\":\"D0002\",\"Value\":\"on\"}]\r\n");
			writer.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

接下来是在Android studio中画开关的图纸,布局采用的是线性布局

在这里插入图片描述
在这里插入图片描述
实现代码:
在xml中:
首先修改xml文件中的Activity标签,将主页的设置为另外的Activity文件(如果此处新建Activity,否则不需要下面的步骤),然后申请网络权限,因为连接网络不是危险权限,所以不需要动态申请(此处很重要)
在这里插入图片描述
在这里插入图片描述
在java文件中的实现代码:
i

import androidx.appcompat.app.AppCompatActivity;

import android.gesture.GestureUtils;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class DeciceTestActivity extends AppCompatActivity implements View.OnClickListener {
    //    声明连接按钮的变量与输入输出流的变量
    private Button connectButton;
    private BufferedReader reader;
    private BufferedWriter writer;
    private Socket socket;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_decice_test);
//        绑定事件
        findViewById(R.id.connect_button).setOnClickListener(this);
        findViewById(R.id.disconnect_button).setOnClickListener(this);
        findViewById(R.id.find_device_button).setOnClickListener(this);
        findViewById(R.id.led_on_button).setOnClickListener(this);
        findViewById(R.id.led_off_button).setOnClickListener(this);
        findViewById(R.id.low_button).setOnClickListener(this);
        findViewById(R.id.middle_button).setOnClickListener(this);
        findViewById(R.id.height_button).setOnClickListener(this);
        findViewById(R.id.stop_space).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.connect_button) {
//            连接服务器
            connectToServer();

        } else if (v.getId() == R.id.disconnect_button) {
//            断开服务器
            disconnectFromServer();

        } else if (v.getId() == R.id.find_device_button) {
//            查询设备
            findDevices();
        } else if (v.getId() == R.id.led_on_button) {
//            开灯
            ledTurn("on");
        } else if (v.getId() == R.id.led_off_button) {
//            关灯
            ledTurn("off");
        }else if(v.getId() == R.id.low_button){
            lowspace();
        }else if(v.getId() == R.id.middle_button){
            midelespace();
        }else if(v.getId() == R.id.height_button){
            heighspace();
        }else if (v.getId() == R.id.stop_space){
            stopspace();
        }


    }

    //    连接到服务器
    private void connectToServer() {
        if (socket != null) {
            Toast.makeText(this, "已经连接到服务器", Toast.LENGTH_LONG).show();
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Socket socket = new Socket("192.168.1.9", 1981);
                    reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            String line;
                            try {
                                while ((line = reader.readLine()) != null) {
                                    Log.d("TEST", line);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d("TEST", "连接服务器错误");
                }
            }
        }).start();

    }

    //    断开连接
    private void disconnectFromServer() {
        if (socket == null) {
            Toast.makeText(this, "请连接服务器", Toast.LENGTH_LONG).show();
            return;
        }
        if (writer != null) {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //    查询智能设备
    private void findDevices() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    writer.write("[]\r\n");
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 设置LED开或者关
     */
    private void ledTurn(String status) {
        if (socket != null){
            Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
            return;
        }

        final String message = "[{\"Device\":\"D0002\",\"Value\":\""+ status +"\"}]\r\n";

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    writer.write(message);
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
//    风扇低速
    private void lowspace(){
        if (socket != null){
            Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
            return;
        }

        final String message = "[{\"Device\":\"D0004\",\"Type\":null,\"Value\":\"low\",\"Value1\":null}]\r\n";

        new  Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    writer.write(message);
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
//    风扇中速
    private void midelespace(){
        if (socket != null){
            Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
            return;
        }

        final String message = "[{\"Device\":\"D0004\",\"Type\":null,\"Value\":\"middle\",\"Value1\":null}]\r\n";

        new  Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    writer.write(message);
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
//    风扇高速
    private void heighspace(){
        if (socket != null){
            Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
            return;
        }

        final String message = "[{\"Device\":\"D0004\",\"Type\":null,\"Value\":\"high\",\"Value1\":null}]\r\n";

        new  Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    writer.write(message);
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

//    停止风扇
    private void stopspace(){
        if (socket != null){
            Toast.makeText(this,"还未连接服务器",Toast.LENGTH_LONG).show();
        }

        final String message = "[{\"Device\":\"D0004\",\"Type\":null,\"Value\":\"off\",\"Value1\":null}]\r\n";

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    writer.write(message);
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }).start();
    }

}

最后晒两张运行图:
在这里插入图片描述
在这里插入图片描述
文中所需工具链接:
链接:https://pan.baidu.com/s/1PNlswFcqDLwdGyQFik52uw
提取码:jdad

  • 7
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
其实这个制作没什么难度,就是几根线连接而已,主要就是程序。 如果手机控制的话是采用发送TCP数据包 具体附件说明文件压缩包文件里面有,控制的话是单片机通过无线路由器收到TCP数据包,然后去除协议头,获取其中的指令部分,然后进行判断。 连接电线的部分其实也很简单,单片机上面的P0.0 --- P0.7 是控制继电器的部分,只要依次接线到继电器上面的接口就行,电源部分:继电器上面有2电源接口,一个跳线,如果电源是1A的可以不用管那个跳线,直接连接到那一排最多的最两头,VCC和GND就行了; 如果是采用电脑控制也是用的TCP数据包,不会写程序的可以用易语言。 压缩包有手机的测试程序 不会写程序的话,推荐程序:电脑用:易语言 手机用: E4A 这两款软件都是采用中文编程。 完成这整个系统的制作需要用到以下几个模块电路: 1、单片机最小系统 随便找一个开发板或者自己动手按照上图搭建一个单片机最小系统就可以了,如上图所示,单片机的P0.0-P0.7分别接继电器模块的输入端子。 2、继电器模块 这种继电器模块在网上很容易就能买到,输入连接到单片机的P0.0-P0.7管脚便可以。 3、网络模块 这种ENC28J60网络模块在网上也很容易买到,用于实现整个智能家居控制系统进行联网。网络模块和单片机最小系统之间的接线如下 软件的修改方法: 各个电路模块之间接好线之后,还需要修改一下程序的参数才可以实现网络控制。程序在附件里,打开程序之后需要修改几个地方,具体见下图: 程序修改完后下载到单片机最小系统就可以了。 系统的测试: 电路连接好,程序修改下载好之后就可以对系统进行测试了,继电器输出部分可以接一些用电设备,比如灯等。测试方法可以用TCP\UDP测试工具,在附件里有提供。地址是根据自己修改 具体请见软件修改方法说明。 例如:LED1=1 表示P0^0 打开 LED1=0 表示P0^0 关闭 除此之外还可以用手机来实现控制,附件里面提供了手机端的测试软件E4A和程序,目前只支持安卓手机安装。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ctrl精

面试很多问题,积攒不容易

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值