求基于Java的Android Studio ESP32多连接通信APP资源与源码
Android Java 与 ESP32 三种连接方式数据收发实现方案
一、经典蓝牙(Bluetooth Classic)连接与数据收发
核心代码片段
设备配对与连接
// 获取蓝牙适配器 BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { // 设备不支持蓝牙,直接返回 return; } // 开启蓝牙(未开启时请求权限) if (!bluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } // 遍历已配对设备,匹配ESP32 Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); for (BluetoothDevice device : pairedDevices) { if (device.getName().contains("ESP32")) { // 建立RFCOMM连接(使用通用串口UUID) BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); // 子线程执行连接与读写,避免阻塞主线程 new Thread(() -> { try { socket.connect(); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); // 发送数据 out.write("Hello ESP32".getBytes()); out.flush(); // 接收数据 byte[] buffer = new byte[1024]; int bytesRead = in.read(buffer); String receivedData = new String(buffer, 0, bytesRead); } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }).start(); break; } }
卡顿规避要点
- 所有蓝牙操作(连接、读写)必须放在子线程执行,禁止在主线程操作,否则会触发ANR。
- 扫描新设备时设置超时时间,扫描完成后立即停止,避免持续占用系统资源。
二、低功耗蓝牙(BLE)连接与数据收发
核心代码片段
扫描与GATT连接
BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner(); ScanCallback scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); BluetoothDevice device = result.getDevice(); if (device.getName() != null && device.getName().contains("ESP32-BLE")) { scanner.stopScan(this); // 连接BLE设备,异步回调处理状态 device.connectGatt(MainActivity.this, false, gattCallback); } } }; // 启动扫描(可添加过滤规则,只扫描指定服务UUID的设备) scanner.startScan(scanCallback); // GATT回调处理连接、服务发现与数据收发 BluetoothGattCallback gattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); if (newState == BluetoothProfile.STATE_CONNECTED) { // 连接成功后发现服务 gatt.discoverServices(); } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); // 匹配ESP32端定义的服务与特征UUID BluetoothGattService service = gatt.getService(UUID.fromString("YOUR_ESP32_SERVICE_UUID")); BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString("YOUR_ESP32_CHAR_UUID")); // 开启通知,接收ESP32主动推送的数据 gatt.setCharacteristicNotification(characteristic, true); // 发送数据到ESP32 characteristic.setValue("BLE Test Data".getBytes()); gatt.writeCharacteristic(characteristic); } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { super.onCharacteristicChanged(gatt, characteristic); // 接收ESP32数据 String receivedData = new String(characteristic.getValue()); // 更新UI需切换到主线程 runOnUiThread(() -> { tvReceived.setText(receivedData); }); } };
卡顿规避要点
- 扫描BLE设备时添加服务UUID过滤,减少无效扫描结果,降低资源消耗。
- GATT的写/读操作回调中,避免执行耗时逻辑,更新UI必须通过
runOnUiThread。
三、WIFI 连接与数据收发(TCP)
核心代码片段(TCP客户端)
// 子线程建立TCP连接,避免阻塞主线程 new Thread(() -> { Socket socket = null; try { // 替换为ESP32的WIFI IP和监听端口 socket = new Socket("192.168.1.100", 8080); OutputStream out = socket.getOutputStream(); InputStream in = socket.getInputStream(); // 发送数据 out.write("WIFI TCP Test".getBytes()); out.flush(); // 接收数据 byte[] buffer = new byte[1024]; int bytesRead = in.read(buffer); String receivedData = new String(buffer, 0, bytesRead); // 更新UI runOnUiThread(() -> { tvReceived.setText(receivedData); }); } catch (IOException e) { e.printStackTrace(); } finally { try { if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } }).start();
卡顿规避要点
- 所有网络操作必须放在子线程,可使用
AsyncTask或RxJava简化线程管理。 - 若需持续通信,使用长连接并设置超时时间,避免无响应时阻塞线程;闲置时及时关闭Socket释放资源。
通用优化与卡顿排查
- 主线程检查:用Android Studio Profiler工具排查主线程耗时操作,确保所有IO、网络、蓝牙逻辑都在子线程执行。
- 资源释放:蓝牙连接断开后关闭
BluetoothSocket/BluetoothGatt;WIFI连接关闭后释放Socket和流,避免资源泄漏。 - 权限配置:确保AndroidManifest.xml添加必要权限(Android 12+需动态申请蓝牙相关权限):
<!-- 经典蓝牙 --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- BLE --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- WIFI --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
内容的提问来源于stack exchange,提问作者Mohamed Amal A
相关产品推荐
相关产品推荐

