starwork_flutter/lib/ble/ble_service.dart

150 lines
5.4 KiB
Dart
Raw Normal View History

2025-09-06 15:42:26 +08:00
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;
}
}