修改了ClientActivity全局可用、完成了通信协议

master
Tushida 2024-06-04 22:52:22 +08:00
parent 1ef6dc61b6
commit 9c4e5a9279
28 changed files with 655 additions and 1023 deletions

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="17" project-jdk-type="JavaSDK" />
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

View File

@ -1 +0,0 @@
WiFiDemo

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" /> <bytecodeTargetLevel target="17" />
</component> </component>
</project> </project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

View File

@ -4,9 +4,8 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Embedded JDK" /> <option name="gradleJvm" value="jbr-17" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />

View File

@ -18,7 +18,7 @@
</option> </option>
</component> </component>
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../../../.." vcs="Git" />
</component>
</project>

View File

@ -8,35 +8,32 @@ import android.os.Message;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
@SuppressLint("StaticFieldLeak")
public class ClientActivity extends AppCompatActivity { public class ClientActivity extends AppCompatActivity {
private static EditText msgET;
private static Button confirmBtn;
private static Button sendBtn;
private static ActionBar actionBar;
private static EditText ipET;
private EditText ipET; private static ImageView startRobot;
private EditText msgET;
private Button confirmBtn;
private Button sendBtn;
private ActionBar actionBar;
private Socket mSocket;
// private OutputStream mOutStream;
// private InputStream mInStream;
private SocketConnectThread socketConnectThread;
private StringBuffer stringBuffer = new StringBuffer();
private TextView msgTV;
private final String TAG="WifiDemoLogClientActivity"; private static StringBuffer stringBuffer = new StringBuffer();
private static TextView msgTV;
private static final String TAG="WifiDemoLogClientActivity";
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
public Handler handler = new Handler(Looper.myLooper()){ public static Handler handler = new Handler(Looper.myLooper()){
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
super.handleMessage(msg); super.handleMessage(msg);
@ -49,15 +46,13 @@ public class ClientActivity extends AppCompatActivity {
}; };
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client); setContentView(R.layout.activity_client);
actionBar = getSupportActionBar(); actionBar = getSupportActionBar();
assert actionBar != null; assert actionBar != null;
actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle("机器人控制"); actionBar.setTitle("机器人控制");
socketConnectThread = new SocketConnectThread();
initView(); initView();
setListener(); setListener();
} }
@ -68,104 +63,47 @@ public class ClientActivity extends AppCompatActivity {
sendBtn = findViewById(R.id.btn_send); sendBtn = findViewById(R.id.btn_send);
confirmBtn = findViewById(R.id.btn_confirm); confirmBtn = findViewById(R.id.btn_confirm);
msgTV = (TextView) findViewById(R.id.msgTV); msgTV = (TextView) findViewById(R.id.msgTV);
startRobot = (ImageView) findViewById(R.id.start_robot_iv);
} }
private void setListener() { private void setListener() {
sendBtn.setOnClickListener(new View.OnClickListener() { sendBtn.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if(mSocket==null) { if(!UPbotComm.getInstance().getConnectStatus()) {
Toast.makeText(ClientActivity.this, "未进行连接", Toast.LENGTH_SHORT).show(); Toast.makeText(ClientActivity.this, "连接失败无法发送", Toast.LENGTH_SHORT).show();
return; return;
} }
sendMessage(msgET.getText().toString()); UPbotComm.getInstance().sendMessage(msgET.getText().toString());
} }
}); });
confirmBtn.setOnClickListener(new View.OnClickListener() { confirmBtn.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
socketConnectThread.start(); if(!UPbotComm.getInstance().connect(ipET.getText().toString())) {
Toast.makeText(ClientActivity.this, "未进行连接", Toast.LENGTH_SHORT).show();
return;
}else{
Toast.makeText(ClientActivity.this, "连接成功", Toast.LENGTH_SHORT).show();
}
confirmBtn.setEnabled(false);//连接只点一次 confirmBtn.setEnabled(false);//连接只点一次
} }
}); });
} startRobot.setOnClickListener(new View.OnClickListener() {
/**
* 线
*/
class SocketConnectThread extends Thread{
public void run(){
try {
//指定ip地址和端口号
mSocket = new Socket(ipET.getText().toString(), 1989);
//获取输出流、输入流
// mOutStream = mSocket.getOutputStream();
// mInStream = mSocket.getInputStream();
} catch (Exception e) {
e.printStackTrace();
return;
}
startReader(mSocket);
}
}
/**
*
* @param msg
*/
public void sendMessage(final String msg) {
if (msg.length() == 0){
return;
}
new Thread() {
@Override @Override
public void run() { public void onClick(View view) {
try { byte start = 0x00;
DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream()); if(!UPbotComm.getInstance().getConnectStatus()) {
writer.writeUTF(msg); // 写一个UTF-8的信息 Toast.makeText(ClientActivity.this, "连接失败无法启动", Toast.LENGTH_SHORT).show();
} catch (IOException e) { return;
e.printStackTrace();
} }
byte[] result = SendMsg.sendCmdMsg(start);
UPbotComm.getInstance().sendMessage(result);
} }
}.start(); });
} }
/**
*
*/
private void startReader(final Socket socket) {
new Thread(){
@Override
public void run() {
DataInputStream reader;
try {
// 获取读取流
reader = new DataInputStream(socket.getInputStream());
while (true) {
// 读取数据
String msg = reader.readUTF();
Message message = new Message();
message.what = 1;
message.obj=msg;
handler.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
if(mSocket!=null){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
super.onDestroy(); super.onDestroy();
} }
} }

View File

@ -1,7 +1,4 @@
package com.example.wifidemo; package com.example.upbot;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.os.Bundle; import android.os.Bundle;
@ -14,12 +11,15 @@ import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
public class ClientActivity extends AppCompatActivity { public class InternetUtil extends AppCompatActivity {
private EditText ipET; private EditText ipET;
private EditText msgET; private EditText msgET;
@ -27,7 +27,7 @@ public class ClientActivity extends AppCompatActivity {
private Button sendBtn; private Button sendBtn;
private ActionBar actionBar; private ActionBar actionBar;
private Socket mSocket; private Socket mSocket;
// private OutputStream mOutStream; // private OutputStream mOutStream;
// private InputStream mInStream; // private InputStream mInStream;
private SocketConnectThread socketConnectThread; private SocketConnectThread socketConnectThread;
private StringBuffer stringBuffer = new StringBuffer(); private StringBuffer stringBuffer = new StringBuffer();
@ -75,7 +75,7 @@ public class ClientActivity extends AppCompatActivity {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if(mSocket==null) { if(mSocket==null) {
Toast.makeText(ClientActivity.this, "未进行连接", Toast.LENGTH_SHORT).show(); Toast.makeText(InternetUtil.this, "未进行连接", Toast.LENGTH_SHORT).show();
return; return;
} }
sendMessage(msgET.getText().toString()); sendMessage(msgET.getText().toString());

View File

@ -0,0 +1,12 @@
package com.example.upbot.MSG.CONF;
public class COORDINATE_CONF {
public int base_num;
public float x_coordinate;
public float y_coordinate;
public float z_coordinate;
}

View File

@ -0,0 +1,29 @@
package com.example.upbot.MSG;
public class Head {
private final byte flag = 0x5b;
private byte msg_id;
private byte length;
public byte getFlag() {
return flag;
}
public byte getLength() {
return length;
}
public byte getMsg_id() {
return msg_id;
}
public void setLength(byte length) {
this.length = length;
}
public void setMsg_id(byte msg_id) {
this.msg_id = msg_id;
}
}

View File

@ -0,0 +1,36 @@
package com.example.upbot.MSG;
public class MSG_CMD {
public static final byte START_ROBOT = 0x00;
// public static final String START_ROBOT = "0x00";
public static final byte START_NAVIGATION = 0x01;
// public static final String START_NAVIGATION = "0x01";
public static final byte START_COVER_CLIENT = 0x02;
// public static final String START_COVER_CLIENT = "0x02";
public static final byte START_COVER_SERVICE = 0x03;
// public static final String START_COVER_SERVICE = "0x03";
public static final byte START_CAMERA_ULTRASONIC = 0x04;
// public static final String START_CAMERA_ULTRASONIC = "0x04";
public static final byte BOUNDARY_SETTING = 0x05;
// public static final String BOUNDARY_SETTING = "0x05";
public static final byte MANUAL_CONTROL = 0x06;
// public static final String MANUAL_CONTROL = "0x06";
public static final byte CHARGING = 0x07;
// public static final String CHARGING = "0x07";
public static final byte STOP_MOWING = 0x08;
// public static final String STOP_MOWING = "0x08";
public static final byte PAUSE_MOWING = 0x09;
// public static final String PAUSE_MOWING = "0x09";
}

View File

@ -0,0 +1,23 @@
package com.example.upbot.MSG;
public class MSG_CONF {
public static final byte COORDINATE_CONF = 0x00;
// public static final String COORDINATE_CONF = "0x00";
public static final byte FREQUENCY_CONF = 0x01;
// public static final String FREQUENCY_CONF = "0x01";
public static final byte BATTERY_CONF = 0x02;
// public static final String BATTERY_CONF = "0x02";
public static final byte MAP_NUM_CONF = 0x03;
// public static final String MAP_NUM_CONF = "0x03";
public static final byte MAP_CORRECT_CONF = 0x04;
// public static final String MAP_CORRECT_CONF = "0x04";
public static final byte VIRTUAL_WALL_CONF = 0x05;
// public static final String VIRTUAL_WALL_CONF = "0x05";
}

View File

@ -0,0 +1,10 @@
package com.example.upbot.MSG;
public class MsgId {
public static final byte MSG_CMD = 0x01;
// public static final String MSG_CMD = "0x01";
public static final byte MSG_CONF = 0x02;
// public static final String MSG_CONF = "0x02";
}

View File

@ -0,0 +1,123 @@
package com.example.upbot;
import com.example.upbot.MSG.Head;
import com.example.upbot.MSG.MsgId;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
public class SendMsg {
public static byte[] sendCmdMsg(byte value){
Head head = new Head();
head.setMsg_id(MsgId.MSG_CMD);
head.setLength((byte) 0x01);
byte[] temp = new byte[]{head.getFlag(), head.getMsg_id(), head.getLength(), value};
long checkSum = getCRC32Checksum(temp);
return new byte[]{head.getFlag(), head.getMsg_id(), head.getLength(),value, (byte) checkSum};
}
public static byte[] sendMapCorrectMsg(float x_offset, float y_offset, float rotation){
Head head = new Head();
head.setMsg_id(MsgId.MSG_CONF);
byte[] x_bytes = getBytes(x_offset);
byte[] y_bytes = getBytes(y_offset);
byte[] rotation_bytes = getBytes(rotation);
int length = x_bytes.length+y_bytes.length+rotation_bytes.length;
head.setLength((byte) length);
byte[] temp = new byte[3+length];
temp[0] = head.getFlag();
temp[1] = head.getMsg_id();
temp[2] = head.getLength();
System.arraycopy(x_bytes, 0, temp, 3, x_bytes.length);
System.arraycopy(y_bytes, 0, temp, 3+x_bytes.length, y_bytes.length);
System.arraycopy(rotation_bytes, 0, temp, 3+x_bytes.length+y_bytes.length, rotation_bytes.length);
long checkSum = getCRC32Checksum(temp);
byte[] result = new byte[4+length];
System.arraycopy(temp, 0, result, 0, temp.length);
result[3+length] = (byte) checkSum;
return result;
}
public static byte[] sendChargingMsg(byte charge){
Head head = new Head();
head.setMsg_id(MsgId.MSG_CONF);
head.setLength((byte) 0x01);
byte[] temp = new byte[]{head.getFlag(), head.getMsg_id(), head.getLength(), charge};
long checkSum = getCRC32Checksum(temp);
return new byte[]{head.getFlag(), head.getMsg_id(), head.getLength(),charge, (byte) checkSum};
}
public static byte[] sendFrequencyMsg(float frequency){
Head head = new Head();
head.setMsg_id(MsgId.MSG_CONF);
head.setLength((byte) 0x01);
byte[] frequency_byte = getBytes(frequency);
byte[] temp = new byte[frequency_byte.length+3];
temp[0] = head.getFlag();
temp[1] = head.getMsg_id();
temp[2] = head.getLength();
System.arraycopy(frequency_byte, 0, temp, 3, frequency_byte.length);
long checkSum = getCRC32Checksum(temp);
byte[] result = new byte[frequency_byte.length+4];
System.arraycopy(temp, 0, result, 0, temp.length);
result[frequency_byte.length+3] = (byte) checkSum;
return result;
}
public static byte[] sendCoordinateMsg(byte base_num, float[] x_offset, float[] y_offset, float[] z_offset){
Head head = new Head();
head.setMsg_id(MsgId.MSG_CONF);
byte[][] x_bytes = new byte[base_num][4];
byte[][] y_bytes = new byte[base_num][4];
byte[][] z_bytes = new byte[base_num][4];
for (int i = 0; i < base_num; i++){
x_bytes[i] = getBytes(x_offset[i]);
y_bytes[i] = getBytes(y_offset[i]);
z_bytes[i] = getBytes(z_offset[i]);
}
int totalLength = (x_bytes.length)*4+(y_bytes.length)*4+(z_bytes.length)*4;
head.setLength((byte) totalLength);
int l = 3 + totalLength;
byte[] temp = new byte[l];
temp[0] = head.getFlag();
temp[1] = head.getMsg_id();
temp[2] = head.getLength();
for (int i = 0; i < base_num ; i++){
System.arraycopy(x_bytes[i], 0, temp, 3+4*i, x_bytes[i].length);
}
for (int i = 0; i < base_num; i++){
System.arraycopy(y_bytes[i], 0, temp, (x_bytes.length)*4+3+4*i, y_bytes.length);
}
for (int i = 0; i < base_num; i++){
System.arraycopy(z_bytes[i], 0, temp, (x_bytes.length)*4+(y_bytes.length)*4+3+4*i, y_bytes.length);
}
long checkSum = getCRC32Checksum(temp);
byte[] result = new byte[4+totalLength];
System.arraycopy(temp, 0, result, 0, temp.length);
result[l] = (byte) checkSum;
return result;
}
public static long getCRC32Checksum(byte[] bytes) {
Checksum crc32 = new CRC32();
crc32.update(bytes, 0, bytes.length);
return crc32.getValue();
}
public static byte[] getBytes(float data)
{
int intBits = Float.floatToIntBits(data);
return getBytes(intBits);
}
public static byte[] getBytes(int data)
{
byte[] bytes = new byte[4];
bytes[0] = (byte) (data & 0xff);
bytes[1] = (byte) ((data & 0xff00) >> 8);
bytes[2] = (byte) ((data & 0xff0000) >> 16);
bytes[3] = (byte) ((data & 0xff000000) >> 24);
return bytes;
}
}

View File

@ -0,0 +1,145 @@
package com.example.upbot;
import static com.example.upbot.ClientActivity.handler;
import android.annotation.SuppressLint;
import android.os.Message;
import android.util.Log;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Arrays;
public class UPbotComm {
@SuppressLint("StaticFieldLeak")
private static volatile UPbotComm instance;
private static Socket mSocket;
private static boolean status = false;
private static String ip;
private static SocketConnectThread socketConnectThread = null;
@SuppressLint("StaticFieldLeak")
private UPbotComm() {
}
public SocketConnectThread threadInit(){
socketConnectThread = new SocketConnectThread();
return socketConnectThread;
}
public static UPbotComm getInstance() {
if (instance == null) {
synchronized (UPbotComm.class) {
if (instance == null) {
instance = new UPbotComm();
}
}
}
return instance;
}
class SocketConnectThread extends Thread{
@Override
public void run(){
try {
//指定ip地址和端口号
Log.d("UPBOTCOMM", ip);
mSocket = new Socket(ip, 1989);
if(mSocket != null){
status = true;
}
//获取输出流、输入流
// mOutStream = mSocket.getOutputStream();
// mInStream = mSocket.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
startReader(mSocket);
}
}
public boolean connect(String Uip){
ip = Uip;
if(socketConnectThread == null){
threadInit();
}
socketConnectThread.start();
return status;
}
/**
*
* @param msg
*/
public void sendMessage(final String msg) {
if (msg.isEmpty() || !status){
return;
}
new Thread() {
@Override
public void run() {
try {
DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream());
writer.writeUTF(msg); // 写一个UTF-8的信息
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
public void sendMessage(final byte[] msg) {
if (msg.length == 0 || !status){
return;
}
new Thread() {
@Override
public void run() {
try {
DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream());
writer.writeUTF(Arrays.toString(msg)); // 写一个UTF-8的信息
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
public boolean getConnectStatus(){
return status;
}
/**
*
*/
private void startReader(final Socket socket) {
new Thread(){
@Override
public void run() {
DataInputStream reader;
try {
// 获取读取流
reader = new DataInputStream(socket.getInputStream());
while (true) {
// 读取数据
String msg = reader.readUTF();
Message message = new Message();
message.what = 1;
message.obj=msg;
handler.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
protected void onDestroy() {
if(mSocket!=null){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@ -1,152 +0,0 @@
package com.example.wifidemo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ESP8266ClientActivity extends AppCompatActivity {
private String mIp;//硬件的IP
private int mPort = 5000;//硬件的端口
private EditText et_ip;//输入硬件对应的IP
private EditText et_msg;//输入要发送的消息
private Button btn_confirm;//进行连接
private Button btn_send;//发送消息
// Socket mSocket = null;//连接成功可得到的Socket
// OutputStream outputStream = null;//定义输出流
// InputStream inputStream = null;//定义输入流
private StringBuffer sb = new StringBuffer();//消息
private TextView tv_msg;//显示消息
private boolean connectFlage = true;//连接成功或连接3s后变false
private TextView connetStatusTextView;//显示连接状态
private int ShowPointSum = 0;//连接时显示 连接中.. 后面点的计数
private final String TAG = "WifiDemoLogESP8266ClientActivity";
private LocalBroadcastManager localBroadcastManager;//本地广播管理器
private MyLocalBroadcastReceiver localBroadcastReceiver;//广播接收者
private int connectingCount=0;//用来刷新 正在连接 与 正 在 连 接
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_esp8266_client);
initView();//初始化控件
setListener();//设置Button的点击事件
registerBroadcastReceiver();//广播注册
}
/**
*
*/
private void initView() {
et_ip = (EditText) findViewById(R.id.et_ipESP8266);
et_msg = (EditText) findViewById(R.id.et_msgESP8266);
btn_send = findViewById(R.id.btn_sendESP8266);
btn_confirm = findViewById(R.id.btn_confirmESP8266);
tv_msg = (TextView) findViewById(R.id.tv_msgESP8266);
connetStatusTextView = findViewById(R.id.connetStatusTV);
}
/**
* Button
*/
private void setListener() {
btn_confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
btn_confirm.setEnabled(false);//防止正在连接时再次点击连接
WiFiModeUtil.connectFlage=true;
mIp = et_ip.getText().toString();//得到IP
WiFiModeUtil.connetByTCP(mIp,mPort);//进行连接
}
});
btn_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (WiFiModeUtil.mSocket == null) {
Toast.makeText(ESP8266ClientActivity.this, "未连接任何设备~~", Toast.LENGTH_SHORT).show();
return;
}
WiFiModeUtil.sendData(et_msg.getText().toString());//发送数据
}
});
}
@Override
protected void onDestroy() {
localBroadcastManager.unregisterReceiver(localBroadcastReceiver);//注销广播
WiFiModeUtil.closeSocketAndStream();//关闭Socket释放资源
super.onDestroy();
}
/**
* 广
*/
private void registerBroadcastReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("WiFiModeUtil.Connecting");//正在连接
intentFilter.addAction("WiFiModeUtil.Connect.Succeed");//连接成功
intentFilter.addAction("WiFiModeUtil.Connect.Fail");//连接失败
intentFilter.addAction("WiFiModeUtil.Connect.ReceiveMessage");//接收到数据
intentFilter.addAction("WiFiModeUtil.Disconnected");//接收到数据
localBroadcastReceiver = new MyLocalBroadcastReceiver();
localBroadcastManager = LocalBroadcastManager.getInstance(this);
WiFiModeUtil.localBroadcastManager=localBroadcastManager;//给WiFiModeUtil工具类中的本地广播管理器赋值
localBroadcastManager.registerReceiver(localBroadcastReceiver,intentFilter);
}
/**
* 广
*/
class MyLocalBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case "WiFiModeUtil.Connecting":
connectingCount++;
if(connectingCount%2==0)
connetStatusTextView.setText("正在连接");
else
connetStatusTextView.setText("正 在 连 接");
break;
case "WiFiModeUtil.Connect.Succeed":
connetStatusTextView.setText("连接成功");
btn_confirm.setEnabled(true);
break;
case "WiFiModeUtil.Connect.Fail":
connetStatusTextView.setText("连接失败");
btn_confirm.setEnabled(true);
break;
case "WiFiModeUtil.Connect.ReceiveMessage":
tv_msg.setText(WiFiModeUtil.DataRecivice.toString());
break;
case "WiFiModeUtil.Disconnected":
tv_msg.setText("连接已断开,请重新进行连接");
break;
}
}
}
}

View File

@ -1,76 +0,0 @@
package com.example.wifidemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity{
private ActionBar actionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle("深安割草机器人");
findViewById(R.id.base_config_layout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this, ServiceActivity.class);
startActivity(intent);
}
});
findViewById(R.id.mowing_layout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,ClientActivity.class);
startActivity(intent);
}
});
findViewById(R.id.client_mode_layout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,ESP8266ClientActivity.class);
startActivity(intent);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home){
Toast.makeText(this,"返回上一页",Toast.LENGTH_LONG).show();
finish();
}else if (item.getItemId() == R.id.action_more){
Toast.makeText(this,"更多设置",Toast.LENGTH_LONG).show();
}
return true;
}
}

View File

@ -1,205 +0,0 @@
package com.example.wifidemo;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ServiceActivity extends AppCompatActivity {
private Button clearBtn;
private Button showIPBtn;
private TextView ipTV;
private TextView msgTV;
private ServerSocket mServerSocket;
private Socket mSocket;
private StringBuffer stringBuffer = new StringBuffer();
private final String TAG = "WifiDemoLogServiceActivity";
@SuppressLint("HandlerLeak")
public Handler handler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
stringBuffer.append(msg.obj);
stringBuffer.append("\n");
msgTV.setText(stringBuffer.toString());
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
initView();
setListener();
try {
mServerSocket = new ServerSocket(5000);//端口号5000
} catch (IOException e) {
e.printStackTrace();
}
//启动服务线程
SocketAcceptThread socketAcceptThread = new SocketAcceptThread();
socketAcceptThread.start();
}
/**
*
*/
private void initView() {
clearBtn = findViewById(R.id.clearBtn);
showIPBtn = findViewById(R.id.showIPBtn);
ipTV = findViewById(R.id.ipTV);
msgTV = findViewById(R.id.msgTV);
}
/**
*
*/
private void setListener() {
clearBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stringBuffer.setLength(0);
msgTV.setText("");
}
});
showIPBtn.setOnClickListener(new View.OnClickListener() {
@SuppressLint("SetTextI18n")
@Override
public void onClick(View v) {
ipTV.setText(getLocalIpAddress(ServiceActivity.this) + ":5000");
}
});
}
/**
* 线
* Socket
*/
class SocketAcceptThread extends Thread {
@Override
public void run() {
try {
//等待客户端的连接Accept会阻塞直到建立连接
//所以需要放在子线程中运行
mSocket = mServerSocket.accept();
} catch (IOException e) {
e.printStackTrace();
return;
}
//启动消息接收线程
startReader(mSocket);
}
}
/**
* Socket
*/
private void startReader(final Socket socket) {
new Thread() {
@Override
public void run() {
DataInputStream reader;
try {
// 获取读取流
reader = new DataInputStream(socket.getInputStream());
while (true) {
// 读取数据
String msg = reader.readUTF();
Log.d(TAG, "客户端的信息:" + msg);
//告知客户端消息收到
DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream());
writer.writeUTF("收到:" + msg); // 写一个UTF-8的信息
//发消息更新UI
Message message = new Message();
message.what = 1;
message.obj=msg;
handler.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
@Override
protected void onDestroy() {
if (mServerSocket != null) {
try {
mServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(mSocket!=null){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
super.onDestroy();
}
/**
* ipip
*
* @param ipInt
* @return
*/
public static String int2ip(int ipInt) {
StringBuilder sb = new StringBuilder();
sb.append(ipInt & 0xFF).append(".");
sb.append((ipInt >> 8) & 0xFF).append(".");
sb.append((ipInt >> 16) & 0xFF).append(".");
sb.append((ipInt >> 24) & 0xFF);
return sb.toString();
}
/**
* ip
*
* @param context
* @return
*/
public static String getLocalIpAddress(Context context) {
try {
WifiManager wifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int i = wifiInfo.getIpAddress();
return int2ip(i);
} catch (Exception ex) {
return " 获取IP出错鸟!!!!请保证是WIFI,或者请重新打开网络!\n" + ex.getMessage();
}
// return null;
}
}

View File

@ -1,57 +0,0 @@
package com.example.wifidemo;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
@SuppressLint("CustomSplashScreen")
public class SplashActivity extends AppCompatActivity {
@RequiresApi(api = Build.VERSION_CODES.P)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fullScreenDisplay();
setContentView(R.layout.activity_splash);
//创建子线程
Thread mThread=new Thread(){
@Override
public void run() {
super.run();
try {
sleep(3000);//使程序休眠3秒
Intent intent=new Intent(getApplicationContext(),MainActivity.class);
startActivity(intent);
finish();
}catch (Exception e){
e.printStackTrace();
}
}
};
mThread.start();//启动线程
}
@RequiresApi(api = Build.VERSION_CODES.P)
protected void fullScreenDisplay(){
// 隐藏状态栏和ActionBar,实现全屏画面的效果
//隐藏状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
//隐藏标题栏
getSupportActionBar().hide();
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN);
WindowManager.LayoutParams lp = getWindow().getAttributes();
// 始终允许窗口延伸到屏幕短边上的刘海区域
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(lp);
}
}

View File

@ -1,260 +0,0 @@
package com.example.wifidemo;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
/**
* 广Action:"WiFiModeUtil.Connecting"
* 广Action:"WiFiModeUtil.Connect.Fail"
* 广Action:"WiFiModeUtil.Connect.Succeed"
* 广Action:"WiFiModeUtil.Connect.ReceiveMessage"
* 广Action:"WiFiModeUtil.Disconnected"
*/
public class WiFiModeUtil {
private static String mIp;//硬件的IP
private static int mPort = 5000;//硬件的端口
public static Socket mSocket = null;//连接成功可得到的Socket
public static OutputStream outputStream = null;//定义输出流
public static InputStream inputStream = null;//定义输入流
public static StringBuffer DataRecivice = new StringBuffer();//数据
public static List<String> DataList=new ArrayList<>();//数据
public static boolean connectFlage = true;//连接成功或连接3s后变false
// private static int ShowPointSum = 0;//连接时显示 连接中.. 后面点的计数
private static final String TAG = "WifiDemoLogESP8266ClientActivity";
/**
* 广 :
* WiFiModeUtil.localBroadcastManager=localBroadcastManager;
*
*/
public static LocalBroadcastManager localBroadcastManager;
/**
* Handler
*/
@SuppressLint("HandlerLeak")
public static Handler mHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0://接收到数据
DataRecivice.append(msg.obj.toString());
DataRecivice.append("\n");
DataList.add(msg.obj.toString());//添加数据
Intent intent = new Intent("WiFiModeUtil.Connect.ReceiveMessage");
localBroadcastManager.sendBroadcast(intent);//发送收到数据广播
break;
case 1://连接成功
Intent intent2 = new Intent("WiFiModeUtil.Connect.Succeed");
localBroadcastManager.sendBroadcast(intent2);//发送连接成功广播
readData();//开启接收线程
connectFlage = true;
break;
case 2://连接断开
Intent intent3 = new Intent("WiFiModeUtil.Disconnected");
localBroadcastManager.sendBroadcast(intent3);//发送连接失败广播
connectFlage = true;
break;
}
}
};
/***
* 3s
* 3s
* 3s
*/
private final static CountDownTimer tcpClientCountDownTimer = new CountDownTimer(3000, 300) {
@Override
public void onTick(long millisUntilFinished) {//每隔300ms进入
if (connectFlage) {
Intent intent = new Intent("WiFiModeUtil.Connecting");
localBroadcastManager.sendBroadcast(intent);
}
}
@Override
public void onFinish() {//3s后进入(没有取消定时器的情况下)
if (connectFlage) {
connectFlage = false;//连接失败
closeSocketAndStream();
}
tcpClientCountDownTimer.cancel();//关掉定时器
Intent intent = new Intent("WiFiModeUtil.Connect.Fail");
localBroadcastManager.sendBroadcast(intent);
Log.d(TAG,"连接失败");
}
};
/**
* Socket
*/
public static void closeSocketAndStream() {
if (outputStream != null) {
try {
outputStream.close();
Log.d(TAG,"关闭输出流");
} catch (IOException e) {
e.printStackTrace();
}
outputStream = null;
}
if (inputStream != null) {
try {
inputStream.close();
Log.d(TAG,"关闭输入流");
} catch (IOException e) {
e.printStackTrace();
}
inputStream = null;
}
if (mSocket != null) {
try {
mSocket.close();
Log.d(TAG,"关闭Socket");
} catch (IOException e) {
e.printStackTrace();
}
mSocket = null;
}
}
/**
*
*/
static class ConnectSeverThread extends Thread {
@Override
public void run() {
Log.d(TAG,"连接线程开启");
while (connectFlage) {
try {
Log.d(TAG,"正在连接...");
mSocket = new Socket(mIp, mPort);//进行连接
connectFlage = false;//已连接
tcpClientCountDownTimer.cancel();//关掉计时器
/*连接成功更新显示连接状态的UI*/
Message msg = new Message();
msg.what = 1;
mHandler.sendMessage(msg);
Log.d(TAG,"连接成功");
inputStream = mSocket.getInputStream();//获取输入流
Log.d(TAG,"获取输入流");
outputStream = mSocket.getOutputStream();////获取输出流
Log.d(TAG,"获取输出流");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d(TAG,"连接过程中出错");
}
}
}
}
/**
* IPTCP
* 200ms 广
* 3 广
* 广
*
* @param IPAdress
*/
public static void connetByTCP(String IPAdress,int Port) {
mIp = IPAdress;
mPort=Port;
ConnectSeverThread connectSeverThread = new ConnectSeverThread();
connectSeverThread.start();
tcpClientCountDownTimer.start();
}
/**
*
*/
public static void sendData(String data) {
if(mSocket!=null){
byte[] sendByte = data.getBytes();
new Thread() {
@Override
public void run() {
try {
Log.d(TAG,"发送线程开启 正在发送中...");
DataOutputStream writer = new DataOutputStream(outputStream);
writer.write(sendByte, 0, sendByte.length);
Log.d(TAG,"已发送数据:"+data);
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG,"发送线程结束");
}
}.start();
}
}
/**
*
*
*/
public static void readData() {
new Thread() {
@Override
public void run() {
Log.d(TAG,"接收线程开启");
try {
while (true) {
Thread.sleep(200);
//如果连接断开 尝试重连
try {
/*
sendUrgentData()
SocketSO_OOBINLINE
SO_OOBINLINE
*/
mSocket.sendUrgentData(0xFF);//发送1个字节的紧急数据默认情况下服务器端没有开启紧急数据处理不影响正常通信
} catch (Exception ex) {
Log.d(TAG,"连接已断开,请重新进行连接");
Message msg=new Message();
msg.what=2;
msg.obj="连接已断开,请重新进行连接";
mHandler.sendMessage(msg);
}
DataInputStream reader = new DataInputStream(inputStream);
byte[] buffer = new byte[1024];
int len;
while ((len = reader.read(buffer)) != -1) {
String data = new String(buffer, 0, len);
Log.d(TAG,"接收到数据:"+data);
Message msg = new Message();
msg.what = 0;
msg.obj = data;
mHandler.sendMessage(msg);
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG,"接收线程结束");
}
}.start();
}
}

View File

@ -47,7 +47,7 @@
app:layout_constraintTop_toBottomOf="@+id/textView11" /> app:layout_constraintTop_toBottomOf="@+id/textView11" />
<ImageView <ImageView
android:id="@+id/imageView5" android:id="@+id/start_robot_iv"
android:layout_width="67dp" android:layout_width="67dp"
android:layout_height="63dp" android:layout_height="63dp"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"