Browse Source

ota升级断开ble连接

weicu
tanlongsheng 1 year ago
parent
commit
7ad217a649
  1. 18
      lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart
  2. 39
      local_plugins/ble_service/ios/ble_service/Sources/ble_service/BleService.swift
  3. 11
      local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftBleServicePlugin.swift
  4. 56
      local_plugins/ble_service/lib/ble_service.dart

18
lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart

@ -1,3 +1,5 @@
import 'package:ble_service/ble_service.dart';
import 'package:classic_bluetooth/classic_bluetooth.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:path/path.dart';
@ -30,6 +32,8 @@ class OtaUpgradeController extends GetxController {
// 当前设备固件版本号
final RxString currentVersion = ''.obs;
String _address = '';
// 更新包地址,用于下载更新文件
String updatepackageaddress = '';
@ -50,6 +54,7 @@ class OtaUpgradeController extends GetxController {
// 蓝牙管理服务,用于获取设备信息和通信
final _bleManager = Get.find<BleManager>();
final BleService _bleService = BleService();
final maxRetryAttempts = 3; // 最大重试次数
int currentRetryCount = 0;
@ -68,6 +73,7 @@ class OtaUpgradeController extends GetxController {
@override
void onClose() {
jlota.onOtaClose();
_bleService.setEnterOta(false);
isUpgrade.value = false;
super.onClose();
}
@ -166,6 +172,16 @@ class OtaUpgradeController extends GetxController {
currentVersion.value = firstPart;
print('getequipmentinfo,id: ${deviceInfo.firmwareProductId}');
final connectedDevices = await ClassicBluetooth.getConnectedDevices();
if (connectedDevices.isNotEmpty) {
_address = connectedDevices.first.address;
}
await _bleService.setEnterOta(true);
await _bleService.disconnect();
await Future.delayed(const Duration(seconds: 2));
jlota.init();
// API请求
@ -372,7 +388,7 @@ class OtaUpgradeController extends GetxController {
// 开始升级
void startUpgrading(String path) async {
jlota.startUpgrading(address: 'E9:09:05:E0:18:7A', filePath: path);
jlota.startUpgrading(address: _address, filePath: path);
return;
// isUpgrade.value = false;
}

39
local_plugins/ble_service/ios/ble_service/Sources/ble_service/BleService.swift

@ -43,6 +43,10 @@ public class BleService: NSObject {
private var audioCharacteristic: CBCharacteristic?
private var isScanning = false
// 是否是ota模式
var isEnterOta = false
private var callbacks = [Callback]()
private var connectionState = BleConst.STATE_DISCONNECTED
@ -212,6 +216,9 @@ public class BleService: NSObject {
/// 统一的连接方法,支持恢复和重连
private func connectPeripheral(_ peripheral: CBPeripheral) {
if isEnterOta {
return
}
guard let manager = centralManager else {
return
}
@ -592,19 +599,14 @@ public class BleService: NSObject {
]
if !responseData.isEmpty {
if let versionStr = String(data: responseData, encoding: .utf8) {
resultMap["version"] = versionStr
os_log("接收到目标版本号: %@", log: logger, type: .info, versionStr)
} else {
// 如果无法解析为字符串,以点分隔的数字表示版本
let versionNums = responseData
.map { $0 }
.filter { $0 != 0xFF } // 过滤掉无效字节
.map { String($0) }
.joined(separator: ".")
resultMap["version"] = versionNums
os_log("接收到目标版本号(数字格式): %@", log: logger, type: .info, versionNums)
}
// 如果无法解析为字符串,以点分隔的数字表示版本
let versionNums = responseData
.map { $0 }
.filter { $0 != 0xFF } // 过滤掉无效字节
.map { String($0) }
.joined(separator: ".")
resultMap["version"] = versionNums
os_log("接收到目标版本号(数字格式): %@", log: logger, type: .info, versionNums)
}
notifyDeviceInfoReceived(infoType: Int(cmd), infoData: resultMap)
@ -616,13 +618,8 @@ public class BleService: NSObject {
"rawData": responseData
]
if responseData.count >= 2 {
let productId = UInt16(responseData[0]) << 8 | UInt16(responseData[1])
resultMap["productId"] = productId
os_log("接收到产品ID: %d", log: logger, type: .info, productId)
} else if !responseData.isEmpty {
// 单字节产品ID
let productId = UInt16(responseData[0])
if !responseData.isEmpty {
let productId = responseData.map { String($0 & 0xFF) }.joined(separator: ".")
resultMap["productId"] = productId
os_log("接收到产品ID: %d", log: logger, type: .info, productId)
}
@ -1263,4 +1260,4 @@ extension BleService: CBPeripheralDelegate {
os_log("✅ 描述符写入成功: %{public}@", log: logger, type: .debug, descriptor.uuid.uuidString)
}
}
}
}

11
local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftBleServicePlugin.swift

@ -150,6 +150,15 @@ public class SwiftBleServicePlugin: NSObject, FlutterPlugin {
case "isBleConnected":
result(BleService.shared.isConnected())
case "setEnterOta":
let arguments = call.arguments as? [String: Any]
BleService.shared.isEnterOta = (arguments?["enterOta"] as? Bool) ?? false
result("")
case "disconnect":
BleService.shared.disconnect()
result("")
case "registerBackgroundScan", "unregisterBackgroundScan":
// iOS上禁用,直接返回成功以避免Flutter端报错
@ -380,4 +389,4 @@ class BleStatusStreamHandler: NSObject, FlutterStreamHandler {
plugin?.statusEventSink = nil
return nil
}
}
}

56
local_plugins/ble_service/lib/ble_service.dart

@ -183,34 +183,35 @@ class BleService {
return false;
}
}
//========================================================================
// 以下是Companion Device相关功能
//========================================================================
/// 检查设备是否支持Companion Device Manager
///
///
/// 返回设备是否支持Companion Device Manager API
/// 仅在Android 8.0及以上版本可用
Future<bool> isCompanionSupported() async {
try {
final result = await _methodChannel.invokeMethod<bool>('isCompanionSupported');
final result =
await _methodChannel.invokeMethod<bool>('isCompanionSupported');
return result ?? false;
} catch (e) {
print('检查Companion设备支持失败: $e');
return false;
}
}
/// 启动设备关联流程
///
///
/// 弹出系统设备选择对话框,用户选择后将建立持久化关联
/// 关联成功后,应用将获得后台扫描和启动前台服务的特权
///
///
/// [deviceNamePattern] 设备名称正则表达式,例如"MyHeadset.*"
/// [serviceUuid] 可选的服务UUID
/// [macAddress] 可选的MAC地址
///
///
/// 返回是否成功启动关联流程
Future<bool> startDeviceAssociation({
String? deviceNamePattern,
@ -232,13 +233,14 @@ class BleService {
return false;
}
}
/// 获取已关联的设备MAC地址
///
///
/// 返回已关联的设备MAC地址,如果没有则返回null
Future<String?> getPairedMacAddress() async {
try {
final result = await _methodChannel.invokeMethod<String>('getPairedMacAddress');
final result =
await _methodChannel.invokeMethod<String>('getPairedMacAddress');
return result;
} catch (e) {
print('获取配对MAC地址失败: $e');
@ -246,9 +248,8 @@ class BleService {
}
}
/// 检查BLE连接状态
///
///
/// 返回BLE是否已连接
Future<bool> isBleConnected() async {
try {
@ -260,11 +261,31 @@ class BleService {
}
}
/// 设置是否是ota模式
Future<void> setEnterOta(bool enterOta) async {
try {
await _methodChannel.invokeMethod<String>('setEnterOta', {
'enterOta': enterOta,
});
} catch (e) {
print('设置是否是ota模式失败: $e');
}
}
/// 断开连接
Future<void> disconnect() async {
try {
await _methodChannel.invokeMethod<String>('disconnect');
} catch (e) {
print('断开连接失败: $e');
}
}
/// 注册BLE后台扫描
///
/// 注册后,即使应用被杀死,系统也会在检测到设备广播时唤醒应用
/// 这是确保设备可以在应用后台时被自动连接的关键功能
///
///
/// [macAddress] 可选的设备MAC地址,如果不提供则使用已关联的设备
Future<bool> registerBackgroundScan({String? macAddress}) async {
try {
@ -290,13 +311,14 @@ class BleService {
return false;
}
}
/// 清除所有设备关联
///
///
/// 用于重置设备关联状态,通常在用户主动解除关联或调试时使用
Future<bool> clearAssociations() async {
try {
final result = await _methodChannel.invokeMethod<bool>('clearAssociations');
final result =
await _methodChannel.invokeMethod<bool>('clearAssociations');
return result ?? false;
} catch (e) {
print('清除设备关联失败: $e');

Loading…
Cancel
Save