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