app-starlock/star_lock/lib/blue/blue_manage.dart
2024-01-02 18:03:50 +08:00

304 lines
11 KiB
Dart

import 'dart:async';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'io_tool/io_model.dart';
import 'io_tool/io_tool.dart';
import 'io_tool/manager_event_bus.dart';
import 'reciver_data.dart';
//连接状态回调
typedef ConnectStateCallBack = Function(DeviceConnectionState connectionState);
class BlueManage{
FlutterReactiveBle? _flutterReactiveBle;
final List<DiscoveredDevice> scanDevices = [];
// 用来写入的服务id
Uuid serviceIdConnect = Uuid.parse("fff0");
// 用来写入的服务id
Uuid serviceIdWrite = Uuid.parse('0000FFF0-0000-1000-8000-00805F9B34FB');
// 用来订阅的特征id
Uuid characteristicIdSubscription = Uuid.parse("fff1");
// 用来写入的特征id
Uuid characteristicIdWrite = Uuid.parse("fff2");
// 发送监听发送事件
StreamSubscription<EventSendModel>? _sendStreamSubscription;
// 监听蓝牙扫描的事件
StreamSubscription? _scanSubscription;
// 监听蓝牙连接的事件
StreamSubscription<dynamic>? _currentConnectionStream;
// 当前连接设备的名字
String connectDeviceName = "";
// 当前连接设备的mac地址
String connectDeviceMacAddress = "";
// 监听蓝牙连接状态
DeviceConnectionState? deviceConnectionState = DeviceConnectionState.disconnected;
static BlueManage? _manager;
BlueManage._init();
static BlueManage? shareManager(){
_manager ??= BlueManage._init();
_manager!._initBlue();
return _manager;
}
factory BlueManage() => shareManager()!;
BlueManage? get manager => shareManager();
void _initBlue(){
// print("蓝牙功能初始化了");
_flutterReactiveBle ??= FlutterReactiveBle();
_initSendStreamSubscription();
}
void _initSendStreamSubscription() {
_sendStreamSubscription ??= EventBusManager().eventBus!.on<EventSendModel>().listen((
EventSendModel model) {
if (model.sendChannel == DataChannel.ble) {
// managerAppWriteData(model.data);
writeCharacteristicWithResponse(model.data);
}
});
}
/// 开始扫描蓝牙设备
void startScan({List<Uuid>? idList}) {
scanDevices.clear();
_scanSubscription = _flutterReactiveBle!.scanForDevices(withServices: idList??[]).listen((device) {
// 判断名字为空的直接剔除
if(device.name.isEmpty){
return;
}
// print("startScanDevice:$device");
if (((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString().contains("758824")) && (device.rssi >= -100)) {
// 查询id相同的元素
final knownDeviceIndex = scanDevices.indexWhere((d) => d.id == device.id);
// 不存在的时候返回-1
if (knownDeviceIndex >= 0) {
scanDevices[knownDeviceIndex] = device;
} else {
scanDevices.add(device);
}
EventBusManager().eventBusFir(scanDevices);
}
}, onError: (Object e) {
print('Device scan fails with error: $e');
});
}
/// 调用连接
Future<void> judgeReconnect(String deviceName, ConnectStateCallBack stateCallBack) async {
if(deviceConnectionState != DeviceConnectionState.connected){
_connect(deviceName, (state){
stateCallBack(deviceConnectionState!);
});
}else{
stateCallBack(deviceConnectionState!);
}
}
/// 连接监听状态
Future<void> _connect(String deviceName, ConnectStateCallBack connectStateCallBack) async {
connectDeviceName = deviceName;
// 判断数组列表里面是否有这个设备
final knownDeviceIndex = scanDevices.indexWhere((d) => d.name == deviceName);
if (knownDeviceIndex >= 0) {
// 存在的时候赋值
connectDeviceMacAddress = scanDevices[knownDeviceIndex].id;
} else {
// 不存在的时候返回-1 然后循环5秒
var index = 0;
Completer? completer = Completer();
Timer.periodic(const Duration(milliseconds: 1000), (timer) {
///定时任务
// print("timer index0:$index");
if(index >= 5){
// 当超过5秒的时候取消定时任务 弹窗显示连接失败
completer.complete();
timer.cancel();
connectDeviceMacAddress = "";
// deviceConnectionState = DeviceConnectionState.disconnected;
// print("timer index1:$index");
connectStateCallBack(DeviceConnectionState.disconnected);
}else{
// 每秒判断数组列表里面是否有这个设备
final knownDeviceIndex = scanDevices.indexWhere((d) => d.name == deviceName);
if (knownDeviceIndex >= 0) {
// 存在的时候销毁定时器,赋值
completer.complete();
timer.cancel();
// print("timer index2:$index");
connectDeviceMacAddress = scanDevices[knownDeviceIndex].id;
} else {
// 不存在的时候返回-1 然后循环5秒
index++;
print("index:$index 没有找到设备");
}
}
});
// 等待Completer完成
await completer.future;
}
print("connectDeviceId:$connectDeviceMacAddress connectDeviceName:$connectDeviceName");
if(connectDeviceMacAddress.isEmpty){
return;
}
_currentConnectionStream = _flutterReactiveBle!.connectToDevice(id: connectDeviceMacAddress, connectionTimeout: const Duration(seconds: 10)).listen((connectionStateUpdate) async {
// 获取状态
deviceConnectionState = connectionStateUpdate.connectionState;
print('deviceConnectionState:$deviceConnectionState connectionStateUpdate.connectionState:${connectionStateUpdate.connectionState}');
if(connectionStateUpdate.connectionState == DeviceConnectionState.connected){
// 如果状态是连接的开始发现服务
try {
_subScribeToCharacteristic(QualifiedCharacteristic(characteristicId: characteristicIdSubscription, serviceId: serviceIdConnect, deviceId: connectDeviceMacAddress));
print('Discovering services finished');
// if(isFrist == true){
// // 第一次添加锁的时候需要先获取公钥
// IoSenderManage.getPublicKey(lockId: deviceName);
// }
deviceConnectionState = connectionStateUpdate.connectionState;
connectStateCallBack(deviceConnectionState!);
} on Exception catch (e) {
deviceConnectionState = DeviceConnectionState.disconnected;
connectStateCallBack(deviceConnectionState!);
print('Error occurred when discovering services: $e');
rethrow;
}
} else{
deviceConnectionState = connectionStateUpdate.connectionState;
connectStateCallBack(deviceConnectionState!);
}
print('ConnectionState for device $connectDeviceMacAddress : ${connectionStateUpdate.connectionState}');
}, onError: (Object e){
deviceConnectionState = DeviceConnectionState.disconnected;
connectStateCallBack(deviceConnectionState!);
print('Connecting to device $connectDeviceMacAddress resulted in error $e');
}
);
}
// 听上报来的数据,参数来自前面扫描到的结果
var allData = <int>[];
_subScribeToCharacteristic(QualifiedCharacteristic characteristic) {
_flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen((data) {
// code to handle incoming data
print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data");
var dataLen = 0;// 高16位用来指示后面数据块内容的长度
if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)){
// 当包有头时
// 判断是否需要分包
dataLen = data[8] * 256 + data[9];
// print("dataLen1111:$dataLen getDataLength:${data.length}");
if(dataLen + 12 > data.length){
// 当前包的长度小于实际的包时 分包添加 不解析
allData.addAll(data);
}else{
// 当前包的长度小于实际的包时 不分包 解析
allData.addAll(data);
CommandReciverManager.appDataReceive(allData);
// 发送完解析初始化数组
allData = <int>[];
}
}else{
// 当包没有头时 是分包的包 直接添加
allData.addAll(data);
// var len = allData[8] * 256 + allData[9];
// print("dataLen222:$dataLen");
if(dataLen <= (allData.length - 14)){
// 当长度小于等于当前包的数据时 直接解析数据
CommandReciverManager.appDataReceive(allData);
// 发送完解析初始化数组
allData = <int>[];
}
}
}, onError: (dynamic error) {
EasyLoading.dismiss();
print("subscribeToCharacteristic error:$error");
});
}
// 写入
Future<void> writeCharacteristicWithResponse(List<int> value) async {
QualifiedCharacteristic characteristic = QualifiedCharacteristic(characteristicId: characteristicIdWrite, serviceId: serviceIdWrite, deviceId: connectDeviceMacAddress);
int mtuLength = await _flutterReactiveBle!.requestMtu(deviceId: characteristic.deviceId, mtu: 250);
print("mtuLength:$mtuLength");
try {
List<int> valueList = value;
List subData = splitList(valueList, mtuLength);
print('得到的分割数据:$subData');
for (int i = 0; i < subData.length; i++) {
await _flutterReactiveBle!.writeCharacteristicWithResponse(characteristic, value: subData[i]).then((value) async {
await Future.delayed(const Duration(milliseconds: 1))
.then((value) async {
print('分包发送成功了');
});
});
}
} on Exception catch (e, s) {
print('Error occurred when writing: $e');
// ignore: avoid_print
print(s);
rethrow;
}
}
// 读取
Future<List<int>> _readCharacteristic(QualifiedCharacteristic characteristic) async {
try {
final result = await _flutterReactiveBle!.readCharacteristic(characteristic);
print("readListresult$result");
return result;
} on Exception catch (e, s) {
print('Error occurred when reading ${characteristic.characteristicId} : $e',);
rethrow;
}
}
Future<void> writeCharacteristicWithoutResponse(
QualifiedCharacteristic characteristic, List<int> value) async {
try {
await _flutterReactiveBle!.writeCharacteristicWithoutResponse(characteristic,
value: value);
} on Exception catch (e, s) {
// ignore: avoid_print
print(s);
rethrow;
}
}
// 停止扫描蓝牙设备
// Future<void> stopScan() async {
// await _scanSubscription?.cancel();
// _scanSubscription = null;
// }
// 断开连接
Future<void> disconnect(String deviceMAC) async {
try {
_currentConnectionStream?.cancel();
print('disconnecting to device: $deviceMAC');
} on Exception catch (e, _) {
print("Error disconnecting from a device: $e");
} finally {
deviceConnectionState = DeviceConnectionState.disconnected;
}
}
disposed(){
_sendStreamSubscription?.cancel();
_currentConnectionStream?.cancel();
_scanSubscription?.cancel();
}
}