【华为云IOT物联网论坛外部版主:中华小能能】
第0章 简介
大家好,在上上上期发布的教程中,教大家如何利用Android Studio开发出一款接入华为云物联网平台并调用相关API完成设备属性查询、设备命令下发等功能,那个是采用的MQTT协议借助华为云物联网平台完成数据收发,本次教程带大家完成一款基于TCP/IP协议的物联网安卓应用开发,实现TCP连接与数据收发,下一期将在此APP上进行修改,并配置ESP8266接入APP完成内网控制物联网设备、查看设备属性信息等功能,首先还是给大家先看一下APP的最终效果:
第1章 提前准备
一、Android Studio IDE(※确保模拟器网络功能正常或使用真机※)
二、网络调试助手
(下载地址/soft/194484.html)
第2章 详细步骤
一、 新建工程
二、 TCP服务
1、新建TCP服务
2、TCP服务功能代码补充
(1)导入可能需要的类:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Looper;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import .InetSocketAddress;
import .Socket;
import .SocketAddress;
(2)修改服务代码(可左右滑动)
public class TCPService extends Service { public static Socket socket;
public static PrintStream output;
boolean conn = false;
String ip="192.168.1.15";
String port="8087";
public TCPService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
MyThread myThread = new MyThread();
new Thread(myThread).start();
//********在最终应用时取消注释下行,用于动态改变的IP和端口的连接********
//ip=intent.getStringExtra("ipaddress");
//port=intent.getStringExtra("port");
//System.out.println("新的TCP连接,新的IP:"+intent.getStringExtra("ipaddress")+"新的端口号:"+intent.getStringExtra("port"));
//********可在其他activity中设置IP和端口号通过上面的方式进行获取******** return super.onStartCommand(intent, flags, startId);
return super.onStartCommand(intent, flags, startId);
}
//socket连接线程
class MyThread implements Runnable{
@Override
public void run(){
try {
socket = new Socket();
SocketAddress socAddress = new InetSocketAddress(ip ,Integer.valueOf(port));
try{
socket.connect(socAddress, 5000);
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("连接失败");
}
if(socket.isConnected())System.out.println("连接成功");
InputStream inputstream = socket.getInputStream();
/* 获取输出流 */
output = new PrintStream(socket.getOutputStream(), true, "utf-8");
conn = true;
byte buffer[] = new byte[100];//接收数组的长度
int len2 ;
String receiveData;
//非阻塞式连接
while(conn){
//接收网络数据
if( (len2 = inputstream.read(buffer)) != -1){
receiveData = new String(buffer, 0, len2);
Intent CMDintent = new Intent();
CMDintent.setAction("munication.data");
CMDintent.putExtra("data", buffer);//buffer为数组,receivedata为文本
sendBroadcast(CMDintent);
}else{
break;
}
}
output.close();
socket.close();
Looper.loop();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// Looper.prepare();
}
}
};
//发送方法((可以把参数改成Byte[]):
public static void send(final byte[] arr)
{
new Thread(new Runnable() {
public void run() {
if (socket.isConnected()) {
try {
output.write(arr);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
3、MainActivity中启动服务
(1) 导入可能需要的类
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
(2) 启动服务
Intentintent=newIntent(this,TCPService.class);
startService(intent);
(3)加入联网权限
在AndroidMainfest.xml文件中加入下面这句:
<uses-permission android:name="android.permission.INTERNET" />
4、打开TCP Service
打开网络调试助手
(1) 协议类型:“TCP Server”
(2) 本机地址:不做修改,并且在APP的TCPService中的IP地址要与此一致
(3) 端口选择:根据需要选择合适的端口,同样在APP的TCPService中的端口号要与此一致基本补充
(4)点击打开
5、运行APP
此时我们可以看到APP已经连接上了网络调试助手
三、 界面配置
四、手动输入IP与端口号进行连接
1.实现过程
为登陆按钮的ImageButton添加事件,获取IP地址和端口号输入框的值后启动连接,相比较于上一步的初始化连接测试,这次的IP地址和端口号是变化的,我们这使用putExtra方式将ip和端口号发送出去,在TCPService中接收
2.修改启动服务语句
此处我们将一开始测试的程序语句
Intent intent=new Intent(this,TCPService.class);
startService(intent);
改为
Intent intent = new Intent(this, TCPService.class);
intent.putExtra("ipaddress", ip);
intent.putExtra("port", port);
startService(intent);
3.添加到登陆按钮的事件代码中
4.在TCPService.java中接收IP和端口号,并启动新的连接
五、 数据的收发
1. 数据的接收
(1) 广播接收器
我们通过广播接收器进行数据接收,首先在MainActivity中新建一个接收器:
private class cmdReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
byte[] receive=intent.getByteArrayExtra("data");
System.out.println("接收到数据:"+recieveData);
}
}
(2)注册接收器
public cmdReceiver cmdReceiver;
cmdReceiver =new cmdReceiver();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("munication.data");
registerReceiver(cmdReceiver,intentFilter);
(3)网络调试助手进行数据发送
由于我们在TCPService中定义了接收数据格式为100字节,大家根据自己需要进行调整。
(4)接收处理
我们在广播接收器中读取接收的数据并显示:
2.数据发送
发送的时候我们可以调用TCPService.send(buff);方法,其中buff为字节数组,例如:
//发送十六进制数据
byte[] buff = {0x00,0x01,0x02,0x03};
TCPService.send(buff);
//发送字符串
String str=”FUNIOT is very fun”;
byte[] buffstr = str.getBytes();
TCPService.send(buffstr);
五、 结语
接下来我们就可以连接我们的设备,使用APP进行通信,完成数据上报或命令控制等其功能,关键代码已经在文章中给出,如果需要上述文章Android Studio的工程文件,在公众号“IOT趣制作”回复关键字“TCP基础应用”即可。