From a4dbf2228b8893e49f58ba3d76b82f92e197e5b3 Mon Sep 17 00:00:00 2001 From: wolfplus Date: Sun, 9 Mar 2025 16:05:49 +0000 Subject: [PATCH] v005.fix --- .../com/example/deep_voice/MainActivity.kt | 45 ++++- .../deep_voice/VoiceInteractionService.kt | 182 +++++++++++++++--- lib/core/bindings/initial_binding.dart | 2 +- .../services/voice_interaction_service.dart | 150 ++++++++++----- .../chat/controllers/chat_controller.dart | 78 +------- 5 files changed, 305 insertions(+), 152 deletions(-) diff --git a/android/app/src/main/kotlin/com/example/deep_voice/MainActivity.kt b/android/app/src/main/kotlin/com/example/deep_voice/MainActivity.kt index cad447104..d0ac2a7b1 100644 --- a/android/app/src/main/kotlin/com/example/deep_voice/MainActivity.kt +++ b/android/app/src/main/kotlin/com/example/deep_voice/MainActivity.kt @@ -82,8 +82,9 @@ class MainActivity: FlutterActivity() { // 注册广播接收器 registerVoiceInteractionReceiver() - // 不再自动启动服务,由用户通过 Flutter 界面手动启动 - Log.d(TAG, "MainActivity 已创建,但不会自动启动 VoiceInteractionService") + // 自动启动语音交互服务 + Log.d(TAG, "MainActivity 已创建,自动启动 VoiceInteractionService") + autoStartVoiceInteractionService() // 确保 Flutter 引擎准备好后立即设置事件通道 flutterEngine?.let { engine -> @@ -569,6 +570,46 @@ class MainActivity: FlutterActivity() { } } + /** + * 自动启动语音交互服务 + */ + private fun autoStartVoiceInteractionService() { + // 检查服务是否已经在运行 + if (VoiceInteractionService.isServiceRunning()) { + Log.d(TAG, "语音交互服务已经在运行,无需重复启动") + return + } + + Log.d(TAG, "自动启动语音交互服务") + + try { + // 创建 Intent 并启动服务 + val serviceIntent = Intent(this, VoiceInteractionService::class.java) + + // 在 Android O 及以上版本,需要使用 startForegroundService + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Log.d(TAG, "使用startForegroundService启动服务") + startForegroundService(serviceIntent) + } else { + Log.d(TAG, "使用startService启动服务") + startService(serviceIntent) + } + + Log.d(TAG, "语音交互服务自动启动命令已发送") + + // 检查服务是否成功启动 + Handler(Looper.getMainLooper()).postDelayed({ + if (VoiceInteractionService.isServiceRunning()) { + Log.d(TAG, "语音交互服务已成功启动") + } else { + Log.e(TAG, "语音交互服务启动失败") + } + }, 1000) + } catch (e: Exception) { + Log.e(TAG, "启动语音交互服务时出错: ${e.message}", e) + } + } + override fun onDestroy() { // 注销广播接收器 try { diff --git a/android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt b/android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt index 5255dd62b..56b398417 100644 --- a/android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt +++ b/android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt @@ -102,18 +102,26 @@ class VoiceInteractionService : Service() { // 初始化组件 audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager + Log.d(TAG, "AudioManager初始化完成") + initServices() initMediaSession() registerMediaButtonReceiver() // 设置为媒体播放状态 setPlaybackState(PlaybackStateCompat.STATE_PLAYING) + Log.d(TAG, "设置播放状态为PLAYING") // 启动监控和前台服务 startMonitoring() startForegroundServiceWithNotification() Log.d(TAG, "VoiceInteractionService 初始化完成,等待蓝牙按键事件...") + + // 延迟3秒后测试按键处理功能 + // Handler(Looper.getMainLooper()).postDelayed({ + // testMediaButtonEvent() + // }, 3000) } /** @@ -163,6 +171,7 @@ class VoiceInteractionService : Service() { * 初始化 MediaSession */ private fun initMediaSession() { + Log.d(TAG, "开始初始化MediaSession") mediaSession = MediaSessionCompat(applicationContext, "VoiceServiceSession") // 设置标志和状态 @@ -170,10 +179,13 @@ class VoiceInteractionService : Service() { MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS ) + Log.d(TAG, "MediaSession标志设置完成") // 设置回调 mediaSession.setCallback(object : MediaSessionCompat.Callback() { override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean { + Log.d(TAG, "收到媒体按钮事件: $mediaButtonEvent") + val keyEvent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT, KeyEvent::class.java) } else { @@ -181,43 +193,75 @@ class VoiceInteractionService : Service() { mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT) as? KeyEvent } - if (keyEvent != null && keyEvent.action == KeyEvent.ACTION_DOWN) { - when (keyEvent.keyCode) { - KeyEvent.KEYCODE_MEDIA_PLAY, - KeyEvent.KEYCODE_MEDIA_PAUSE, - KeyEvent.KEYCODE_HEADSETHOOK, - KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> { - // 检测双击 - val currentTime = System.currentTimeMillis() - val timeDiff = currentTime - lastKeyEventTime - - if (timeDiff < 500) { // 500毫秒内的按键视为连续按键 - keyEventCount++ - if (keyEventCount == 1) { // 这是第二次按键,即双击 - handleDoubleClick() + if (keyEvent != null) { + Log.d(TAG, "解析到按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}") + + if (keyEvent.action == KeyEvent.ACTION_DOWN) { + when (keyEvent.keyCode) { + KeyEvent.KEYCODE_MEDIA_PLAY -> { + Log.d(TAG, "检测到MEDIA_PLAY按键") + handleDoubleClick() + return true + } + KeyEvent.KEYCODE_MEDIA_PAUSE -> { + Log.d(TAG, "检测到MEDIA_PAUSE按键") + handleDoubleClick() + return true + } + KeyEvent.KEYCODE_HEADSETHOOK -> { + Log.d(TAG, "检测到HEADSETHOOK按键") + // 检测双击 + val currentTime = System.currentTimeMillis() + val timeDiff = currentTime - lastKeyEventTime + + Log.d(TAG, "按键时间差: $timeDiff ms, 当前计数: $keyEventCount") + + if (timeDiff < 500) { // 500毫秒内的按键视为连续按键 + keyEventCount++ + Log.d(TAG, "连续按键,计数增加到: $keyEventCount") + if (keyEventCount == 1) { // 这是第二次按键,即双击 + Log.d(TAG, "检测到双击,执行处理") + handleDoubleClick() + keyEventCount = 0 + return true + } + } else { + Log.d(TAG, "非连续按键,重置计数") keyEventCount = 0 - return true } - } else { - keyEventCount = 0 + lastKeyEventTime = currentTime + + // 单击也处理 + Log.d(TAG, "单击也处理") + handleDoubleClick() + return true + } + KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> { + Log.d(TAG, "检测到MEDIA_PLAY_PAUSE按键") + handleDoubleClick() + return true + } + else -> { + Log.d(TAG, "检测到其他按键: ${keyEvent.keyCode}") } - lastKeyEventTime = currentTime - - // 单击也处理 - handleDoubleClick() - return true } + } else { + Log.d(TAG, "非ACTION_DOWN事件: ${keyEvent.action}") } + } else { + Log.d(TAG, "Intent中没有KeyEvent") } return super.onMediaButtonEvent(mediaButtonEvent) } override fun onPlay() { + Log.d(TAG, "收到onPlay回调") handleDoubleClick() return super.onPlay() } override fun onPause() { + Log.d(TAG, "收到onPause回调") handleDoubleClick() return super.onPause() } @@ -225,14 +269,20 @@ class VoiceInteractionService : Service() { // 激活 MediaSession mediaSession.isActive = true + Log.d(TAG, "MediaSession已激活") } /** * 注册媒体按钮接收器 */ private fun registerMediaButtonReceiver() { - val mediaButtonReceiver = ComponentName(packageName, MediaButtonReceiver::class.java.name) - audioManager.registerMediaButtonEventReceiver(mediaButtonReceiver) + try { + val mediaButtonReceiver = ComponentName(packageName, MediaButtonReceiver::class.java.name) + audioManager.registerMediaButtonEventReceiver(mediaButtonReceiver) + Log.d(TAG, "媒体按钮接收器注册成功: $mediaButtonReceiver") + } catch (e: Exception) { + Log.e(TAG, "媒体按钮接收器注册失败: ${e.message}", e) + } } /** @@ -276,6 +326,8 @@ class VoiceInteractionService : Service() { * 处理双击事件 */ private fun handleDoubleClick() { + Log.d(TAG, "处理双击事件") + // 停止当前TTS播放 stopCurrentTTS() @@ -290,8 +342,10 @@ class VoiceInteractionService : Service() { // 启动或重置语音识别 if (!isRecognitionActive) { + Log.d(TAG, "语音识别未激活,开始启动") startVoiceRecognition() } else { + Log.d(TAG, "语音识别已激活,更新活动时间") updateLastActivityTime() hasSpeechDetected = false } @@ -576,8 +630,12 @@ class VoiceInteractionService : Service() { * 当 Service 被启动时调用 */ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + Log.d(TAG, "onStartCommand: intent=$intent, action=${intent?.action}") + // 处理媒体按键 Intent if (intent?.action == Intent.ACTION_MEDIA_BUTTON) { + Log.d(TAG, "收到媒体按钮Intent: ${intent.extras}") + val keyEvent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT, KeyEvent::class.java) } else { @@ -586,17 +644,27 @@ class VoiceInteractionService : Service() { } if (keyEvent != null) { + Log.d(TAG, "从Intent中解析到按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}") handleKeyEvent(keyEvent) } else { + Log.d(TAG, "Intent中没有按键事件,直接处理双击") handleDoubleClick() } } else if (intent?.action == ACTION_PAUSE_VOICE_INTERACTION) { // 处理来自 Flutter 的暂停请求 + Log.d(TAG, "收到暂停请求") pauseVoiceInteraction() + } else { + Log.d(TAG, "收到其他Intent: action=${intent?.action}") } // 让 MediaSession 处理 Intent - MediaButtonReceiver.handleIntent(mediaSession, intent) + try { + MediaButtonReceiver.handleIntent(mediaSession, intent) + Log.d(TAG, "MediaButtonReceiver处理Intent完成") + } catch (e: Exception) { + Log.e(TAG, "MediaButtonReceiver处理Intent失败: ${e.message}", e) + } return START_STICKY } @@ -605,28 +673,50 @@ class VoiceInteractionService : Service() { * 处理按键事件 */ private fun handleKeyEvent(keyEvent: KeyEvent) { + Log.d(TAG, "处理按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}") + if (keyEvent.action == KeyEvent.ACTION_DOWN) { when (keyEvent.keyCode) { - KeyEvent.KEYCODE_MEDIA_PLAY, - KeyEvent.KEYCODE_MEDIA_PAUSE, - KeyEvent.KEYCODE_HEADSETHOOK, - KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> { + KeyEvent.KEYCODE_MEDIA_PLAY -> { + Log.d(TAG, "处理MEDIA_PLAY按键") + handleDoubleClick() + } + KeyEvent.KEYCODE_MEDIA_PAUSE -> { + Log.d(TAG, "处理MEDIA_PAUSE按键") + handleDoubleClick() + } + KeyEvent.KEYCODE_HEADSETHOOK -> { + Log.d(TAG, "处理HEADSETHOOK按键") // 检测双击 val currentTime = System.currentTimeMillis() val timeDiff = currentTime - lastKeyEventTime + Log.d(TAG, "按键时间差: $timeDiff ms, 当前计数: $keyEventCount") + if (timeDiff < 500) { // 500毫秒内的按键视为连续按键 keyEventCount++ + Log.d(TAG, "连续按键,计数增加到: $keyEventCount") if (keyEventCount == 1) { // 这是第二次按键,即双击 + Log.d(TAG, "检测到双击,执行处理") handleDoubleClick() keyEventCount = 0 } } else { + Log.d(TAG, "非连续按键,重置计数") keyEventCount = 0 } lastKeyEventTime = currentTime } + KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> { + Log.d(TAG, "处理MEDIA_PLAY_PAUSE按键") + handleDoubleClick() + } + else -> { + Log.d(TAG, "处理其他按键: ${keyEvent.keyCode}") + } } + } else { + Log.d(TAG, "非ACTION_DOWN事件: ${keyEvent.action}") } } @@ -709,4 +799,38 @@ class VoiceInteractionService : Service() { // 发送广播 sendBroadcast(intent) } + + /** + * 测试媒体按钮事件处理 + */ + private fun testMediaButtonEvent() { + Log.d(TAG, "开始测试媒体按钮事件处理") + + try { + // 创建一个模拟的HEADSETHOOK按键事件 + val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK) + + // 创建一个包含按键事件的Intent + val intent = Intent(Intent.ACTION_MEDIA_BUTTON).apply { + putExtra(Intent.EXTRA_KEY_EVENT, keyEvent) + } + + // 直接调用onMediaButtonEvent方法 + Log.d(TAG, "直接调用onMediaButtonEvent方法") + val result = mediaSession.controller.dispatchMediaButtonEvent(keyEvent) + Log.d(TAG, "dispatchMediaButtonEvent结果: $result") + + // 通过MediaButtonReceiver发送Intent + Log.d(TAG, "通过MediaButtonReceiver发送Intent") + MediaButtonReceiver.handleIntent(mediaSession, intent) + + // 直接调用handleKeyEvent方法 + Log.d(TAG, "直接调用handleKeyEvent方法") + handleKeyEvent(keyEvent) + + Log.d(TAG, "测试媒体按钮事件处理完成") + } catch (e: Exception) { + Log.e(TAG, "测试媒体按钮事件处理失败: ${e.message}", e) + } + } } \ No newline at end of file diff --git a/lib/core/bindings/initial_binding.dart b/lib/core/bindings/initial_binding.dart index 00fb2da94..d27dd3199 100644 --- a/lib/core/bindings/initial_binding.dart +++ b/lib/core/bindings/initial_binding.dart @@ -24,6 +24,6 @@ class InitialBinding extends Bindings { Get.lazyPut(() => VolcanoTranslationService(), fenix: true); // 语音交互服务 - 使用 putAsync 确保 init 方法被调用 - Get.putAsync(() => VoiceInteractionService().init(), permanent: true); + Get.lazyPut(() => VoiceInteractionService(), fenix: true); } } \ No newline at end of file diff --git a/lib/data/services/voice_interaction_service.dart b/lib/data/services/voice_interaction_service.dart index 4705cd714..e979302bd 100644 --- a/lib/data/services/voice_interaction_service.dart +++ b/lib/data/services/voice_interaction_service.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; @@ -23,16 +24,82 @@ class VoiceInteractionService extends GetxService { final RxList personalAssistantMessages = [].obs; // 方法通道 - final MethodChannel _channel = const MethodChannel('com.deep_voice.voice_interaction'); + static const MethodChannel _channel = MethodChannel('com.deep_voice.voice_interaction'); // 事件通道 - final EventChannel _eventChannel = const EventChannel('com.deep_voice.voice_interaction_events'); + static const EventChannel _eventChannel = EventChannel('com.deep_voice.voice_interaction_events'); - // 事件流订阅 - Stream? _eventStream; + // 配置信息 + late final String _azureSpeechKey; + late final String _azureSpeechRegion; + late final String _volcanoAiApiKey; + + // 事件通道状态 + bool _isEventChannelReady = false; + Completer? _eventChannelReadyCompleter; // 初始化标记,避免重复初始化 - static bool _isInitialized = false; + bool _isInitialized = false; + + VoiceInteractionService() { + _loadConfig(); + _setupEventChannel(); + } + + /// 从环境变量加载配置 + void _loadConfig() { + _azureSpeechKey = dotenv.env['AZURE_SPEECH_KEY'] ?? ''; + _azureSpeechRegion = dotenv.env['AZURE_SPEECH_REGION'] ?? ''; + _volcanoAiApiKey = dotenv.env['VOLCANO_AI_API_KEY'] ?? ''; + + if (_azureSpeechKey.isEmpty || _azureSpeechRegion.isEmpty) { + Logger.error('未找到 Azure 语音服务配置。请在 .env 文件中设置 AZURE_SPEECH_KEY 和 AZURE_SPEECH_REGION'); + } + + if (_volcanoAiApiKey.isEmpty) { + Logger.error('未找到火山 AI 配置。请在 .env 文件中设置 VOLCANO_AI_API_KEY'); + } + } + + /// 设置事件通道监听 + void _setupEventChannel() { + _eventChannelReadyCompleter = Completer(); + + _eventChannel.receiveBroadcastStream().listen( + (event) { + if (event is Map) { + final String eventType = event['type'] as String? ?? ''; + + // 处理通道准备好的事件 + if (eventType == 'channelReady') { + _isEventChannelReady = true; + if (!_eventChannelReadyCompleter!.isCompleted) { + _eventChannelReadyCompleter!.complete(); + } + return; + } + + _handleEvent(event); + } + }, + onError: (error) { + Logger.error('语音交互事件通道错误: $error'); + } + ); + } + + /// 等待事件通道准备好 + Future _waitForEventChannel({Duration timeout = const Duration(seconds: 5)}) async { + if (_isEventChannelReady) return true; + + try { + await _eventChannelReadyCompleter!.future.timeout(timeout); + return true; + } on TimeoutException { + Logger.error('等待事件通道准备好超时'); + return false; + } + } /// 初始化服务 Future init() async { @@ -42,12 +109,16 @@ class VoiceInteractionService extends GetxService { } try { + // 等待事件通道准备好 + final bool eventChannelReady = await _waitForEventChannel(); + if (!eventChannelReady) { + Logger.error('事件通道未准备好,初始化失败'); + return this; + } + // 获取服务运行状态 await _updateServiceStatus(); - // 设置事件监听 - _setupEventChannel(); - // 加载个人助手的历史记录 _loadPersonalAssistantHistory(); @@ -55,7 +126,7 @@ class VoiceInteractionService extends GetxService { _isInitialized = true; return this; } catch (e) { - Logger.error('VoiceInteractionService 初始化失败', e); + Logger.error('VoiceInteractionService 初始化失败: $e'); return this; } } @@ -71,21 +142,6 @@ class VoiceInteractionService extends GetxService { } } - /// 设置事件通道监听 - void _setupEventChannel() { - try { - _eventStream = _eventChannel.receiveBroadcastStream(); - _eventStream?.listen( - _handleEvent, - onError: (error) { - Logger.error('语音交互事件通道错误', error); - } - ); - } catch (e) { - Logger.error('设置事件通道监听失败', e); - } - } - /// 处理来自原生端的事件 void _handleEvent(dynamic event) { try { @@ -99,8 +155,6 @@ class VoiceInteractionService extends GetxService { } switch (type) { - case 'channelReady': - break; case 'recognitionStarted': _isRecognitionActive.value = true; @@ -113,7 +167,7 @@ class VoiceInteractionService extends GetxService { break; } } catch (e) { - Logger.error('处理原生端事件时出错', e); + Logger.error('处理原生端事件时出错: $e'); } } @@ -154,7 +208,7 @@ class VoiceInteractionService extends GetxService { historyService.saveHistory('personal_assistant', personalAssistantMessages); } } catch (e) { - Logger.error('处理聊天记录事件失败', e); + Logger.error('处理聊天记录事件失败: $e'); } } @@ -173,19 +227,16 @@ class VoiceInteractionService extends GetxService { /// 启动语音交互服务 Future startService() async { + if (!_isInitialized) { + await init(); + } + try { - // 获取 Azure 配置 - final azureKey = dotenv.env['AZURE_SPEECH_KEY'] ?? ''; - final azureRegion = dotenv.env['AZURE_SPEECH_REGION'] ?? ''; - - // 获取火山 AI 配置 - final volcanoApiKey = dotenv.env['VOLCANO_AI_API_KEY'] ?? ''; - // 启动服务 final result = await _channel.invokeMethod('startVoiceInteractionService', { - 'azure_speech_key': azureKey, - 'azure_speech_region': azureRegion, - 'volcano_ai_api_key': volcanoApiKey, + 'azure_speech_key': _azureSpeechKey, + 'azure_speech_region': _azureSpeechRegion, + 'volcano_ai_api_key': _volcanoAiApiKey, }) ?? false; // 更新状态 @@ -195,7 +246,7 @@ class VoiceInteractionService extends GetxService { return result; } catch (e) { - Logger.error('启动语音交互服务失败', e); + Logger.error('启动语音交互服务失败: $e'); return false; } } @@ -212,7 +263,7 @@ class VoiceInteractionService extends GetxService { return result; } catch (e) { - Logger.error('停止语音交互服务失败', e); + Logger.error('停止语音交互服务失败: $e'); return false; } } @@ -223,7 +274,7 @@ class VoiceInteractionService extends GetxService { final result = await _channel.invokeMethod('pauseVoiceInteraction') ?? false; return result; } catch (e) { - Logger.error('暂停语音交互失败', e); + Logger.error('暂停语音交互失败: $e'); return false; } } @@ -234,15 +285,28 @@ class VoiceInteractionService extends GetxService { final status = await _channel.invokeMethod('isVoiceInteractionServiceRunning') ?? false; _isRunning.value = status; } catch (e) { - Logger.error('获取语音交互服务状态失败', e); + Logger.error('获取语音交互服务状态失败: $e'); _isRunning.value = false; } } + /// 释放资源 + Future dispose() async { + try { + if (_isRunning.value) { + await stopService(); + } + + _isInitialized = false; + } catch (e) { + Logger.error('释放语音交互服务资源失败: $e'); + } + } + @override void onClose() { // 清理资源 - _eventStream = null; + dispose(); super.onClose(); } } \ No newline at end of file diff --git a/lib/modules/chat/controllers/chat_controller.dart b/lib/modules/chat/controllers/chat_controller.dart index 1b19c9ce9..f444a76a8 100644 --- a/lib/modules/chat/controllers/chat_controller.dart +++ b/lib/modules/chat/controllers/chat_controller.dart @@ -9,7 +9,6 @@ import '../../../data/providers/agent_provider.dart'; import '../../../data/models/agent.dart'; import '../../../core/utils/logger.dart'; import '../../../data/services/chat_history_service.dart'; -import '../../../data/services/voice_interaction_service.dart'; class ChatController extends GetxController { // 服务 @@ -17,7 +16,6 @@ class ChatController extends GetxController { final AzureTtsService _ttsService = Get.find(); final AzureAsrService _asrService = Get.find(); final ChatHistoryService _historyService = Get.find(); - final VoiceInteractionService _voiceInteractionService = Get.find(); // 添加ScrollController用于控制列表滚动 final ScrollController scrollController = ScrollController(); @@ -48,9 +46,6 @@ class ChatController extends GetxController { // 流式响应控制 StreamSubscription? _aiResponseSubscription; StreamSubscription? _recognitionSubscription; - - // 语音交互服务消息监听 - Worker? _personalAssistantMessagesWorker; // 取消标志 bool _shouldCancelAiResponse = false; @@ -60,8 +55,6 @@ class ChatController extends GetxController { super.onInit(); Logger.info('ChatController onInit'); - - // 从路由参数获取Agent信息 final Map args = Get.arguments ?? {}; final String agentId = args['agentId'] ?? 'personal_assistant'; @@ -75,24 +68,12 @@ class ChatController extends GetxController { } agent = foundAgent; - - - // 暂停后台语音交互服务,避免与聊天页面的语音功能相互干扰 - // if (Get.isRegistered()) { - // await VoiceInteractionService.to.pauseVoiceInteraction(); - // Logger.info('已暂停后台语音交互服务'); - // } // 设置TTS服务 await _ttsService.setVoice(agent.voice); // 加载聊天历史 _loadChatHistory(); - - // 如果是个人助手,监听语音交互服务的消息更新 - if (agent.id == 'personal_assistant') { - _setupPersonalAssistantMessagesListener(); - } // 如果没有历史记录,添加欢迎消息 if (messages.isEmpty && agent.welcomeMessage.isNotEmpty) { @@ -117,37 +98,6 @@ class ChatController extends GetxController { _scrollToBottom(); }); } - - /// 设置个人助手消息监听器 - void _setupPersonalAssistantMessagesListener() { - // 取消之前的监听器(如果有) - _personalAssistantMessagesWorker?.dispose(); - - // 设置新的监听器 - _personalAssistantMessagesWorker = ever( - _voiceInteractionService.personalAssistantMessages, - (List updatedMessages) { - if (agent.id == 'personal_assistant' && updatedMessages.isNotEmpty) { - Logger.info('检测到语音交互服务的个人助手消息更新,同步到聊天视图'); - - // 中断当前响应 - _interruptCurrentResponse("检测到语音交互服务的消息更新,中断当前响应"); - - // 更新消息列表 - messages.assignAll(updatedMessages); - - // 滚动到底部 - _scrollToBottom(); - } - } - ); - - // 初始同步 - if (_voiceInteractionService.personalAssistantMessages.isNotEmpty) { - messages.assignAll(_voiceInteractionService.personalAssistantMessages); - Logger.info('初始同步语音交互服务的个人助手消息,消息数: ${_voiceInteractionService.personalAssistantMessages.length}'); - } - } @override void onClose() { @@ -157,7 +107,6 @@ class ChatController extends GetxController { scrollController.dispose(); _aiResponseSubscription?.cancel(); _recognitionSubscription?.cancel(); - _personalAssistantMessagesWorker?.dispose(); // 停止TTS _ttsService.stop(); @@ -555,31 +504,11 @@ class ChatController extends GetxController { // 删除存储的历史记录 _historyService.clearHistory(agent.id); - - // 如果是个人助手,同时清空语音交互服务的消息 - if (agent.id == 'personal_assistant' && Get.isRegistered()) { - _voiceInteractionService.personalAssistantMessages.clear(); - _voiceInteractionService.personalAssistantMessages.add(Message( - role: 'assistant', - content: agent.welcomeMessage, - timestamp: DateTime.now(), - )); - } } // 加载聊天历史 void _loadChatHistory() { - // 如果是个人助手,优先使用语音交互服务中的消息 - if (agent.id == 'personal_assistant' && - Get.isRegistered() && - _voiceInteractionService.personalAssistantMessages.isNotEmpty) { - messages.clear(); - messages.addAll(_voiceInteractionService.personalAssistantMessages); - Logger.info('从语音交互服务加载个人助手的历史记录,消息数: ${messages.length}'); - return; - } - - // 否则从历史服务加载 + // 从历史服务加载 final history = _historyService.loadHistory(agent.id); if (history.isNotEmpty) { messages.clear(); @@ -590,11 +519,6 @@ class ChatController extends GetxController { // 保存聊天历史 void _saveChatHistory() { _historyService.saveHistory(agent.id, messages); - - // 如果是个人助手,同时更新语音交互服务的消息 - if (agent.id == 'personal_assistant' && Get.isRegistered()) { - _voiceInteractionService.personalAssistantMessages.assignAll(messages); - } } // 添加消息,供外部调用