|
|
@ -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<BluetoothDevice> scannedDevices = new ArrayList<>(); |
|
|
|
// 使用线程安全的集合包装 |
|
|
|
private final List<BluetoothDevice> scannedDevices = Collections.synchronizedList(new ArrayList<>()); |
|
|
|
private ScanCallback scanCallback; |
|
|
|
|
|
|
|
// 记录设备最后出现时间,用于定时清理 |
|
|
|
private final Map<BluetoothDevice, Long> deviceLastSeenMap = new HashMap<>(); |
|
|
|
// 记录已经进行服务查询的设备(以 MAC 地址为 key),避免重复连接 |
|
|
|
private final Set<String> processedDevices = new HashSet<>(); |
|
|
|
// 记录设备最后出现时间,用于定时清理(线程安全) |
|
|
|
private final Map<BluetoothDevice, Long> deviceLastSeenMap = Collections.synchronizedMap(new HashMap<>()); |
|
|
|
// 记录已经进行服务查询的设备(以 MAC 地址为 key),避免重复连接(线程安全) |
|
|
|
private final Set<String> 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<BluetoothDevice> toRemove = new ArrayList<>(); |
|
|
|
for (Map.Entry<BluetoothDevice, Long> entry : deviceLastSeenMap.entrySet()) { |
|
|
|
if (now - entry.getValue() > DEVICE_TIMEOUT) { |
|
|
|
toRemove.add(entry.getKey()); |
|
|
|
synchronized (deviceLastSeenMap) { |
|
|
|
for (Map.Entry<BluetoothDevice, Long> 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(); |
|
|
|