ESP8266安卓TCP客户端开发
最近在玩8266模块,想让它在局域网控制下开关,所以就搞开发一个安卓客户端调试的工具
直接上步骤:
第一步新建一个空白的Activity

工程名字自己可以改

第二先在AndroidManifest.xml加入网络权限
<uses-permission android:name="android.permission.INTERNET"/>
|
第三修改界面布局(注意这个布局必须要支持约束布局才能正常使用不然会报错,可以使用AS3.6以上版本):
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
<Button android:id="@+id/btn_send" android:layout_width="0dp" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:text="@string/c" android:textColor="#F4F2F2" android:textSize="18sp" app:layout_constraintBottom_toTopOf="@+id/guideline2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline2" app:layout_constraintVertical_bias="0.52" />
<EditText android:id="@+id/et_port" android:layout_width="0dp" android:layout_height="wrap_content" android:autofillHints="" android:ems="10" android:hint="@string/s" android:inputType="number" app:layout_constraintBottom_toTopOf="@+id/guideline3" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.81" app:layout_constraintStart_toStartOf="@+id/guideline4" app:layout_constraintTop_toTopOf="@+id/guideline3" app:layout_constraintVertical_bias="0.555" />
<EditText android:id="@+id/et_ip" android:layout_width="0dp" android:layout_height="wrap_content" android:autofillHints="" android:ems="10" android:hint="@string/sip" android:inputType="date" app:layout_constraintBottom_toTopOf="@+id/guideline" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.81" app:layout_constraintStart_toStartOf="@+id/guideline4" app:layout_constraintTop_toTopOf="@+id/guideline" app:layout_constraintVertical_bias="0.555" />
<TextView android:id="@+id/textView" android:layout_width="0dp" android:layout_height="wrap_content" android:text="@string/ssip" android:textAlignment="textEnd" android:textSize="18sp" app:layout_constraintBottom_toTopOf="@+id/guideline" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline" />
<TextView android:id="@+id/textView2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="@string/sd" android:textAlignment="textEnd" android:textSize="18sp" app:layout_constraintBottom_toTopOf="@+id/guideline3" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintHorizontal_bias="0.51" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline3" app:layout_constraintVertical_bias="0.526" />
<androidx.constraintlayout.widget.Guideline android:id="@+id/guideline3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.3" />
<androidx.constraintlayout.widget.Guideline android:id="@+id/guideline5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.6" />
<androidx.constraintlayout.widget.Guideline android:id="@+id/guideline6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.9" />
<androidx.constraintlayout.widget.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.2" />
<androidx.constraintlayout.widget.Guideline android:id="@+id/guideline2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.75" />
<androidx.constraintlayout.widget.Guideline android:id="@+id/guideline4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.38" />
<androidx.constraintlayout.widget.Guideline android:id="@+id/guideline7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.5" />
<androidx.constraintlayout.widget.Guideline android:id="@+id/guideline8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.45" />
<Button android:id="@+id/btn_link" android:layout_width="0dp" android:layout_height="wrap_content" android:background="#16E6CE" android:text="@string/contenct" android:textColor="#F4EFEF" android:textSize="18sp" app:layout_constraintBottom_toTopOf="@+id/guideline8" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline8" />
<EditText android:id="@+id/et_data" android:layout_width="255dp" android:layout_height="48dp" android:autofillHints="" android:ems="10" android:hint="@string/plesdata" android:inputType="date|text" app:layout_constraintBottom_toTopOf="@+id/guideline5" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline5" app:layout_constraintVertical_bias="0.446" tools:ignore="LabelFor" />
<TextView android:id="@+id/tv_sendata" android:layout_width="0dp" android:layout_height="wrap_content" android:text="@string/senddata" android:textAlignment="textEnd" android:textSize="18sp" app:layout_constraintBottom_toTopOf="@+id/guideline5" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline5" />
<TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tcp" app:layout_constraintBottom_toTopOf="@+id/guideline6" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline6" />
</androidx.constraintlayout.widget.ConstraintLayout>
|

