app-starlock/star_lock/lib/blue/blue_manage.dart
Daisy 62f3c9fdd3 Merge branch 'talk_flutter'
# Conflicts:
#	star_lock/ios/Podfile.lock
#	star_lock/lib/blue/blue_manage.dart
#	star_lock/lib/main.dart
#	star_lock/lib/main/lockDetail/lcokSet/lockSet/lockSet_page.dart
#	star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart
#	star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart
#	star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart
2024-01-02 15:42:41 +08:00

349 lines
12 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:star_lock/blue/sender_manage.dart';
import '../tools/toast.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 serviceId = 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() {
_flutterReactiveBle ??= FlutterReactiveBle();
print("蓝牙功能初始化了");
_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> connect(
String deviceName, ConnectStateCallBack connectStateCallBack,
{bool? isFrist = false, bool isShowLoading = true}) 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 index:$index");
if (index >= 4) {
// 当超过5秒的时候取消定时任务 弹窗显示连接失败
completer.complete();
timer.cancel();
connectDeviceMacAddress = "";
deviceConnectionState = DeviceConnectionState.disconnected;
connectStateCallBack(deviceConnectionState!);
Toast.show(msg: "未扫描到要连接的设备,请确保在设备附近,设备未被连接,设备已打开");
} else {
// 每秒判断数组列表里面是否有这个设备
final knownDeviceIndex =
scanDevices.indexWhere((d) => d.name == deviceName);
if (knownDeviceIndex >= 0) {
// 存在的时候销毁定时器,赋值
completer.complete();
timer.cancel();
connectDeviceMacAddress = scanDevices[knownDeviceIndex].id;
} else {
// 不存在的时候返回-1 然后循环5秒
index++;
print("index:$index 没有找到设备");
}
}
});
// 等待Completer完成
await completer.future;
// print("111111");
}
print(
"connectDeviceId:$connectDeviceMacAddress connectDeviceName:$connectDeviceName");
if (connectDeviceMacAddress.isEmpty) {
return;
}
_currentConnectionStream = _flutterReactiveBle!
.connectToDevice(
id: connectDeviceMacAddress,
connectionTimeout: const Duration(milliseconds: 10000))
.listen((connectionStateUpdate) async {
// 获取状态
deviceConnectionState = connectionStateUpdate.connectionState;
print(
'deviceConnectionState:$deviceConnectionState connectionStateUpdate.connectionState:${connectionStateUpdate.connectionState}');
if (connectionStateUpdate.connectionState ==
DeviceConnectionState.connected) {
// 如果状态是连接的开始发现服务
try {
_subScribeToCharacteristic(QualifiedCharacteristic(
characteristicId: characteristicIdSubscription,
serviceId: Uuid.parse("fff0"),
deviceId: connectDeviceMacAddress));
print('Discovering services finished');
if (isFrist == true) {
// 第一次添加锁的时候需要先获取公钥
IoSenderManage.getPublicKey(lockId: deviceName);
}
// print("333333:$deviceConnectionState");
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');
});
}
// 重新连接
Future<void> judgeReconnect(
String deviceName, ConnectStateCallBack stateCallBack,
{bool isShowLoading = true}) async {
if (deviceConnectionState != DeviceConnectionState.connected) {
connect(deviceName, (state) {
stateCallBack(deviceConnectionState!);
}, isShowLoading: false);
} else {
stateCallBack(deviceConnectionState!);
}
}
// 听上报来的数据,参数来自前面扫描到的结果
var allData = <int>[];
int? dataLen;
_subScribeToCharacteristic(QualifiedCharacteristic characteristic) {
_flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen(
(data) {
// code to handle incoming data
print(
"subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data");
if ((data[0] == 0xEF) &&
(data[1] == 0x01) &&
(data[2] == 0xEE) &&
(data[3] == 0x02)) {
// 当包有头时
// 判断是否需要分包
dataLen = data[8] * 256 + data[9]; // 高16位用来指示后面数据块内容的长度
print("dataLen1111:$dataLen getDataLength:${data.length}");
if (dataLen! + 12 > data.length) {
// 当前包的长度小于实际的包时 分包添加 不解析
allData.addAll(data);
} else {
// 当前包的长度小于实际的包时 不分包 解析
allData.addAll(data);
print("dataLen2222:$dataLen getDataLength:${data.length}");
CommandReciverManager.appDataReceive(allData);
// 发送完解析初始化数组
allData = <int>[];
}
} else {
// 当包没有头时 是分包的包 直接添加
allData.addAll(data);
// var len = allData[8] * 256 + allData[9];
print("dataLen3333:$dataLen");
if ((dataLen! + 14) <= allData.length) {
print("44444数据被解析了");
// 当长度小于等于当前包的数据时 直接解析数据
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: serviceId,
deviceId: connectDeviceMacAddress);
// print('Write with characteristicId${characteristic.characteristicId} serviceId${characteristic.serviceId} deviceId${characteristic.deviceId} value : $value \nhexStr:${radixHex16String(value)}');
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;
// _currentConnectionStream = null;
}
}
disposed() {
_sendStreamSubscription?.cancel();
_currentConnectionStream?.cancel();
_scanSubscription?.cancel();
}
}