【Android开发—智能家居系列】(四):UDP通信发送指令

简介:

思路回顾

【1】手机连接WIFI模块 
【2】UDP通信对WIFI模块发送指令,以和WIFI模块保持连接状态 
【3】UDP通信对WIFI模块发送指令,让其搜索可用的无线网,返回WIFI列表 
【4】发送指令,让WIFI模块接入指定路由 
【5】手机连接路由 
【6】发送指令,获得WIFI模块的动态IP地址

UDP通信线程类

package com.jczb.smartlife.common;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketException; import java.net.UnknownHostException; import android.os.Handler; import android.os.Message; import com.jczb.smartlife.common.Tool; public class GetInfoThread extends Thread { private Handler handler; private DatagramSocket socket; private int msgType; private final String IP = "255.255.255.255";//广播地址 private int PORT = 26000; /** * 48899端口:C32x系列的端口,用户可以用AT指令更改 * 49000端口:除C32x系列,其他WIFI模块的端口 * 1902端口:有人掌控宝系列产品的端口 */ private int targetPort = 49000 ; private boolean receive = true; /** * * @param handler 传入监听此线程的Handler * @param intMsg 传入监听的消息类型 */ public GetInfoThread(Handler handler,int msgType) { this.handler = handler; this.msgType=msgType; init(); } public void init(){ try { socket = new DatagramSocket(null); socket.setBroadcast(true); socket.setReuseAddress(true); socket.bind(new InetSocketAddress(PORT)); } catch (SocketException e) { e.printStackTrace(); sendErrorMsg("Search Thread init fail"); return; } } public void run() { if (socket == null) { return; } try { byte[] data = new byte[1024]; //创建一个空的DatagramPacket对象 DatagramPacket revPacket = new DatagramPacket(data, data.length); while (receive) { //服务端接收数据 socket.receive(revPacket); if(null!=handler){ byte[] realData = new byte[revPacket.getLength()]; System.arraycopy(data, 0, realData,0, realData.length); Message msg =handler.obtainMessage(msgType,realData); handler.sendMessage(msg); } } } catch (Exception e) { e.printStackTrace(); socket.close(); } } public void close() { if (socket == null) return; socket.close(); } private void sendErrorMsg(String info){ } /** * 发送数据 * @param msg */ public void sendMsg(byte[] msg) { if (socket != null) { try { System.out.println("targetPort------------------->"+targetPort); DatagramPacket sendPacket = new DatagramPacket(msg, msg.length, InetAddress.getByName(IP), targetPort); socket.send(sendPacket); } catch (UnknownHostException e) { e.printStackTrace(); System.out.println("发送失败"); } catch (IOException e) { e.printStackTrace(); System.out.println("发送失败"); } } } public void setReceive(boolean receive) { this.receive = receive; } public void setTargetPort(int targetPort) { this.targetPort = targetPort; } public void setMsgType(int msgType){ this.msgType=msgType; } } 

 

发送消息的线程类

/**
     * 发送消息的队列,每次发送数据时,只需要调用putMsg(byte[] data)方法
     * 
     * @author usr_liujinqi
     * 
     */
    private class SendMsgThread extends Thread { // 发送消息的队列 private Queue<byte[]> sendMsgQuene = new LinkedList<byte[]>(); // 是否发送消息 private boolean send = true; private GetInfoThread ss; public SendMsgThread(GetInfoThread ss) { this.ss = ss; } public synchronized void putMsg(byte[] msg) { // 唤醒线程 if (sendMsgQuene.size() == 0) notify(); sendMsgQuene.offer(msg); } public void run() { synchronized (this) { while (send) { // 当队列里的消息发送完毕后,线程等待 while (sendMsgQuene.size() > 0) { byte[] msg = sendMsgQuene.poll(); if (ss != null) ss.sendMsg(msg); } try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void setSend(boolean send) { this.send = send; } }

 

应用

【举例】发送搜索WIFI模块的指令

//1.用户获得温控器中WIFI模块的WIFI模块的IP地址,MAC地址,模块名称的指令    
    private final byte[] getInfoCode=new byte[]{(byte)0x48,0x46,0x2D,0x41,0x31,0x31,0x41,0x53,0x53,0x49,0x53,0x54,0x48,0x52,0x45,0x41,0x44}; public static final int REC_Module=0x04;//搜索WIFI模块的信息(包括IP、Mac、名称) //实例化一个线程,用户获得模块信息(IP,Mac,名称) //参数为监听为此线程的Handler,以及接收成功后,给Handler发送的消息类型 getInfoThread = new GetInfoThread(handler,Tool.REC_Module); getInfoThread.start(); //发送消息的线程 smt = new SendMsgThread(getInfoThread); smt.start(); //设置发送的目的端口号 getInfoThread.setTargetPort(Integer.parseInt("48899")); smt.putMsg(getInfoCode); 

 

WIFI模块在接收到指令后,就会回复信息,以下的Handler就是针对回复过来的信息进行解析处理等操作。

//处理消息的Handler
    private Handler handler= new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case Tool.REC_Module:// 解析接收到的数据
                //设置发送的目的端口号
                getInfoThread.setTargetPort(Integer.parseInt("48899")); getInfoThread.setMsgType(Tool.REC_OK); smt.putMsg(okCode); SetServer(); SetDHCP(); byte[] data = (byte[]) msg.obj; //将十进制的数据转化成十六进制数据 String strTemp= Tool.bytesToHexString(data); //将十六进制的字符串去掉空格之后进行解析 String strdecode=Tool.DecodeHex(strTemp.replace(" ", "")); //取出IP,Mac地址,模块名称 decodeIP(strdecode); Toast.makeText(ConnectWifiActivity.this, "获得WIFI模块名称成功!"+ModuleName, Toast.LENGTH_SHORT).show(); break; case Tool.REC_Server: byte[] dataServer = (byte[])msg.obj; //将十进制的数据转化成十六进制数据 String strServer= Tool.bytesToHexString(dataServer); if("2b 6f 6b 0d 0a 0d 0a ".equals(strServer)){ Toast.makeText(ConnectWifiActivity.this, "设置服务器成功!", Toast.LENGTH_SHORT).show(); } break; case Tool.REC_SSID: byte[] dataSSID=(byte[])msg.obj; Tool.bytesToHexString(dataSSID); decodeData(dataSSID); break; case Tool.REC_AT: byte[] dataID = (byte[]) msg.obj; //将十进制的数据转化成十六进制数据 String strTempID= Tool.bytesToHexString(dataID); //将十六进制的字符串去掉空格之后进行解析 String strdecodeID=Tool.DecodeHex(strTempID.replace(" ", "")); break; case Tool.REC_DHCP: byte[] dataDHCP = (byte[])msg.obj; //将十进制的数据转化成十六进制数据 String strDHCP= Tool.bytesToHexString(dataDHCP); if("2b 6f 6b 0d 0a 0d 0a ".equals(strDHCP)){ Toast.makeText(ConnectWifiActivity.this, "设置DHCP网络参数成功!", Toast.LENGTH_SHORT).show(); } break; default: byte[] data1 = (byte[]) msg.obj; //将十进制的数据转化成十六进制数据 String strTemp1= Tool.bytesToHexString(data1); Toast.makeText(ConnectWifiActivity.this, strTemp1, Toast.LENGTH_SHORT).show(); break; } } };

 

总结

  凡是需要对WIFI模块发送指令的,就需要用到上述的两个线程类,还有一个对返回信息进行处理的Handler。只是发送的指令的code不一样,如上述表示的是搜索WIFI模块的十六进制的指令。不管WIFI模块在AP模式下还是STA模式,通信的最开始步骤都是先搜索模块,然后获得它的IP和Mac之后,立即回复+ok指令,就可以保持连接状态。



    本文转自 一点点征服   博客园博客,原文链接:

http://www.cnblogs.com/ldq2016/p/6774195.html

,如需转载请自行联系原作者


相关文章
|
2天前
|
网络协议 算法 Java
【Java网络编程】网络编程概述、UDP通信(DatagramPacket 与 DatagramSocket)
【Java网络编程】网络编程概述、UDP通信(DatagramPacket 与 DatagramSocket)
15 3
|
2天前
|
Java Android开发
Android开发--Intent-filter属性详解
Android开发--Intent-filter属性详解
|
2天前
|
物联网 Java 开发工具
安卓应用开发:打造未来移动生活
【5月更文挑战第10天】 随着科技的飞速发展,智能手机已成为我们日常生活中不可或缺的一部分。作为智能手机市场的两大巨头,安卓和iOS分别占据了一定的市场份额。在这篇文章中,我们将重点关注安卓应用开发,探讨如何利用先进的技术和创新思维,为用户打造更加便捷、智能的移动生活。文章将涵盖安卓应用开发的基本概念、关键技术、以及未来发展趋势等方面的内容。
|
4天前
|
Java API 开发工具
java与Android开发入门指南
java与Android开发入门指南
11 0
|
5天前
|
Android开发 Kotlin
Kotlin开发Android之基础问题记录
Kotlin开发Android之基础问题记录
16 1
|
5天前
|
Java Android开发
Android开发@IntDef完美替代Enum
Android开发@IntDef完美替代Enum
13 0
|
6天前
|
Android开发
Android 盒子开发过程中遇到的问题及解决方法
Android 盒子开发过程中遇到的问题及解决方法
8 2
|
2月前
|
人工智能 搜索推荐 语音技术
未来智能家居技术的发展与应用前景
随着人工智能、物联网等技术的快速发展,智能家居正逐渐成为现代家庭生活的重要组成部分。本文将探讨未来智能家居技术的发展趋势,以及其在提升生活品质、节能环保等方面的广阔应用前景。
52 0
|
2月前
|
人工智能 搜索推荐 人机交互
未来智能家居技术的发展趋势与应用前景
当提到智能家居技术,我们往往会联想到便捷的生活方式和高效的能源利用。然而,未来智能家居技术的发展不仅仅局限于这些表面的便利,更涉及到对于人类生活的深刻改变和未来社会发展的巨大影响。本文将探讨未来智能家居技术的发展趋势以及其在日常生活、健康管理、能源节约等方面的应用前景,旨在带领读者了解智能家居技术的未来走向。
15 1
|
2月前
|
人工智能 监控 安全
未来智能家居技术的发展趋势与应用前景
随着人工智能和物联网技术的不断进步,智能家居已经成为现代生活中不可或缺的一部分。本文将探讨未来智能家居技术的发展趋势,以及其在日常生活中的广泛应用前景,为读者揭示智能家居领域的新趋势和可能性。
16 2