第四新建SendAsyncTask.java文件
package com.kizai.projects.esp8266;
import android.os.AsyncTask;
import java.io.IOException; import java.io.PrintStream; import java.net.Socket;
import static com.kizai.projects.esp8266.MainActivity.ip; import static com.kizai.projects.esp8266.MainActivity.port;
public class SendAsyncTask extends AsyncTask<String, Void, Void> {
private static final String IP = ip; private static final int PORT = port;
@Override protected Void doInBackground(String... params) { String str = params[0]; try { Socket client = new Socket(IP, PORT); client.setSoTimeout(5000); PrintStream out = new PrintStream(client.getOutputStream()); out.print(str); out.flush(); out.close(); client.close(); } catch (IOException e) { e.printStackTrace(); } return null; } }
|
第五回到主活动代码MainActivity.java:
package com.kizai.projects.esp8266;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast;
import java.net.Socket;
public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static String ip, pport, sendData; public static int port; private EditText et_ip, et_port, et_data;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); }
private void initView() { Button btn_send = findViewById(R.id.btn_send); Button btn_link = findViewById(R.id.btn_link); et_ip = findViewById(R.id.et_ip); et_port = findViewById(R.id.et_port); et_data = findViewById(R.id.et_data);
btn_send.setOnClickListener(this); btn_link.setOnClickListener(this); }
@Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_link: if (et_port.length() != 0 && et_ip.length() != 0) { ip = et_ip.getText().toString().trim(); pport = et_port.getText().toString().trim(); port = Integer.parseInt(pport); String str = "o\n"; new SendAsyncTask().execute(str); Toast.makeText(getApplicationContext(), "如果看到ESP8266的灯闪烁两次就代表连接成功!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "请输入正确的ip和端口号!", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_send: sendData = et_data.getText().toString().trim(); if (!sendData.isEmpty()) { new SendAsyncTask().execute(sendData); } else { Toast.makeText(getApplicationContext(), "请输入数据!", Toast.LENGTH_SHORT).show(); } break; } } }
|
第六ESP8266 TCPServer服务端代码:
#include <ESP8266WiFi.h>
#define MAX_SRV_CLIENTS 2
#define DebugBegin(baud_rate) Serial.begin(baud_rate) #define DebugPrintln(message) Serial.println(message) #define DebugPrint(message) Serial.print(message) const char* ssid = "KIZAI-HOME"; const char* password = "700800900";
WiFiServer server(23);
WiFiClient serverClients[MAX_SRV_CLIENTS]; void setup() { DebugBegin(115200); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); DebugPrint("\nConnecting to "); DebugPrintln(ssid); uint8_t i = 0; while (WiFi.status() != WL_CONNECTED && i++ < 20) { delay(500); } if (i == 21) { DebugPrint("Could not connect to"); DebugPrintln(ssid); while (1) { delay(500); } } server.begin(); server.setNoDelay(true); DebugPrint("Ready! Use 'telnet "); DebugPrint(WiFi.localIP()); DebugPrintln(" 23' to connect"); } void loop() { uint8_t i; if (server.hasClient()) { for (i = 0; i < MAX_SRV_CLIENTS; i++) { if (!serverClients[i] || !serverClients[i].connected()) { if (serverClients[i]) { serverClients[i].stop(); } serverClients[i] = server.available(); DebugPrint("New client: "); DebugPrint(i); break; } } if (i == MAX_SRV_CLIENTS) { WiFiClient serverClient = server.available(); serverClient.stop(); DebugPrintln("Connection rejected "); } } for (i = 0; i < MAX_SRV_CLIENTS; i++) { if (serverClients[i] && serverClients[i].connected()) { if (serverClients[i].available()) { while (serverClients[i].available()) {
char data = serverClients[i].read(); Serial.print(data); switch(data){ case 'o': digitalWrite(LED_BUILTIN, LOW); delay(100); digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); delay(100); digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); break; } } } } } if (Serial.available()) { size_t len = Serial.available(); uint8_t sbuf[len]; Serial.readBytes(sbuf, len); for (i = 0; i < MAX_SRV_CLIENTS; i++) { if (serverClients[i] && serverClients[i].connected()) { serverClients[i].write(sbuf, len); delay(1); } } } }
void blink() { static long previousMillis = 0; static int currstate = 0;
if (millis() - previousMillis > 200) { previousMillis = millis(); currstate = 1 - currstate;
digitalWrite(LED_BUILTIN, currstate); } }
|
8266端口监视器:

第七现在运行软件(真机和虚拟机都可以实现连接:前提是连接在统一个局域网里面)

也可以看到串口监视器会有反应:New client:0o

测试发送数据:


看到串口监视器都是可以接收到数据的

希望这篇文章对你有所帮助,觉得还可以点赞收藏喔!也还可以点个关注,你们的支持是对我最大的鼓励!!!