From 438f8d1e2d394972b768f79037a8fad5127309f5 Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Fri, 13 Jun 2025 12:06:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9ota=E5=8D=87=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/ota_upgrade_controller.dart | 7 +- .../ota/ios/Classes/BleManager/JLBleManager.h | 3 + .../ota/ios/Classes/BleManager/JLBleManager.m | 89 ++++++++++++++++--- local_plugins/ota/ios/Classes/OtaPlugin.swift | 35 ++++++-- local_plugins/ota/lib/ota.dart | 4 + local_plugins/ota/lib/ota_method_channel.dart | 5 ++ .../ota/lib/ota_platform_interface.dart | 4 + 7 files changed, 126 insertions(+), 21 deletions(-) diff --git a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart index 63536be30..25e6188ce 100644 --- a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart +++ b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart @@ -58,6 +58,7 @@ class OtaUpgradeController extends GetxController { final RxDouble progress = 0.0.obs; // 控制器自己的可观察属性 final RxInt type = OtaEvent.NOT_STARTED.obs; final RxBool isUpgrade = false.obs; + @override void onInit() { super.onInit(); @@ -156,7 +157,7 @@ class OtaUpgradeController extends GetxController { final firstPart = firmwareParts.sublist(0, 3).join('.'); final secondPart = firmwareParts.sublist(3).join('.'); print("firstPart${firstPart},secondPart=${secondPart}"); -// 判断两部分是否一致 + // 判断两部分是否一致 if (firstPart != secondPart) { throw "固件版本格式错误:${deviceInfo.firmwareVersion}"; } @@ -164,6 +165,9 @@ class OtaUpgradeController extends GetxController { // 正常流程 currentVersion.value = firstPart; print('getequipmentinfo,id: ${deviceInfo.firmwareProductId}'); + + jlota.init(); + // API请求 final response = await Api.getequipmentinfo({ "id": deviceInfo.firmwareProductId, @@ -402,6 +406,7 @@ class OtaUpgradeController extends GetxController { if (event.event == 'onError') { type.value = OtaEvent.UPGRADE_FAILED; isUpgrade.value = false; + Get.snackbar('升级失败', '请检查设备连接或升级包'); } if (event.event == 'NOCONNECTION') { type.value = OtaEvent.CONNECTION_DISCONNECTION; diff --git a/local_plugins/ota/ios/Classes/BleManager/JLBleManager.h b/local_plugins/ota/ios/Classes/BleManager/JLBleManager.h index f768de83a..b72e4247f 100644 --- a/local_plugins/ota/ios/Classes/BleManager/JLBleManager.h +++ b/local_plugins/ota/ios/Classes/BleManager/JLBleManager.h @@ -15,6 +15,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -63,6 +64,8 @@ extern NSString *kFLT_BLE_DISCONNECTED; //断开连接 @property (strong, nonatomic) JLBleEntity *__nullable currentEntity; +@property (nonatomic, copy, nullable) FlutterEventSink flutterEventSink; + /** * 单例 */ diff --git a/local_plugins/ota/ios/Classes/BleManager/JLBleManager.m b/local_plugins/ota/ios/Classes/BleManager/JLBleManager.m index 1fd281682..a7087124e 100644 --- a/local_plugins/ota/ios/Classes/BleManager/JLBleManager.m +++ b/local_plugins/ota/ios/Classes/BleManager/JLBleManager.m @@ -206,8 +206,17 @@ NSString *FLT_BLE_RCSP_R = @"AE02"; //命令“读”通道 if (ble_name.length == 0) return; kJLLog(JLLOG_DEBUG, @"发现 ----> NAME:%@ RSSI:%@ AD:%@", ble_name,RSSI,ble_AD); - - [self addPeripheral:peripheral RSSI:RSSI Name:ble_name Info:ble_AD]; + + if (ble_AD.length >= 29) { + const uint8_t *bytes = ble_AD.bytes; + NSMutableString *macStr = [NSMutableString string]; + for (int i = 7; i <= 12; i++) { + uint8_t macByte = bytes[i] ^ 0x5A; + [macStr appendFormat:@"%02X", macByte]; + if (i < 12) [macStr appendString:@":"]; + } + [self addPeripheral:peripheral Info:macStr]; + } [[NSNotificationCenter defaultCenter] postNotificationName:kFLT_BLE_FOUND object:_blePeripheralArr userInfo:nil]; @@ -217,11 +226,11 @@ NSString *FLT_BLE_RCSP_R = @"AE02"; //命令“读”通道 } } -- (void)addPeripheral:(CBPeripheral*)peripheral RSSI:(NSNumber *)rssi Name:(NSString*)name Info:(NSData*)blead{ -// if ([name isEqualToString:@"DeapSound"]) { -// [self stopScanBLE]; -// [self connectBLE:peripheral]; -// } +- (void)addPeripheral:(CBPeripheral*)peripheral Info:(NSString*)macStr { + if (self.lastAddress && [macStr isEqualToString:self.lastAddress]) { + [self stopScanBLE]; + [self connectBLE:peripheral]; + } } #pragma mark 设备连接回调 @@ -349,13 +358,7 @@ NSString *FLT_BLE_RCSP_R = @"AE02"; //命令“读”通道 if (needForcedUpgrade) { kJLLog(JLLOG_DEBUG, @"设备需要强制升级,请到升级界面选择ota升级文件进行升级!"); } - NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; - NSString *otaFilePath = [documentsPath stringByAppendingPathComponent:@"update030.ufw"]; - if ([[NSFileManager defaultManager] fileExistsAtPath:otaFilePath]) { - [self otaFuncWithFilePath:otaFilePath]; - } else { - kJLLog(JLLOG_DEBUG, @"OTA文件不存在: %@", otaFilePath); - } + [self otaFuncWithFilePath:self.lastFilePath]; }]; }); } @@ -396,6 +399,15 @@ NSString *FLT_BLE_RCSP_R = @"AE02"; //命令“读”通道 */ - (void)otaFuncWithFilePath:(NSString *)otaFilePath { kJLLog(JLLOG_DEBUG, @"current otaFilePath ---> %@", otaFilePath); + if (self.flutterEventSink) { + self.flutterEventSink(@{ + @"event": @"onStartOTA", + @"type": @0, + @"progress": @0.0, + @"code": @8, + @"message": @"开始升级" + }); + } self.selectedOtaFilePath = otaFilePath; NSData *otaData = [[NSData alloc] initWithContentsOfFile:otaFilePath]; @@ -425,6 +437,55 @@ NSString *FLT_BLE_RCSP_R = @"AE02"; //命令“读”通道 -(void)otaUpgradeResult:(JL_OTAResult)result Progress:(float)progress{ //TODO: 设备升级过程回调,包括进度状态 kJLLog(JLLOG_DEBUG, @"otaUpgradeResult ---> %u", result); + if (result == JL_OTAResultPreparing) { + if (self.flutterEventSink) { + self.flutterEventSink(@{ + @"event": @"onProgress", + @"type": @0, + @"progress": @(progress * 100), + @"code": @(result), + @"message": @"开始升级" + }); + } + } else if (result == JL_OTAResultUpgrading) { + if (self.flutterEventSink) { + self.flutterEventSink(@{ + @"event": @"onProgress", + @"type": @1, + @"progress": @(progress * 100), + @"code": @(result), + @"message": @"开始升级" + }); + } + } else if (result == JL_OTAResultPrepared) { + + } else if (result == JL_OTAResultReconnect) { + + } else if (result == JL_OTAResultReconnectWithMacAddr) { + + } else if (result == JL_OTAResultSuccess) { + if (self.flutterEventSink) { + self.flutterEventSink(@{ + @"event": @"onStopOTA", + @"type": @0, + @"progress": @0.0, + @"code": @(result), + @"message": @"升级成功" + }); + } + } else if (result == JL_OTAResultReboot) { + + } else { + if (self.flutterEventSink) { + self.flutterEventSink(@{ + @"event": @"onError", + @"type": @0, + @"progress": @0.0, + @"code": @(result), + @"message": @"升级失败" + }); + } + } } -(void)otaDataSend:(NSData *)data{ diff --git a/local_plugins/ota/ios/Classes/OtaPlugin.swift b/local_plugins/ota/ios/Classes/OtaPlugin.swift index 7286ad364..1b6514e57 100644 --- a/local_plugins/ota/ios/Classes/OtaPlugin.swift +++ b/local_plugins/ota/ios/Classes/OtaPlugin.swift @@ -1,18 +1,24 @@ import Flutter -public class OtaPlugin: NSObject, FlutterPlugin { - let userManager = JLBleManager.sharedInstance() +public class OtaPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { + var userManager: JLBleManager? + var eventSink: FlutterEventSink? public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "ota", binaryMessenger: registrar.messenger()) + let eventChannel = FlutterEventChannel(name: "com.example.ota/events", binaryMessenger: registrar.messenger()) let instance = OtaPlugin() registrar.addMethodCallDelegate(instance, channel: channel) + eventChannel.setStreamHandler(instance) } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? [String: Any] switch call.method { + case "init": + userManager = JLBleManager.sharedInstance() + result("") case "startUpgrading": let address = arguments?["address"] as? String let filePath = arguments?["filePath"] as? String @@ -26,14 +32,31 @@ public class OtaPlugin: NSObject, FlutterPlugin { } } + public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { + eventSink = events + return nil + } + + public func onCancel(withArguments arguments: Any?) -> FlutterError? { + eventSink = nil + userManager?.flutterEventSink = nil + return nil + } + private func startUpgrading(address: String?, filePath: String?) { - if userManager.mBleManagerState == CBManagerState.poweredOn { - userManager.startScanBLE(address, filePath: filePath) + if userManager?.mBleManagerState == CBManagerState.poweredOn { + userManager?.flutterEventSink = eventSink + userManager?.startScanBLE(address, filePath: filePath) DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) { - self.userManager.stopScanBLE() + self.userManager?.stopScanBLE() } } } - private func onOtaClose() {} + private func onOtaClose() { + userManager?.stopScanBLE() + userManager?.otaFuncCancel{code in} + userManager?.disconnectBLE() + userManager = nil + } } diff --git a/local_plugins/ota/lib/ota.dart b/local_plugins/ota/lib/ota.dart index 2919d9107..79c2948f9 100644 --- a/local_plugins/ota/lib/ota.dart +++ b/local_plugins/ota/lib/ota.dart @@ -132,6 +132,10 @@ class Ota { // _isEventListenerSet = true; // } + Future init() { + return OtaPlatform.instance.init(); + } + Future startUpgrading({String? address, String? filePath}) { return OtaPlatform.instance.startUpgrading( address: address, diff --git a/local_plugins/ota/lib/ota_method_channel.dart b/local_plugins/ota/lib/ota_method_channel.dart index cc3890635..83203825c 100644 --- a/local_plugins/ota/lib/ota_method_channel.dart +++ b/local_plugins/ota/lib/ota_method_channel.dart @@ -9,6 +9,11 @@ class MethodChannelOta extends OtaPlatform { @visibleForTesting final methodChannel = const MethodChannel('ota'); + @override + Future init() async { + await methodChannel.invokeMethod('init'); + } + @override Future startUpgrading({String? address, String? filePath}) async { await methodChannel.invokeMethod('startUpgrading', { diff --git a/local_plugins/ota/lib/ota_platform_interface.dart b/local_plugins/ota/lib/ota_platform_interface.dart index 026414e86..a1a271b13 100644 --- a/local_plugins/ota/lib/ota_platform_interface.dart +++ b/local_plugins/ota/lib/ota_platform_interface.dart @@ -23,6 +23,10 @@ abstract class OtaPlatform extends PlatformInterface { _instance = instance; } + Future init() { + throw UnimplementedError('init() has not been implemented.'); + } + Future startUpgrading({String? address, String? filePath}) { throw UnimplementedError('startUpgrading() has not been implemented.'); }