From 0669b7b682f4ae0f4dc192f066a066bc6f010045 Mon Sep 17 00:00:00 2001 From: wolfplus Date: Sat, 22 Mar 2025 11:22:26 +0000 Subject: [PATCH] v002ios --- ios/Runner/AzureAsrHelper.swift | 60 ++++++++++++---------- ios/Runner/ClassicBluetoothHelper.swift | 68 ++++++++++++++++++++++--- 2 files changed, 93 insertions(+), 35 deletions(-) diff --git a/ios/Runner/AzureAsrHelper.swift b/ios/Runner/AzureAsrHelper.swift index c799f8f9f..82deddfba 100644 --- a/ios/Runner/AzureAsrHelper.swift +++ b/ios/Runner/AzureAsrHelper.swift @@ -328,37 +328,43 @@ class AzureAsrHelper: NSObject { print("[AzureAsrHelper] 停止连续语音识别") - do { - // 防止空指针异常 - guard let recognizer = recognizer else { - print("[AzureAsrHelper] 警告: 识别器为空,但状态显示活跃") - _isContinuousRecognitionActive = false - eventHandler("sessionStopped", [:]) - return true - } - - // 尝试停止 - try recognizer.stopContinuousRecognition() - - // 标记为非活跃状态 + // 防止空指针异常 + guard let recognizer = recognizer else { + print("[AzureAsrHelper] 警告: 识别器为空,但状态显示活跃") _isContinuousRecognitionActive = false - - print("[AzureAsrHelper] 连续识别已停止") - return true - } catch { - print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)") - - // 即使失败,也将状态设置为非活跃 - _isContinuousRecognitionActive = false - - // 发送停止事件,确保上层知道识别已经结束 eventHandler("sessionStopped", [:]) + return true + } + + // 先标记为非活跃状态,防止重复调用 + _isContinuousRecognitionActive = false + + // 异步执行停止操作,避免阻塞主线程 + DispatchQueue.global(qos: .userInitiated).async { [weak self] in + guard let self = self else { return } - // 尝试释放和重新创建识别器 - recognizer = nil - - return false + do { + // 在后台线程执行停止操作 + try recognizer.stopContinuousRecognition() + + // 主线程回调通知结果 + DispatchQueue.main.async { + print("[AzureAsrHelper] 连续识别已停止") + self.eventHandler("sessionStopped", [:]) + } + } catch { + // 主线程回调通知错误 + DispatchQueue.main.async { + print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)") + // 停止失败,恢复状态 + self._isContinuousRecognitionActive = true + self.eventHandler("error", ["error": "停止识别失败: \(error.localizedDescription)"]) + } + } } + + // 立即返回,不阻塞调用方 + return true } /// 检查连续识别是否活跃 diff --git a/ios/Runner/ClassicBluetoothHelper.swift b/ios/Runner/ClassicBluetoothHelper.swift index 9fffd1e41..6bea951df 100644 --- a/ios/Runner/ClassicBluetoothHelper.swift +++ b/ios/Runner/ClassicBluetoothHelper.swift @@ -8,13 +8,15 @@ import UIKit func sendEvent(_ event: [String: Any]) } -@objc class ClassicBluetoothHelper: NSObject { +@objc class ClassicBluetoothHelper: NSObject, CBCentralManagerDelegate { // MARK: - 属性 // 音频会话管理器 private let audioSessionManager = AudioSessionManager.shared - + // 蓝牙管理器 + private var centralManager: CBCentralManager? + // 事件处理器 private weak var eventHandler: BluetoothEventHandler? @@ -28,7 +30,14 @@ import UIKit @objc func setEventHandler(_ handler: BluetoothEventHandler) { eventHandler = handler } + + // MARK: - CBCentralManagerDelegate + + func centralManagerDidUpdateState(_ central: CBCentralManager) { + let stateString = getBluetoothStateString(state: central.state) + sendBluetoothStateEvent(state: stateString) + } // MARK: - 设备监控 @@ -56,7 +65,20 @@ import UIKit // 启动蓝牙设备监控 @objc func startBluetoothDeviceMonitoring() { + if centralManager == nil { + centralManager = CBCentralManager(delegate: self, queue: nil) + } + + + + // 发送当前蓝牙状态 + if let manager = centralManager { + let stateString = getBluetoothStateString(state: manager.state) + sendBluetoothStateEvent(state: stateString) + } + // 移除之前的监听器 NotificationCenter.default.removeObserver(self) + // 添加新的监听器 audioSessionManager.addRouteChangeListener(self, selector: #selector(handleRouteChange(_:))) BluetoothMediaButtonHelper.shared.startButtonListening() } @@ -108,23 +130,41 @@ import UIKit // MARK: - 设备事件 - // 发送设备已连接事件 + // 发送设备连接事件 private func sendDeviceConnectedEvent(device: [String: String]) { + guard let name = device["name"], let address = device["address"] else { return } + + let deviceMap: [String: Any] = [ + "name": name, + "address": address, + "type": "headset" + ] + let event: [String: Any] = [ "type": "deviceConnected", - "device": device, + "device": deviceMap, "timestamp": Int(Date().timeIntervalSince1970 * 1000) ] + eventHandler?.sendEvent(event) } - // 发送设备已断开事件 + // 发送设备断开事件 private func sendDeviceDisconnectedEvent(device: [String: String]) { + guard let name = device["name"], let address = device["address"] else { return } + + let deviceMap: [String: Any] = [ + "name": name, + "address": address, + "type": "headset" + ] + let event: [String: Any] = [ "type": "deviceDisconnected", - "device": device, + "device": deviceMap, "timestamp": Int(Date().timeIntervalSince1970 * 1000) ] + eventHandler?.sendEvent(event) } @@ -132,7 +172,12 @@ import UIKit // 获取当前连接的耳机设备 @objc func getConnectedHeadsetDevices(_ completion: @escaping ([[String: String]]?, String?) -> Void) { - + // 检查蓝牙状态 + if centralManager?.state != .poweredOn { + completion(nil, "蓝牙未启用") + return + } + do { // 获取设备 let devices = getConnectedAudioDevices() @@ -160,11 +205,18 @@ import UIKit return result } + + // 释放资源 + @objc func dispose() { + audioSessionManager.removeRouteChangeListener(self) + eventHandler = nil + } + // 检查蓝牙是否启用 @objc func isBluetoothEnabled() -> Bool { - return audioSessionManager.isBluetoothEnabled() + return centralManager?.state == .poweredOn } // 清理设备地址,移除后缀