From a2db5510bb88eec88c14d686785f8a13bf0d7383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=87=A4=E5=90=89?= Date: Mon, 14 Apr 2025 11:07:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=93=9D=E7=89=99=E9=93=BE?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../profilometer/core/bluetooth/BleManager.java | 61 ++++++++++++++++------ .../migration/channel/BleDeviceUartChannel.java | 2 +- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/iflytop/profilometer/core/bluetooth/BleManager.java b/app/src/main/java/com/iflytop/profilometer/core/bluetooth/BleManager.java index b7ce1b2..140d926 100644 --- a/app/src/main/java/com/iflytop/profilometer/core/bluetooth/BleManager.java +++ b/app/src/main/java/com/iflytop/profilometer/core/bluetooth/BleManager.java @@ -34,6 +34,7 @@ import com.iflytop.profilometer.core.system.DeviceState; import com.iflytop.profilometer.core.system.SystemService; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -74,13 +75,14 @@ public class BleManager { private BluetoothGatt bluetoothGatt; // 当前已连接设备的 Gatt private final Context context; - private final List scannedDevices = new ArrayList<>(); + // 使用线程安全的集合包装 + private final List scannedDevices = Collections.synchronizedList(new ArrayList<>()); private ScanCallback scanCallback; - // 记录设备最后出现时间,用于定时清理 - private final Map deviceLastSeenMap = new HashMap<>(); - // 记录已经进行服务查询的设备(以 MAC 地址为 key),避免重复连接 - private final Set processedDevices = new HashSet<>(); + // 记录设备最后出现时间,用于定时清理(线程安全) + private final Map deviceLastSeenMap = Collections.synchronizedMap(new HashMap<>()); + // 记录已经进行服务查询的设备(以 MAC 地址为 key),避免重复连接(线程安全) + private final Set processedDevices = Collections.synchronizedSet(new HashSet<>()); // 定时清理 Handler 和 Runnable(移除超时设备及清除已处理记录) private final Handler cleanupHandler = new Handler(Looper.getMainLooper()); @@ -89,10 +91,13 @@ public class BleManager { @Override public void run() { long now = System.currentTimeMillis(); + // 使用同步快照遍历 List toRemove = new ArrayList<>(); - for (Map.Entry entry : deviceLastSeenMap.entrySet()) { - if (now - entry.getValue() > DEVICE_TIMEOUT) { - toRemove.add(entry.getKey()); + synchronized (deviceLastSeenMap) { + for (Map.Entry entry : deviceLastSeenMap.entrySet()) { + if (now - entry.getValue() > DEVICE_TIMEOUT) { + toRemove.add(entry.getKey()); + } } } if (!toRemove.isEmpty()) { @@ -427,6 +432,7 @@ public class BleManager { // 定义同步等待的 CountDownLatch 和状态标志 final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean connectionSuccess = new AtomicBoolean(false); + final AtomicBoolean latchTriggered = new AtomicBoolean(false); // 新的 BluetoothGattCallback 用于同步连接结果 BluetoothGattCallback syncGattCallback = new BluetoothGattCallback() { @@ -434,16 +440,17 @@ public class BleManager { public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { Log.d(TAG, "设备已连接,开始发现服务"); + // 等待服务发现回调决定成功与否 gatt.discoverServices(); - connectionSuccess.set(true); - latch.countDown(); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { Log.d(TAG, "设备已断开连接"); if (status != BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "连接失败,错误码:" + status); connectionSuccess.set(false); } - latch.countDown(); + if (!latchTriggered.getAndSet(true)) { + latch.countDown(); + } gatt.close(); bluetoothGatt = null; } @@ -452,20 +459,40 @@ public class BleManager { @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { - Log.d(TAG, "服务发现成功"); + BluetoothGattService service = gatt.getService(SERVICE_UUID); + if (service != null) { + Log.d(TAG, "服务发现成功,目标服务存在"); + connectionSuccess.set(true); + } else { + Log.e(TAG, "服务发现成功,但未找到目标服务"); + connectionSuccess.set(false); + } } else { Log.e(TAG, "服务发现失败,错误码:" + status); + connectionSuccess.set(false); + } + if (!latchTriggered.getAndSet(true)) { + latch.countDown(); } } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { - // 处理通知数据(留空或根据需要扩展) + if (NOTIFY_CHARACTERISTIC_UUID.equals(characteristic.getUuid())) { + byte[] data = characteristic.getValue(); + if (bleDataListener != null) { + bleDataListener.onDataReceived(data); + } + } } @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { - // 处理写数据结果(留空或根据需要扩展) + if (status != BluetoothGatt.GATT_SUCCESS) { + Log.i(TAG, "数据写入失败,错误码:" + status); + }else{ + Log.i(TAG, "数据写入成功" + status); + } } }; @@ -477,7 +504,7 @@ public class BleManager { return false; } - // 同步等待最大 15 秒(较之前延长等待时间) + // 同步等待最大 15 秒 try { if (!latch.await(15, TimeUnit.SECONDS)) { Log.e(TAG, "连接超时"); @@ -504,6 +531,8 @@ public class BleManager { editor.putString("mac_address", macAddress); editor.apply(); + // 连接成功后,移除定时清理任务 + cleanupHandler.removeCallbacks(cleanupRunnable); return true; } else { return false; @@ -556,6 +585,8 @@ public class BleManager { editor.remove("mac_address"); editor.apply(); + // 断开时取消定时清理任务,防止任务悬挂 + cleanupHandler.removeCallbacks(cleanupRunnable); Log.d(TAG, "当前蓝牙设备已断开连接"); } catch (Exception e) { e.printStackTrace(); diff --git a/app/src/main/java/com/iflytop/profilometer/core/migration/channel/BleDeviceUartChannel.java b/app/src/main/java/com/iflytop/profilometer/core/migration/channel/BleDeviceUartChannel.java index b8c3194..d9df5d9 100644 --- a/app/src/main/java/com/iflytop/profilometer/core/migration/channel/BleDeviceUartChannel.java +++ b/app/src/main/java/com/iflytop/profilometer/core/migration/channel/BleDeviceUartChannel.java @@ -81,7 +81,7 @@ public class BleDeviceUartChannel { } public synchronized TPMIPacket sendCommand(TPMIPacket tx, Integer overtime) { - Log.e("BLE", "TX PACKET :" + tx); + Log.i("BLE", "TX PACKET :" + tx); ctCxt.newCtCxt(tx); BleManager.getInstance().sendMessage(tx.rawpacket);