这个教程版本不够详细,请参考最新版安卓TCP助手Android studio教程分享:Android studio TCP网络调试助手应用开发(支持TCP Server与Client切换) 

------------------------------------

--请参考上面链接的最新版教程--

------------------------------------

第0章 简介

    大家好,在上上上期发布的教程中,教大家如何利用Android Studio开发出一款接入华为云物联网平台并调用相关API完成设备属性查询、设备命令下发等功能,那个是采用的MQTT协议借助华为云物联网平台完成数据收发,本次教程带大家完成一款基于TCP/IP协议的物联网安卓应用开发,实现TCP连接与数据收发,下一期将在此APP上进行修改,并配置ESP8266接入APP完成内网控制物联网设备、查看设备属性信息等功能,首先还是给大家先看一下APP的最终效果:

android studio tcp Android studio TCP教程_ide

第1章 提前准备

一、Android Studio IDE(※确保模拟器网络功能正常或使用真机※)

二、 网络调试助手

(下载地址https://www.pcsoft.com.cn/soft/194484.html)

第2章 详细步骤

一、 新建工程

android studio tcp Android studio TCP教程_android_02

android studio tcp Android studio TCP教程_android studio tcp_03

二、 TCP服务

1、 新建TCP服务

android studio tcp Android studio TCP教程_ide_04

android studio tcp Android studio TCP教程_TCP_05

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 java.net.InetSocketAddress;
import java.net.Socket;
import java.net.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("com.example.communication.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) 启动服务

Intent intent=new Intent(this,TCPService.class);
startService(intent);

 

android studio tcp Android studio TCP教程_android studio_06

(3) 加入联网权限

    在AndroidMainfest.xml文件中加入下面这句:

<uses-permission android:name="android.permission.INTERNET" />

 

android studio tcp Android studio TCP教程_android studio_07

4、 打开TCP Service

    打开网络调试助手

(1) 协议类型:“TCP Server”

(2) 本机地址:不做修改,并且在APP的TCPService中的IP地址要与此一致

(3) 端口选择:根据需要选择合适的端口,同样在APP的TCPService中的端口号要与此一致基本补充

(4)点击打开

android studio tcp Android studio TCP教程_android_08

5、 运行APP

此时我们可以看到APP已经连接上了网络调试助手

android studio tcp Android studio TCP教程_ide_09

三、 界面配置

android studio tcp Android studio TCP教程_ide_10

四、 手动输入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.添加到登陆按钮的事件代码中

android studio tcp Android studio TCP教程_android_11

4.在TCPService.java中接收IP和端口号,并启动新的连接

android studio tcp Android studio TCP教程_android_12

五、 数据的收发

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("com.example.communication.data");
registerReceiver(cmdReceiver,intentFilter);

(3)网络调试助手进行数据发送

由于我们在TCPService中定义了接收数据格式为100字节,大家根据自己需要进行调整。

android studio tcp Android studio TCP教程_android studio tcp_13

(4)接收处理

我们在广播接收器中读取接收的数据并显示:

android studio tcp Android studio TCP教程_android studio_14

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);

 

android studio tcp Android studio TCP教程_ide_15

五、 结语

    接下来我们就可以连接我们的设备,使用APP进行通信,完成数据上报或命令控制等其功能,关键代码已经在文章中给出,如果需要上述文章Android  Studio的工程文件,在公众号“IOT趣制作”回复关键字“TCP基础应用”即可。

android studio tcp Android studio TCP教程_android_16