diff --git a/app/build.gradle b/app/build.gradle index b243669..d4225fa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -91,10 +91,6 @@ dependencies { // 华为扫码库 implementation "com.huawei.hms:scanplus:2.12.0.301" - - // KryoNet UDP通信库 - implementation 'com.esotericsoftware:kryonet:2.22.0-RC1' - implementation 'com.esotericsoftware:kryo:2.24.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' diff --git a/app/src/main/java/com/ouxuan/oxface/device/DeviceUDPManager.java b/app/src/main/java/com/ouxuan/oxface/device/DeviceUDPManager.java deleted file mode 100644 index 855ef45..0000000 --- a/app/src/main/java/com/ouxuan/oxface/device/DeviceUDPManager.java +++ /dev/null @@ -1,539 +0,0 @@ -package com.ouxuan.oxface.device; - -import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.util.Log; - -import com.esotericsoftware.kryonet.Client; -import com.esotericsoftware.kryonet.Connection; -import com.esotericsoftware.kryonet.Listener; -import com.esotericsoftware.kryonet.Server; - -import java.io.IOException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * 设备UDP通信管理器 - * 基于KryoNet库实现UDP数据收发功能 - * - * 功能特性: - * - 支持UDP服务端和客户端模式 - * - 自动重连机制 - * - 线程安全的数据收发 - * - 支持自定义消息类型 - * - * 使用示例: - * DeviceUDPManager manager = DeviceUDPManager.getInstance(); - * manager.initializeAsClient(context, "192.168.1.100", 54555, 54777); - * manager.sendUDPMessage("Hello World"); - * - * @author AI Assistant - * @version 1.0 - */ -public class DeviceUDPManager { - - private static final String TAG = "DeviceUDPManager"; - private static final int DEFAULT_TCP_PORT = 54555; - private static final int DEFAULT_UDP_PORT = 54777; - private static final int RECONNECT_DELAY = 5000; // 5秒重连延迟 - private static final int CONNECTION_TIMEOUT = 5000; // 5秒连接超时 - - private static DeviceUDPManager instance; - private Context context; - - // 网络组件 - private Client client; - private Server server; - - // 配置参数 - private String serverIP; - private int tcpPort = DEFAULT_TCP_PORT; - private int udpPort = DEFAULT_UDP_PORT; - private boolean isClientMode = true; - private boolean isInitialized = false; - private boolean isConnected = false; - private boolean autoReconnect = true; - - // 线程管理 - private ExecutorService executorService; - private Handler mainHandler; - - // 回调接口 - private UDPMessageListener messageListener; - private ConnectionStateListener connectionListener; - - /** - * UDP消息监听接口 - */ - public interface UDPMessageListener { - /** - * 接收到UDP消息 - * @param message 消息内容 - * @param connection 连接对象 - */ - void onMessageReceived(Object message, Connection connection); - - /** - * UDP消息发送成功 - * @param message 发送的消息 - */ - void onMessageSent(Object message); - - /** - * UDP消息发送失败 - * @param message 发送的消息 - * @param error 错误信息 - */ - void onMessageSendFailed(Object message, String error); - } - - /** - * 连接状态监听接口 - */ - public interface ConnectionStateListener { - /** - * 连接成功 - */ - void onConnected(); - - /** - * 连接断开 - */ - void onDisconnected(); - - /** - * 连接失败 - * @param error 错误信息 - */ - void onConnectionFailed(String error); - - /** - * 重连中 - * @param attempt 重连次数 - */ - void onReconnecting(int attempt); - } - - private DeviceUDPManager() { - executorService = Executors.newCachedThreadPool(); - mainHandler = new Handler(Looper.getMainLooper()); - } - - /** - * 获取单例实例 - */ - public static synchronized DeviceUDPManager getInstance() { - if (instance == null) { - instance = new DeviceUDPManager(); - } - return instance; - } - - /** - * 初始化为客户端模式 - * @param context 应用上下文 - * @param serverIP 服务器IP地址 - * @param tcpPort TCP端口 - * @param udpPort UDP端口 - */ - public void initializeAsClient(Context context, String serverIP, int tcpPort, int udpPort) { - this.context = context.getApplicationContext(); - this.serverIP = serverIP; - this.tcpPort = tcpPort; - this.udpPort = udpPort; - this.isClientMode = true; - - Log.i(TAG, "初始化为客户端模式 - 服务器: " + serverIP + ", TCP: " + tcpPort + ", UDP: " + udpPort); - initializeClient(); - } - - /** - * 初始化为服务端模式 - * @param context 应用上下文 - * @param tcpPort TCP端口 - * @param udpPort UDP端口 - */ - public void initializeAsServer(Context context, int tcpPort, int udpPort) { - this.context = context.getApplicationContext(); - this.tcpPort = tcpPort; - this.udpPort = udpPort; - this.isClientMode = false; - - Log.i(TAG, "初始化为服务端模式 - TCP: " + tcpPort + ", UDP: " + udpPort); - initializeServer(); - } - - /** - * 初始化客户端 - */ - private void initializeClient() { - executorService.execute(() -> { - try { - // 清理现有连接 - cleanup(); - - // 创建客户端 - client = new Client(); - - // 注册常用数据类型 - registerCommonClasses(client.getKryo()); - - // 添加监听器 - client.addListener(new Listener() { - @Override - public void connected(Connection connection) { - Log.i(TAG, "客户端已连接到服务器"); - isConnected = true; - notifyConnectionState(true); - } - - @Override - public void disconnected(Connection connection) { - Log.i(TAG, "客户端已断开连接"); - isConnected = false; - notifyConnectionState(false); - - // 自动重连 - if (autoReconnect && isInitialized) { - scheduleReconnect(); - } - } - - @Override - public void received(Connection connection, Object object) { - Log.d(TAG, "收到UDP消息: " + object); - notifyMessageReceived(object, connection); - } - }); - - // 启动客户端 - client.start(); - isInitialized = true; - - // 连接到服务器 - connectToServer(); - - } catch (Exception e) { - Log.e(TAG, "初始化客户端失败", e); - notifyConnectionError("初始化客户端失败: " + e.getMessage()); - } - }); - } - - /** - * 初始化服务端 - */ - private void initializeServer() { - executorService.execute(() -> { - try { - // 清理现有连接 - cleanup(); - - // 创建服务端 - server = new Server(); - - // 注册常用数据类型 - registerCommonClasses(server.getKryo()); - - // 添加监听器 - server.addListener(new Listener() { - @Override - public void connected(Connection connection) { - Log.i(TAG, "客户端已连接到服务器: " + connection.getRemoteAddressTCP()); - isConnected = true; - notifyConnectionState(true); - } - - @Override - public void disconnected(Connection connection) { - Log.i(TAG, "客户端已断开连接: " + connection.getRemoteAddressTCP()); - // 服务端模式下不需要自动重连 - } - - @Override - public void received(Connection connection, Object object) { - Log.d(TAG, "收到UDP消息: " + object + " 来自: " + connection.getRemoteAddressTCP()); - notifyMessageReceived(object, connection); - } - }); - - // 绑定端口并启动 - server.bind(tcpPort, udpPort); - server.start(); - isInitialized = true; - isConnected = true; - - Log.i(TAG, "UDP服务器已启动 - TCP: " + tcpPort + ", UDP: " + udpPort); - notifyConnectionState(true); - - } catch (Exception e) { - Log.e(TAG, "初始化服务端失败", e); - notifyConnectionError("初始化服务端失败: " + e.getMessage()); - } - }); - } - - /** - * 连接到服务器(客户端模式) - */ - private void connectToServer() { - if (!isClientMode || client == null) return; - - executorService.execute(() -> { - try { - Log.i(TAG, "正在连接到服务器: " + serverIP); - client.connect(CONNECTION_TIMEOUT, serverIP, tcpPort, udpPort); - } catch (IOException e) { - Log.e(TAG, "连接服务器失败", e); - notifyConnectionError("连接服务器失败: " + e.getMessage()); - - // 自动重连 - if (autoReconnect && isInitialized) { - scheduleReconnect(); - } - } - }); - } - - /** - * 安排重连 - */ - private int reconnectAttempt = 0; - private void scheduleReconnect() { - if (!autoReconnect || !isInitialized) return; - - reconnectAttempt++; - Log.i(TAG, "计划重连,第 " + reconnectAttempt + " 次尝试"); - - mainHandler.postDelayed(() -> { - if (isInitialized && !isConnected && autoReconnect) { - notifyReconnecting(reconnectAttempt); - connectToServer(); - } - }, RECONNECT_DELAY); - } - - /** - * 注册常用数据类型 - */ - private void registerCommonClasses(com.esotericsoftware.kryo.Kryo kryo) { - kryo.register(String.class); - kryo.register(Integer.class); - kryo.register(Long.class); - kryo.register(Boolean.class); - kryo.register(Double.class); - kryo.register(Float.class); - kryo.register(byte[].class); - // 可以根据需要注册更多自定义类型 - } - - /** - * 发送UDP消息 - * @param message 要发送的消息 - * @return 是否发送成功 - */ - public boolean sendUDPMessage(Object message) { - if (!isInitialized || !isConnected) { - Log.w(TAG, "UDP管理器未初始化或未连接,无法发送消息"); - notifyMessageSendFailed(message, "UDP管理器未初始化或未连接"); - return false; - } - - executorService.execute(() -> { - try { - if (isClientMode && client != null) { - // 客户端模式发送 - client.sendUDP(message); - Log.d(TAG, "客户端发送UDP消息: " + message); - notifyMessageSent(message); - } else if (!isClientMode && server != null) { - // 服务端模式广播发送 - server.sendToAllUDP(message); - Log.d(TAG, "服务端广播UDP消息: " + message); - notifyMessageSent(message); - } - } catch (Exception e) { - Log.e(TAG, "发送UDP消息失败", e); - notifyMessageSendFailed(message, "发送失败: " + e.getMessage()); - } - }); - - return true; - } - - /** - * 发送UDP消息到指定连接(服务端模式) - * @param connection 目标连接 - * @param message 要发送的消息 - * @return 是否发送成功 - */ - public boolean sendUDPMessageToConnection(Connection connection, Object message) { - if (!isInitialized || server == null || isClientMode) { - Log.w(TAG, "服务端模式未初始化,无法发送消息"); - notifyMessageSendFailed(message, "服务端模式未初始化"); - return false; - } - - executorService.execute(() -> { - try { - connection.sendUDP(message); - Log.d(TAG, "服务端发送UDP消息到连接: " + message); - notifyMessageSent(message); - } catch (Exception e) { - Log.e(TAG, "发送UDP消息失败", e); - notifyMessageSendFailed(message, "发送失败: " + e.getMessage()); - } - }); - - return true; - } - - /** - * 设置消息监听器 - */ - public void setMessageListener(UDPMessageListener listener) { - this.messageListener = listener; - } - - /** - * 设置连接状态监听器 - */ - public void setConnectionStateListener(ConnectionStateListener listener) { - this.connectionListener = listener; - } - - /** - * 设置自动重连 - */ - public void setAutoReconnect(boolean autoReconnect) { - this.autoReconnect = autoReconnect; - } - - /** - * 获取连接状态 - */ - public boolean isConnected() { - return isConnected; - } - - /** - * 获取初始化状态 - */ - public boolean isInitialized() { - return isInitialized; - } - - /** - * 获取当前模式 - */ - public boolean isClientMode() { - return isClientMode; - } - - /** - * 手动重连(客户端模式) - */ - public void reconnect() { - if (isClientMode && isInitialized) { - Log.i(TAG, "手动重连"); - reconnectAttempt = 0; - connectToServer(); - } - } - - /** - * 停止UDP管理器 - */ - public void stop() { - Log.i(TAG, "停止UDP管理器"); - isInitialized = false; - autoReconnect = false; - cleanup(); - } - - /** - * 清理资源 - */ - private void cleanup() { - isConnected = false; - - if (client != null) { - try { - client.stop(); - } catch (Exception e) { - Log.e(TAG, "停止客户端失败", e); - } - client = null; - } - - if (server != null) { - try { - server.stop(); - } catch (Exception e) { - Log.e(TAG, "停止服务端失败", e); - } - server = null; - } - } - - /** - * 释放所有资源 - */ - public void release() { - Log.i(TAG, "释放UDP管理器资源"); - stop(); - - if (executorService != null && !executorService.isShutdown()) { - executorService.shutdown(); - } - - messageListener = null; - connectionListener = null; - } - - // 通知方法 - private void notifyMessageReceived(Object message, Connection connection) { - if (messageListener != null) { - mainHandler.post(() -> messageListener.onMessageReceived(message, connection)); - } - } - - private void notifyMessageSent(Object message) { - if (messageListener != null) { - mainHandler.post(() -> messageListener.onMessageSent(message)); - } - } - - private void notifyMessageSendFailed(Object message, String error) { - if (messageListener != null) { - mainHandler.post(() -> messageListener.onMessageSendFailed(message, error)); - } - } - - private void notifyConnectionState(boolean connected) { - if (connectionListener != null) { - mainHandler.post(() -> { - if (connected) { - reconnectAttempt = 0; // 连接成功后重置重连计数 - connectionListener.onConnected(); - } else { - connectionListener.onDisconnected(); - } - }); - } - } - - private void notifyConnectionError(String error) { - if (connectionListener != null) { - mainHandler.post(() -> connectionListener.onConnectionFailed(error)); - } - } - - private void notifyReconnecting(int attempt) { - if (connectionListener != null) { - mainHandler.post(() -> connectionListener.onReconnecting(attempt)); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/device/DeviceUDPManagerUsageExample.java b/app/src/main/java/com/ouxuan/oxface/device/DeviceUDPManagerUsageExample.java deleted file mode 100644 index 559a796..0000000 --- a/app/src/main/java/com/ouxuan/oxface/device/DeviceUDPManagerUsageExample.java +++ /dev/null @@ -1,314 +0,0 @@ -package com.ouxuan.oxface.device; - -import android.content.Context; -import android.util.Log; - -import com.esotericsoftware.kryonet.Connection; - -/** - * DeviceUDPManager 使用示例 - * 展示如何在项目中初始化和使用UDP通信功能 - * - * @author AI Assistant - * @version 1.0 - */ -public class DeviceUDPManagerUsageExample { - - private static final String TAG = "UDPManagerExample"; - private DeviceUDPManager udpManager; - private Context context; - - public DeviceUDPManagerUsageExample(Context context) { - this.context = context; - this.udpManager = DeviceUDPManager.getInstance(); - } - - /** - * 初始化为客户端模式示例 - */ - public void initializeAsClientExample() { - // 设置消息监听器 - udpManager.setMessageListener(new DeviceUDPManager.UDPMessageListener() { - @Override - public void onMessageReceived(Object message, Connection connection) { - Log.i(TAG, "收到消息: " + message + " 来自: " + connection.getRemoteAddressTCP()); - - // 处理接收到的消息 - if (message instanceof String) { - String strMessage = (String) message; - handleStringMessage(strMessage, connection); - } - // 可以根据需要处理其他类型的消息 - } - - @Override - public void onMessageSent(Object message) { - Log.i(TAG, "消息发送成功: " + message); - } - - @Override - public void onMessageSendFailed(Object message, String error) { - Log.e(TAG, "消息发送失败: " + message + ", 错误: " + error); - } - }); - - // 设置连接状态监听器 - udpManager.setConnectionStateListener(new DeviceUDPManager.ConnectionStateListener() { - @Override - public void onConnected() { - Log.i(TAG, "UDP连接成功"); - // 连接成功后可以发送消息 - sendTestMessage(); - } - - @Override - public void onDisconnected() { - Log.i(TAG, "UDP连接断开"); - } - - @Override - public void onConnectionFailed(String error) { - Log.e(TAG, "UDP连接失败: " + error); - } - - @Override - public void onReconnecting(int attempt) { - Log.i(TAG, "UDP重连中,第 " + attempt + " 次尝试"); - } - }); - - // 设置自动重连 - udpManager.setAutoReconnect(true); - - // 初始化为客户端(连接到服务器) - String serverIP = "192.168.1.100"; // 替换为实际的服务器IP - int tcpPort = 54555; - int udpPort = 54777; - udpManager.initializeAsClient(context, serverIP, tcpPort, udpPort); - } - - /** - * 初始化为服务端模式示例 - */ - public void initializeAsServerExample() { - // 设置消息监听器 - udpManager.setMessageListener(new DeviceUDPManager.UDPMessageListener() { - @Override - public void onMessageReceived(Object message, Connection connection) { - Log.i(TAG, "服务端收到消息: " + message + " 来自: " + connection.getRemoteAddressTCP()); - - // 处理接收到的消息并回复 - if (message instanceof String) { - String strMessage = (String) message; - handleServerMessage(strMessage, connection); - } - } - - @Override - public void onMessageSent(Object message) { - Log.i(TAG, "服务端消息发送成功: " + message); - } - - @Override - public void onMessageSendFailed(Object message, String error) { - Log.e(TAG, "服务端消息发送失败: " + message + ", 错误: " + error); - } - }); - - // 设置连接状态监听器 - udpManager.setConnectionStateListener(new DeviceUDPManager.ConnectionStateListener() { - @Override - public void onConnected() { - Log.i(TAG, "服务端已准备就绪,等待客户端连接"); - } - - @Override - public void onDisconnected() { - Log.i(TAG, "客户端断开连接"); - } - - @Override - public void onConnectionFailed(String error) { - Log.e(TAG, "服务端启动失败: " + error); - } - - @Override - public void onReconnecting(int attempt) { - // 服务端模式下通常不需要重连 - } - }); - - // 初始化为服务端 - int tcpPort = 54555; - int udpPort = 54777; - udpManager.initializeAsServer(context, tcpPort, udpPort); - } - - /** - * 发送测试消息 - */ - public void sendTestMessage() { - if (udpManager.isConnected()) { - // 发送字符串消息 - udpManager.sendUDPMessage("Hello from Android device!"); - - // 发送JSON格式的消息 - String jsonMessage = "{\"type\":\"device_status\",\"status\":\"online\",\"timestamp\":" + System.currentTimeMillis() + "}"; - udpManager.sendUDPMessage(jsonMessage); - - // 发送数字消息 - udpManager.sendUDPMessage(12345); - } else { - Log.w(TAG, "UDP未连接,无法发送消息"); - } - } - - /** - * 处理接收到的字符串消息(客户端) - */ - private void handleStringMessage(String message, Connection connection) { - Log.d(TAG, "处理字符串消息: " + message); - - // 根据消息内容进行不同处理 - if (message.startsWith("{")) { - // JSON格式消息 - handleJsonMessage(message, connection); - } else if (message.equals("ping")) { - // 心跳消息 - udpManager.sendUDPMessage("pong"); - } else if (message.startsWith("command:")) { - // 命令消息 - String command = message.substring(8); - handleCommand(command, connection); - } else { - // 普通文本消息 - Log.i(TAG, "收到普通文本消息: " + message); - } - } - - /** - * 处理服务端接收到的消息 - */ - private void handleServerMessage(String message, Connection connection) { - Log.d(TAG, "服务端处理消息: " + message); - - // 服务端可以回复消息给特定客户端 - if (message.equals("ping")) { - udpManager.sendUDPMessageToConnection(connection, "pong"); - } else if (message.equals("get_status")) { - String status = "{\"server_status\":\"running\",\"timestamp\":" + System.currentTimeMillis() + "}"; - udpManager.sendUDPMessageToConnection(connection, status); - } else { - // 回复确认消息 - udpManager.sendUDPMessageToConnection(connection, "message_received: " + message); - } - } - - /** - * 处理JSON格式消息 - */ - private void handleJsonMessage(String jsonMessage, Connection connection) { - try { - Log.d(TAG, "处理JSON消息: " + jsonMessage); - // 这里可以使用Gson或其他JSON库解析消息 - // 示例:设备状态更新、配置同步等 - } catch (Exception e) { - Log.e(TAG, "解析JSON消息失败", e); - } - } - - /** - * 处理命令消息 - */ - private void handleCommand(String command, Connection connection) { - Log.d(TAG, "处理命令: " + command); - - switch (command) { - case "restart": - Log.i(TAG, "收到重启命令"); - // 执行重启逻辑 - break; - case "get_config": - Log.i(TAG, "收到获取配置命令"); - // 返回当前配置 - udpManager.sendUDPMessage("{\"config\":{\"version\":\"1.0\",\"mode\":\"production\"}}"); - break; - case "shutdown": - Log.i(TAG, "收到关闭命令"); - // 执行关闭逻辑 - break; - default: - Log.w(TAG, "未知命令: " + command); - break; - } - } - - /** - * 手动重连 - */ - public void reconnect() { - if (udpManager.isClientMode()) { - udpManager.reconnect(); - } - } - - /** - * 停止UDP管理器 - */ - public void stop() { - udpManager.stop(); - } - - /** - * 获取连接状态 - */ - public boolean isConnected() { - return udpManager.isConnected(); - } - - /** - * 在Activity或Service中的使用示例 - */ - public static class IntegrationExample { - - /** - * 在Application中初始化(推荐) - */ - public static void initializeInApplication(Context context) { - DeviceUDPManagerUsageExample example = new DeviceUDPManagerUsageExample(context); - - // 根据设备角色选择模式 - boolean isServer = isCurrentDeviceServer(); // 自定义逻辑判断 - - if (isServer) { - example.initializeAsServerExample(); - } else { - example.initializeAsClientExample(); - } - } - - /** - * 在Activity中使用 - */ - public static void useInActivity(Context context) { - DeviceUDPManager manager = DeviceUDPManager.getInstance(); - - // 检查连接状态 - if (manager.isConnected()) { - // 发送设备状态消息 - String deviceInfo = "{\"device_id\":\"" + android.os.Build.MODEL + "\",\"timestamp\":" + System.currentTimeMillis() + "}"; - manager.sendUDPMessage(deviceInfo); - } - } - - /** - * 判断当前设备是否应该作为服务端 - * 这里可以根据具体业务逻辑实现 - */ - private static boolean isCurrentDeviceServer() { - // 示例:可以根据设备配置、IP地址范围、设备类型等判断 - // 这里简单返回false,实际使用时需要根据业务需求实现 - return false; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/device/UDPTestActivity.java b/app/src/main/java/com/ouxuan/oxface/device/UDPTestActivity.java deleted file mode 100644 index 3c03123..0000000 --- a/app/src/main/java/com/ouxuan/oxface/device/UDPTestActivity.java +++ /dev/null @@ -1,351 +0,0 @@ -package com.ouxuan.oxface.device; - -import android.os.Bundle; -import android.util.Log; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ScrollView; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.appcompat.app.AppCompatActivity; - -import com.esotericsoftware.kryonet.Connection; -import com.ouxuan.oxface.R; - -/** - * UDP通信测试Activity - * 用于测试DeviceUDPManager的功能 - * - * @author AI Assistant - * @version 1.0 - */ -public class UDPTestActivity extends AppCompatActivity { - - private static final String TAG = "UDPTestActivity"; - - private DeviceUDPManager udpManager; - private EditText etServerIP; - private EditText etTcpPort; - private EditText etUdpPort; - private EditText etMessage; - private Button btnStartClient; - private Button btnStartServer; - private Button btnSendMessage; - private Button btnStop; - private TextView tvStatus; - private TextView tvLog; - private ScrollView scrollView; - - private StringBuilder logBuilder = new StringBuilder(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // 由于这是测试Activity,我们使用简单的布局 - initializeViews(); - - udpManager = DeviceUDPManager.getInstance(); - setupUDPManager(); - setupClickListeners(); - - // 设置默认值 - etServerIP.setText("192.168.1.100"); - etTcpPort.setText("54555"); - etUdpPort.setText("54777"); - etMessage.setText("Hello UDP!"); - - updateStatus("未连接"); - } - - /** - * 初始化视图(简化版,实际项目中应该使用XML布局) - */ - private void initializeViews() { - // 这里为了演示目的使用代码创建布局 - // 在实际项目中应该创建对应的XML布局文件 - - android.widget.LinearLayout mainLayout = new android.widget.LinearLayout(this); - mainLayout.setOrientation(android.widget.LinearLayout.VERTICAL); - mainLayout.setPadding(32, 32, 32, 32); - - // 服务器IP输入 - android.widget.TextView ipLabel = new android.widget.TextView(this); - ipLabel.setText("服务器IP:"); - mainLayout.addView(ipLabel); - - etServerIP = new EditText(this); - etServerIP.setHint("输入服务器IP地址"); - mainLayout.addView(etServerIP); - - // TCP端口输入 - android.widget.TextView tcpLabel = new android.widget.TextView(this); - tcpLabel.setText("TCP端口:"); - mainLayout.addView(tcpLabel); - - etTcpPort = new EditText(this); - etTcpPort.setHint("TCP端口"); - etTcpPort.setInputType(android.text.InputType.TYPE_CLASS_NUMBER); - mainLayout.addView(etTcpPort); - - // UDP端口输入 - android.widget.TextView udpLabel = new android.widget.TextView(this); - udpLabel.setText("UDP端口:"); - mainLayout.addView(udpLabel); - - etUdpPort = new EditText(this); - etUdpPort.setHint("UDP端口"); - etUdpPort.setInputType(android.text.InputType.TYPE_CLASS_NUMBER); - mainLayout.addView(etUdpPort); - - // 按钮布局 - android.widget.LinearLayout buttonLayout = new android.widget.LinearLayout(this); - buttonLayout.setOrientation(android.widget.LinearLayout.HORIZONTAL); - - btnStartClient = new Button(this); - btnStartClient.setText("启动客户端"); - buttonLayout.addView(btnStartClient); - - btnStartServer = new Button(this); - btnStartServer.setText("启动服务端"); - buttonLayout.addView(btnStartServer); - - btnStop = new Button(this); - btnStop.setText("停止"); - buttonLayout.addView(btnStop); - - mainLayout.addView(buttonLayout); - - // 消息输入 - android.widget.TextView msgLabel = new android.widget.TextView(this); - msgLabel.setText("发送消息:"); - mainLayout.addView(msgLabel); - - etMessage = new EditText(this); - etMessage.setHint("输入要发送的消息"); - mainLayout.addView(etMessage); - - btnSendMessage = new Button(this); - btnSendMessage.setText("发送消息"); - mainLayout.addView(btnSendMessage); - - // 状态显示 - tvStatus = new TextView(this); - tvStatus.setText("状态: 未连接"); - tvStatus.setTextSize(16); - tvStatus.setPadding(0, 20, 0, 10); - mainLayout.addView(tvStatus); - - // 日志显示 - android.widget.TextView logLabel = new android.widget.TextView(this); - logLabel.setText("日志:"); - mainLayout.addView(logLabel); - - tvLog = new TextView(this); - tvLog.setTextSize(12); - tvLog.setBackgroundColor(0xFFF0F0F0); - tvLog.setPadding(10, 10, 10, 10); - tvLog.setMaxLines(20); - - scrollView = new ScrollView(this); - scrollView.addView(tvLog); - android.widget.LinearLayout.LayoutParams scrollParams = new android.widget.LinearLayout.LayoutParams( - android.widget.LinearLayout.LayoutParams.MATCH_PARENT, 400); - scrollView.setLayoutParams(scrollParams); - mainLayout.addView(scrollView); - - setContentView(mainLayout); - } - - /** - * 设置UDP管理器监听器 - */ - private void setupUDPManager() { - udpManager.setMessageListener(new DeviceUDPManager.UDPMessageListener() { - @Override - public void onMessageReceived(Object message, Connection connection) { - String logMsg = "收到消息: " + message + " 来自: " + - (connection.getRemoteAddressTCP() != null ? connection.getRemoteAddressTCP().toString() : "未知"); - addLog(logMsg); - Log.i(TAG, logMsg); - } - - @Override - public void onMessageSent(Object message) { - String logMsg = "消息发送成功: " + message; - addLog(logMsg); - Log.i(TAG, logMsg); - } - - @Override - public void onMessageSendFailed(Object message, String error) { - String logMsg = "消息发送失败: " + message + ", 错误: " + error; - addLog(logMsg); - Log.e(TAG, logMsg); - showToast("发送失败: " + error); - } - }); - - udpManager.setConnectionStateListener(new DeviceUDPManager.ConnectionStateListener() { - @Override - public void onConnected() { - updateStatus("已连接"); - addLog("UDP连接成功"); - Log.i(TAG, "UDP连接成功"); - showToast("连接成功"); - } - - @Override - public void onDisconnected() { - updateStatus("已断开"); - addLog("UDP连接断开"); - Log.i(TAG, "UDP连接断开"); - } - - @Override - public void onConnectionFailed(String error) { - updateStatus("连接失败"); - addLog("UDP连接失败: " + error); - Log.e(TAG, "UDP连接失败: " + error); - showToast("连接失败: " + error); - } - - @Override - public void onReconnecting(int attempt) { - updateStatus("重连中 (第" + attempt + "次)"); - addLog("UDP重连中,第 " + attempt + " 次尝试"); - Log.i(TAG, "UDP重连中,第 " + attempt + " 次尝试"); - } - }); - - udpManager.setAutoReconnect(true); - } - - /** - * 设置按钮点击监听器 - */ - private void setupClickListeners() { - btnStartClient.setOnClickListener(v -> startClient()); - btnStartServer.setOnClickListener(v -> startServer()); - btnSendMessage.setOnClickListener(v -> sendMessage()); - btnStop.setOnClickListener(v -> stopUDP()); - } - - /** - * 启动客户端 - */ - private void startClient() { - String serverIP = etServerIP.getText().toString().trim(); - String tcpPortStr = etTcpPort.getText().toString().trim(); - String udpPortStr = etUdpPort.getText().toString().trim(); - - if (serverIP.isEmpty()) { - showToast("请输入服务器IP"); - return; - } - - try { - int tcpPort = Integer.parseInt(tcpPortStr); - int udpPort = Integer.parseInt(udpPortStr); - - updateStatus("连接中..."); - addLog("正在启动客户端连接到 " + serverIP + ":" + tcpPort + "/" + udpPort); - - udpManager.initializeAsClient(this, serverIP, tcpPort, udpPort); - - } catch (NumberFormatException e) { - showToast("端口号格式错误"); - } - } - - /** - * 启动服务端 - */ - private void startServer() { - String tcpPortStr = etTcpPort.getText().toString().trim(); - String udpPortStr = etUdpPort.getText().toString().trim(); - - try { - int tcpPort = Integer.parseInt(tcpPortStr); - int udpPort = Integer.parseInt(udpPortStr); - - updateStatus("启动中..."); - addLog("正在启动服务端,端口: " + tcpPort + "/" + udpPort); - - udpManager.initializeAsServer(this, tcpPort, udpPort); - - } catch (NumberFormatException e) { - showToast("端口号格式错误"); - } - } - - /** - * 发送消息 - */ - private void sendMessage() { - String message = etMessage.getText().toString().trim(); - - if (message.isEmpty()) { - showToast("请输入要发送的消息"); - return; - } - - if (!udpManager.isConnected()) { - showToast("UDP未连接,无法发送消息"); - return; - } - - addLog("发送消息: " + message); - udpManager.sendUDPMessage(message); - - // 清空输入框 - etMessage.setText(""); - } - - /** - * 停止UDP - */ - private void stopUDP() { - updateStatus("已停止"); - addLog("停止UDP服务"); - udpManager.stop(); - showToast("UDP服务已停止"); - } - - /** - * 更新状态显示 - */ - private void updateStatus(String status) { - runOnUiThread(() -> tvStatus.setText("状态: " + status)); - } - - /** - * 添加日志 - */ - private void addLog(String log) { - runOnUiThread(() -> { - String timestamp = java.text.DateFormat.getTimeInstance().format(new java.util.Date()); - logBuilder.append("[").append(timestamp).append("] ").append(log).append("\n"); - tvLog.setText(logBuilder.toString()); - - // 自动滚动到底部 - scrollView.post(() -> scrollView.fullScroll(ScrollView.FOCUS_DOWN)); - }); - } - - /** - * 显示Toast消息 - */ - private void showToast(String message) { - runOnUiThread(() -> Toast.makeText(this, message, Toast.LENGTH_SHORT).show()); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - if (udpManager != null) { - udpManager.stop(); - } - } -} \ No newline at end of file