150 lines
5.4 KiB
Dart
150 lines
5.4 KiB
Dart
import 'dart:async';
|
||
|
||
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||
import 'package:starwork_flutter/base/app_logger.dart';
|
||
import 'package:starwork_flutter/ble/model/scan_device_info.dart';
|
||
import 'package:starwork_flutter/common/constant/device_type.dart';
|
||
|
||
class BleService {
|
||
// 私有构造函数
|
||
BleService._() {
|
||
// ✅ 这里就是单例初始化的地方
|
||
// 只会执行一次(第一次获取实例时)
|
||
_initialize();
|
||
}
|
||
|
||
// 静态实例
|
||
static final BleService _instance = BleService._();
|
||
|
||
// 工厂构造函数,提供全局访问点
|
||
factory BleService() => _instance;
|
||
|
||
/// 用来存储搜索到的设备,并用于去重和过滤
|
||
final Map<String, ScanResult> _discoveredDevices = {};
|
||
|
||
/// 用来监听蓝牙适配器状态的订阅流
|
||
StreamSubscription<BluetoothAdapterState>? _adapterStateSubscription;
|
||
|
||
/// 用来监听搜索到的设备的订阅流
|
||
StreamSubscription<List<ScanResult>>? _scanResultSubscription;
|
||
|
||
// 内部维护的蓝牙状态
|
||
BluetoothAdapterState _bluetoothAdapterState = BluetoothAdapterState.unknown;
|
||
|
||
/// 提供外部获取蓝牙适配器方法
|
||
BluetoothAdapterState get bluetoothAdapterState => _bluetoothAdapterState;
|
||
|
||
/// 搜索状态
|
||
bool get isScanningNow => FlutterBluePlus.isScanningNow;
|
||
|
||
/// 初始化服务时执行的
|
||
Future<void> _initialize() async {
|
||
AppLogger.highlight('🚀 BleService 正在初始化...');
|
||
|
||
/// 监听蓝牙适配器状态
|
||
_adapterStateSubscription = FlutterBluePlus.adapterState.listen((BluetoothAdapterState state) {
|
||
_bluetoothAdapterState = state;
|
||
AppLogger.highlight('蓝牙适配器状态发送变化:${state}');
|
||
});
|
||
|
||
AppLogger.highlight('✅ BleService 初始化完成');
|
||
}
|
||
|
||
/// 开启蓝牙搜索
|
||
void enableBluetoothSearch({
|
||
DeviceType deviceType = DeviceType.all,
|
||
Duration searchTime = const Duration(seconds: 30),
|
||
required void Function(ScanDeviceInfo device) onDeviceFound,
|
||
}) async {
|
||
// 如果正在搜索中,直接返回
|
||
var isScanningNow = FlutterBluePlus.isScanningNow;
|
||
if (isScanningNow) {
|
||
AppLogger.warn('正处于搜索状态,请勿重复搜索');
|
||
return;
|
||
}
|
||
if (_bluetoothAdapterState == BluetoothAdapterState.on) {
|
||
FlutterBluePlus.startScan(timeout: searchTime);
|
||
|
||
/// 取消旧的订阅,防止重复
|
||
_scanResultSubscription?.cancel();
|
||
_discoveredDevices.clear();
|
||
|
||
/// 监听搜索到的设备
|
||
_scanResultSubscription = FlutterBluePlus.onScanResults.listen(
|
||
(List<ScanResult> results) {
|
||
for (var result in results) {
|
||
var device = result.device;
|
||
final deviceId = device.remoteId.toString();
|
||
final platformName = device.platformName;
|
||
var serviceUuids = result.advertisementData.serviceUuids;
|
||
|
||
// ✅ 只有新设备才回调
|
||
if (!_discoveredDevices.containsKey(deviceId) && platformName.isNotEmpty) {
|
||
_discoveredDevices[deviceId] = result;
|
||
bool pairStatus = false;
|
||
bool hasNewEvent = false;
|
||
for (var uuid in serviceUuids) {
|
||
String uuidStr = uuid.toString().replaceAll('-', '');
|
||
if (uuidStr.length == 8) {
|
||
var pairStatusStr = uuidStr.substring(4, 6);
|
||
var hasNewEventStr = uuidStr.substring(6, 8);
|
||
pairStatus = pairStatusStr == '01';
|
||
hasNewEvent = hasNewEventStr == '01';
|
||
var scanDeviceInfo = ScanDeviceInfo(
|
||
isBinding: pairStatus,
|
||
advName: device.advName,
|
||
rawDeviceInfo: result,
|
||
hasNewEvent: hasNewEvent,
|
||
);
|
||
onDeviceFound.call(scanDeviceInfo);
|
||
} else if (uuidStr.length == 32) {
|
||
var pairStatusStr = uuidStr.substring(26, 28);
|
||
pairStatus = pairStatusStr == '00'; // 第4、5位(索引3和4)
|
||
int statusValue = int.parse(pairStatusStr, radix: 16);
|
||
// 提取 byte0(配对状态:第1位)
|
||
int byte0 = (statusValue >> 0) & 0x01; // 取最低位
|
||
// 提取 byte1(事件状态:第2位)
|
||
int byte1 = (statusValue >> 1) & 0x01; // 取次低位
|
||
// 判断是否未配对
|
||
pairStatus = (byte0 == 1);
|
||
// 判断是否有新事件
|
||
hasNewEvent = (byte1 == 1);
|
||
var scanDeviceInfo = ScanDeviceInfo(
|
||
isBinding: pairStatus,
|
||
advName: device.advName,
|
||
rawDeviceInfo: result,
|
||
hasNewEvent: hasNewEvent,
|
||
);
|
||
onDeviceFound.call(scanDeviceInfo);
|
||
}
|
||
}
|
||
} else {
|
||
// 可选:更新 RSSI
|
||
_discoveredDevices[deviceId] = result;
|
||
}
|
||
}
|
||
},
|
||
onError: (e) => AppLogger.error('搜索设备时遇到错误:' + e),
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 停止扫描
|
||
void stopBluetoothSearch() async {
|
||
var isScanningNow = FlutterBluePlus.isScanningNow;
|
||
if (isScanningNow) {
|
||
FlutterBluePlus.stopScan();
|
||
|
||
/// 清空搜索到的设备
|
||
_discoveredDevices.clear();
|
||
}
|
||
}
|
||
|
||
void cancel() {
|
||
/// 销毁蓝牙适配器监听
|
||
_adapterStateSubscription?.cancel();
|
||
_scanResultSubscription?.cancel();
|
||
_bluetoothAdapterState = BluetoothAdapterState.unknown;
|
||
}
|
||
}
|