n9 解决蓝牙ai录音线程创建不了问题导致不能连续对话bug 2627/1 2627/head 2628/target/1
authorluozheng <1732036298@qq.com>
Wed, 29 Oct 2025 04:00:59 +0000 (12:00 +0800)
committerluozheng <1732036298@qq.com>
Wed, 29 Oct 2025 04:00:59 +0000 (12:00 +0800)
12 files changed:
code/sdk/application/wearable/fd230/nativeapp/nativeui/aivoice/src/AiVoiceConnectingView.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/aivoice/src/AiVoiceModel.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/aivoice/src/AiVoiceView.cpp
code/sdk/application/wearable/fd272/nativeapp/nativeui/aivoice/src/AiVoiceConnectingView.cpp
code/sdk/application/wearable/n9/nativeapp/nativeui/aivoice/include/AiVoiceModel.h
code/sdk/application/wearable/n9/nativeapp/nativeui/aivoice/src/AiVoiceConnectingView.cpp
code/sdk/application/wearable/n9/nativeapp/nativeui/aivoice/src/AiVoiceModel.cpp
code/sdk/application/wearable/n9/nativeapp/nativeui/aivoice/src/AiVoiceView.cpp
code/sdk/middleware/services/media/foundation/sample/wrapper/audio_capture_wrapper.cpp
code/sdk/middleware/services/media/foundation/sample/wrapper/audio_capture_wrapper.h
code/sdk/zhihui/services/ble_service/bleservice/bleEvent.c
code/sdk/zhihui/utils/custom_utils.c

index 45f1401..385b807 100644 (file)
@@ -113,10 +113,10 @@ namespace OHOS
                 connectingAnimatorView->Stop();
                 delete connectingAnimatorView;
                 connectingAnimatorView = nullptr;
-                for (int i = 0; i < AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES; i++)
-                {
-                    ImageCacheManager::GetInstance().UnloadSingleRes(connecting_path_array[i]);
-                }
+                // for (int i = 0; i < AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES; i++)
+                // {
+                //     ImageCacheManager::GetInstance().UnloadSingleRes(connecting_path_array[i]);
+                // }
             }
             if (cancelLabel)
             {
@@ -132,7 +132,6 @@ namespace OHOS
             delete scrollView;
             scrollView = nullptr;
         }
-        ScreenTurnOff();
     }
 
     AiVoiceConnectingView *AiVoiceConnectingView::GetInstance(void)
@@ -297,8 +296,8 @@ namespace OHOS
         }
         for (uint8_t i = 0; i < AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES; i++)
         {
-            connectingImageInfo[i].imageInfo = ImageCacheManager::GetInstance().LoadSingleRes(connecting_path_array[i]);
-            connectingImageInfo[i].imageType = IMG_SRC_IMAGE_INFO;
+            connectingImageInfo[i].imagePath = connecting_path_array[i];
+            connectingImageInfo[i].imageType = IMG_SRC_FILE_PATH;
             connectingImageInfo[i].pos.x = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_X;
             connectingImageInfo[i].pos.y = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_Y;
             connectingImageInfo[i].width = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_W;
index b5e2123..7808dae 100644 (file)
@@ -192,7 +192,7 @@ namespace OHOS
             else if (GetSelect4gorbt() == AI_SELECT_BT)
             {
 #ifdef SUPPORT_BLE_SERVICE
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "蓝牙:查询Ai是否就绪:%d",it->second.second);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "蓝牙:查询Ai是否就绪:%d", it->second.second);
                 inquire_AI_is_ready(it->second.second);
 #endif
             }
@@ -831,33 +831,29 @@ namespace OHOS
 
     void AiVoiceModel::SetAiAnswerStrStr(std::string str, uint8_t type)
     {
-        AIResponseType = type;
-        errnote = str;
         AiVoiceView *view_ = AiVoiceView::GetInstance();
         if (GetSelect4gorbt() == AI_SELECT_4G) // 4G
         {
-            if (!OHOS::AiVoiceModel::GetInstance().GetIsLimitDisplayed()) // 如果ai答案没有显示到极限了,就更新ai答案字符串
-            {
-                delete_start_line_break_str(str);
-                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "传入的str:%s", str.c_str());
-                aiAnswerStr += str;
-                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "接受字的符串:%s", aiAnswerStr.c_str());
-                /* -------------------------------------------------------------------------- */
-                // 累积接收到的文本
-                // accumulatedText += str;//tts播放的代码去除掉
-                /* -------------------------------------------------------------------------- */
-            }
             if (view_ != nullptr)
             {
-                if (view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID) && view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID)->IsVisible())
+                if (view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID) &&
+                    view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID)->IsVisible())
                 {
-                    // start_ai4g_tts_play_timer(); // 开启一个定时器,用于播放tts音频
                     start_update_ai_answer_timer();
+                    // delete_start_line_break_str(str);
+                    if (!OHOS::AiVoiceModel::GetInstance().GetIsLimitDisplayed()) // 如果ai答案没有显示到极限了,就更新ai答案字符串
+                    {
+                        aiAnswerStr += str;
+                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接受字的符串:%s", aiAnswerStr.c_str());
+                        // SendMsgToUIService(UI_UPDATE_AI_ANSWER_STR, 0, nullptr, 0);
+                    }
                 }
             }
         }
         else if (GetSelect4gorbt() == AI_SELECT_BT) // 蓝牙
         {
+            AIResponseType = type;
+            errnote = str;
             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AIResponseType = %d,errnote = %s\n", AIResponseType, errnote.c_str());
             // 如果是:AI录音解析错误或AI 回应错误 ,或者重传多次录音数据->跳转AI回应错误界面
             if (AIResponseType == AiVoiceModel::AI_RECORDING_PARSING_ERROR || AIResponseType == AiVoiceModel::AI_RESPONSE_ERROR || AIResponseType == AiVoiceModel::AI_BLE_ERROR)
@@ -913,6 +909,7 @@ namespace OHOS
 #endif
         int32_t AudioCaptureSample(int32_t argc, const char *argv[]);
         int32_t streamingRecordAndSend_AI(int type);
+        int32_t StopStreamingRecordAndSend_AI(void);
 #define IS_SUPPORT_REALTIME_RECORD_SEND_AI 1 // 是否支持实时发送录音数据
 #ifdef __cplusplus
     };
@@ -978,9 +975,11 @@ namespace OHOS
         }
         else if (GetSelect4gorbt() == AI_SELECT_BT)
         {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "停止录音BT");
             int32_t argc = 1;
             uint8_t *argv = (uint8_t *)"stop";
             AudioCaptureSample(argc, (const char **)&argv);
+            StopStreamingRecordAndSend_AI();
         }
         uapi_save_runtime_log(RUNTIME_LOG_RECORD_STOP_AI); // TOOD*
         return;
@@ -2181,11 +2180,13 @@ extern "C"
 
     void ble_set_ai_Question_str_(char *buf)
     {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble_set_ai_Question_str_:%s", buf);
         OHOS::AiVoiceModel::GetInstance().SetUserQuestionStr(std::string(buf));
     }
 
     void ble_set_ai_Answer_str_(char *buf, uint8_t type)
     {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble_set_ai_Answer_str_:%s,type:%d",buf,type);
         // chat_filter_result_chars(buf);
         OHOS::AiVoiceModel::GetInstance().SetAiAnswerStrStr(std::string(buf), type);
     }
@@ -2203,10 +2204,12 @@ extern "C"
         bleInstruct_t.ble_set_ai_Question_str = ble_set_ai_Question_str_;
 
         bleInstruct_t.ble_set_ai_Answer_str = ble_set_ai_Answer_str_;
-
         bleInstruct_t.ble_app_reply = ble_app_reply_;
     }
 
+    /*
+     * WebSocket 聊天结果过滤回调包装,匹配 ws_register_chat_filter_callback 的签名
+     */
     static void ws_chat_filter_cb_wrapper(char *result)
     {
         /* 复用现有过滤实现,忽略返回长度 */
index 820f351..bd2b150 100644 (file)
@@ -522,12 +522,12 @@ namespace OHOS
     void AiVoiceView::OnStart()
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::OnStart");
-        ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_AIMODE_CONNECTING);
-        GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING)->SetVisible(false);
-        ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_LISTENING_VIEWID);
-        GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->SetVisible(false);
-        ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_THINKING_VIEWID);
-        GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID)->SetVisible(false);
+        // ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_AIMODE_CONNECTING);
+        // GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING)->SetVisible(false);
+        // ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_LISTENING_VIEWID);
+        // GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->SetVisible(false);
+        // ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_THINKING_VIEWID);
+        // GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID)->SetVisible(false);
         ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_STARTCHAT_VIEWID);
 #if defined(AI_VOICE_FD230) || defined(AI_VOICE_N9)
         CreateAiVoiceVoiceView();
@@ -978,10 +978,10 @@ namespace OHOS
     }
 
     static const int16 AiVoiceDestroyMapper[] = {
-        // AIVOICE_AIMODE_CONNECTING,
+        AIVOICE_AIMODE_CONNECTING,
         AIVOICE_4GSERVICECON_VIEW,
-        // AIVOICE_LISTENING_VIEWID,
-        // AIVOICE_THINKING_VIEWID,
+        AIVOICE_LISTENING_VIEWID,
+        AIVOICE_THINKING_VIEWID,
         AIVOICE_SELECT_VIEW,
         AIVOICE_CONNECT_TIMEOUT_VIEWID,
         AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID,
@@ -1012,9 +1012,9 @@ namespace OHOS
         case AIVOICE_AIMODE_CONNECTING:
             if (p_AiVoiceConnectingView)
             {
-                // delete p_AiVoiceConnectingView;
-                // p_AiVoiceConnectingView = nullptr;
-                p_AiVoiceConnectingView->StartOrStopAiVoiceConnectingImageAnimatorView(false);
+                delete p_AiVoiceConnectingView;
+                p_AiVoiceConnectingView = nullptr;
+                // p_AiVoiceConnectingView->StartOrStopAiVoiceConnectingImageAnimatorView(false);
             }
             break;
         case AIVOICE_4GSERVICECON_VIEW:
@@ -1028,17 +1028,17 @@ namespace OHOS
         case AIVOICE_LISTENING_VIEWID:
             if (p_AivoiceListeningView)
             {
-                // delete p_AivoiceListeningView;
-                // p_AivoiceListeningView = nullptr;
-                p_AivoiceListeningView->StartOrStopAivoiceListeningImageAnimatorView(false);
+                delete p_AivoiceListeningView;
+                p_AivoiceListeningView = nullptr;
+                // p_AivoiceListeningView->StartOrStopAivoiceListeningImageAnimatorView(false);
             }
             break;
         case AIVOICE_THINKING_VIEWID:
             if (p_AivoiceThinkingView)
             {
-                // delete p_AivoiceThinkingView;
-                // p_AivoiceThinkingView = nullptr;
-                p_AivoiceThinkingView->StartOrStopAiVoiceThinkingImageAnimatorView(false);
+                delete p_AivoiceThinkingView;
+                p_AivoiceThinkingView = nullptr;
+                // p_AivoiceThinkingView->StartOrStopAiVoiceThinkingImageAnimatorView(false);
             }
             break;
         case AIVOICE_SELECT_VIEW:
index 86ad721..896874e 100644 (file)
@@ -131,7 +131,6 @@ namespace OHOS
             delete scrollView;
             scrollView = nullptr;
         }
-        ScreenTurnOff();
     }
 
     AiVoiceConnectingView *AiVoiceConnectingView::GetInstance(void)
index 6f619a1..17b87f8 100644 (file)
@@ -131,7 +131,7 @@ namespace OHOS
         void start_ai4g_tts_play_timer(uint32_t interval = 600);
         void stop_ai4g_tts_play_timer(void);
 
-        void start_update_ai_answer_timer(uint32_t interval = 300);
+        void start_update_ai_answer_timer(uint32_t interval = 1000);
         void stop_update_ai_answer_timer(void);
 
         void start_uapi_stop_tts_timer(uint32_t interval = 2000);
index 45f1401..385b807 100644 (file)
@@ -113,10 +113,10 @@ namespace OHOS
                 connectingAnimatorView->Stop();
                 delete connectingAnimatorView;
                 connectingAnimatorView = nullptr;
-                for (int i = 0; i < AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES; i++)
-                {
-                    ImageCacheManager::GetInstance().UnloadSingleRes(connecting_path_array[i]);
-                }
+                // for (int i = 0; i < AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES; i++)
+                // {
+                //     ImageCacheManager::GetInstance().UnloadSingleRes(connecting_path_array[i]);
+                // }
             }
             if (cancelLabel)
             {
@@ -132,7 +132,6 @@ namespace OHOS
             delete scrollView;
             scrollView = nullptr;
         }
-        ScreenTurnOff();
     }
 
     AiVoiceConnectingView *AiVoiceConnectingView::GetInstance(void)
@@ -297,8 +296,8 @@ namespace OHOS
         }
         for (uint8_t i = 0; i < AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES; i++)
         {
-            connectingImageInfo[i].imageInfo = ImageCacheManager::GetInstance().LoadSingleRes(connecting_path_array[i]);
-            connectingImageInfo[i].imageType = IMG_SRC_IMAGE_INFO;
+            connectingImageInfo[i].imagePath = connecting_path_array[i];
+            connectingImageInfo[i].imageType = IMG_SRC_FILE_PATH;
             connectingImageInfo[i].pos.x = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_X;
             connectingImageInfo[i].pos.y = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_Y;
             connectingImageInfo[i].width = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_W;
index cdfc8d7..2846941 100644 (file)
@@ -192,7 +192,7 @@ namespace OHOS
             else if (GetSelect4gorbt() == AI_SELECT_BT)
             {
 #ifdef SUPPORT_BLE_SERVICE
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "蓝牙:查询Ai是否就绪:%d",it->second.second);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "蓝牙:查询Ai是否就绪:%d", it->second.second);
                 inquire_AI_is_ready(it->second.second);
 #endif
             }
@@ -831,33 +831,29 @@ namespace OHOS
 
     void AiVoiceModel::SetAiAnswerStrStr(std::string str, uint8_t type)
     {
-        AIResponseType = type;
-        errnote = str;
         AiVoiceView *view_ = AiVoiceView::GetInstance();
         if (GetSelect4gorbt() == AI_SELECT_4G) // 4G
         {
-            if (!OHOS::AiVoiceModel::GetInstance().GetIsLimitDisplayed()) // 如果ai答案没有显示到极限了,就更新ai答案字符串
-            {
-                delete_start_line_break_str(str);
-                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "传入的str:%s", str.c_str());
-                aiAnswerStr += str;
-                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "接受字的符串:%s", aiAnswerStr.c_str());
-                /* -------------------------------------------------------------------------- */
-                // 累积接收到的文本
-                // accumulatedText += str;//tts播放的代码去除掉
-                /* -------------------------------------------------------------------------- */
-            }
             if (view_ != nullptr)
             {
-                if (view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID) && view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID)->IsVisible())
+                if (view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID) &&
+                    view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID)->IsVisible())
                 {
-                    // start_ai4g_tts_play_timer(); // 开启一个定时器,用于播放tts音频
                     start_update_ai_answer_timer();
+                    // delete_start_line_break_str(str);
+                    if (!OHOS::AiVoiceModel::GetInstance().GetIsLimitDisplayed()) // 如果ai答案没有显示到极限了,就更新ai答案字符串
+                    {
+                        aiAnswerStr += str;
+                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接受字的符串:%s", aiAnswerStr.c_str());
+                        // SendMsgToUIService(UI_UPDATE_AI_ANSWER_STR, 0, nullptr, 0);
+                    }
                 }
             }
         }
         else if (GetSelect4gorbt() == AI_SELECT_BT) // 蓝牙
         {
+            AIResponseType = type;
+            errnote = str;
             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AIResponseType = %d,errnote = %s\n", AIResponseType, errnote.c_str());
             // 如果是:AI录音解析错误或AI 回应错误 ,或者重传多次录音数据->跳转AI回应错误界面
             if (AIResponseType == AiVoiceModel::AI_RECORDING_PARSING_ERROR || AIResponseType == AiVoiceModel::AI_RESPONSE_ERROR || AIResponseType == AiVoiceModel::AI_BLE_ERROR)
@@ -883,7 +879,7 @@ namespace OHOS
                     if (!OHOS::AiVoiceModel::GetInstance().GetIsLimitDisplayed()) // 如果ai答案没有显示到极限了,就更新ai答案字符串
                     {
                         aiAnswerStr += str;
-                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接受字的符串:%s", aiAnswerStr.c_str());
+                        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "接受字的符串:%s", aiAnswerStr.c_str());
                         SendMsgToUIService(UI_UPDATE_AI_ANSWER_STR, 0, nullptr, 0);
                     }
                 }
@@ -913,6 +909,7 @@ namespace OHOS
 #endif
         int32_t AudioCaptureSample(int32_t argc, const char *argv[]);
         int32_t streamingRecordAndSend_AI(int type);
+        int32_t StopStreamingRecordAndSend_AI(void);
 #define IS_SUPPORT_REALTIME_RECORD_SEND_AI 1 // 是否支持实时发送录音数据
 #ifdef __cplusplus
     };
@@ -978,9 +975,11 @@ namespace OHOS
         }
         else if (GetSelect4gorbt() == AI_SELECT_BT)
         {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "停止录音BT");
             int32_t argc = 1;
             uint8_t *argv = (uint8_t *)"stop";
             AudioCaptureSample(argc, (const char **)&argv);
+            StopStreamingRecordAndSend_AI();
         }
         uapi_save_runtime_log(RUNTIME_LOG_RECORD_STOP_AI); // TOOD*
         return;
@@ -2181,7 +2180,7 @@ extern "C"
 
     void ble_set_ai_Question_str_(char *buf)
     {
-        printf("ble_set_ai_Question_str_ %s\n",buf);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble_set_ai_Question_str_:%s", buf);
         OHOS::AiVoiceModel::GetInstance().SetUserQuestionStr(std::string(buf));
     }
 
@@ -2195,7 +2194,7 @@ extern "C"
     void ble_app_reply_(bool data)
     {
         bool state = data;
-        printf("ble_app_reply_:%d\n",state);
+        printf("ble_app_reply_:%d\n", state);
         SendMsgToUIService(UI_AI_JUMP_TO_LISTENING_VIEW, 0, &state, sizeof(bool));
     }
 
index a0a8fd7..fab863d 100644 (file)
@@ -522,12 +522,12 @@ namespace OHOS
     void AiVoiceView::OnStart()
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::OnStart");
-        ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_AIMODE_CONNECTING);
-        GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING)->SetVisible(false);
-        ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_LISTENING_VIEWID);
-        GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->SetVisible(false);
-        ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_THINKING_VIEWID);
-        GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID)->SetVisible(false);
+        // ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_AIMODE_CONNECTING);
+        // GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING)->SetVisible(false);
+        // ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_LISTENING_VIEWID);
+        // GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->SetVisible(false);
+        // ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_THINKING_VIEWID);
+        // GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID)->SetVisible(false);
         ChangeView(MAX_AIVOICE_VIEWID, AIVOICE_STARTCHAT_VIEWID);
 #if defined(AI_VOICE_FD230) || defined(AI_VOICE_N9)
         CreateAiVoiceVoiceView();
@@ -978,10 +978,10 @@ namespace OHOS
     }
 
     static const int16 AiVoiceDestroyMapper[] = {
-        // AIVOICE_AIMODE_CONNECTING,
+        AIVOICE_AIMODE_CONNECTING,
         AIVOICE_4GSERVICECON_VIEW,
-        // AIVOICE_LISTENING_VIEWID,
-        // AIVOICE_THINKING_VIEWID,
+        AIVOICE_LISTENING_VIEWID,
+        AIVOICE_THINKING_VIEWID,
         AIVOICE_SELECT_VIEW,
         AIVOICE_CONNECT_TIMEOUT_VIEWID,
         AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID,
@@ -1012,9 +1012,9 @@ namespace OHOS
         case AIVOICE_AIMODE_CONNECTING:
             if (p_AiVoiceConnectingView)
             {
-                // delete p_AiVoiceConnectingView;
-                // p_AiVoiceConnectingView = nullptr;
-                p_AiVoiceConnectingView->StartOrStopAiVoiceConnectingImageAnimatorView(false);
+                delete p_AiVoiceConnectingView;
+                p_AiVoiceConnectingView = nullptr;
+                // p_AiVoiceConnectingView->StartOrStopAiVoiceConnectingImageAnimatorView(false);
             }
             break;
         case AIVOICE_4GSERVICECON_VIEW:
@@ -1028,17 +1028,17 @@ namespace OHOS
         case AIVOICE_LISTENING_VIEWID:
             if (p_AivoiceListeningView)
             {
-                // delete p_AivoiceListeningView;
-                // p_AivoiceListeningView = nullptr;
-                p_AivoiceListeningView->StartOrStopAivoiceListeningImageAnimatorView(false);
+                delete p_AivoiceListeningView;
+                p_AivoiceListeningView = nullptr;
+                // p_AivoiceListeningView->StartOrStopAivoiceListeningImageAnimatorView(false);
             }
             break;
         case AIVOICE_THINKING_VIEWID:
             if (p_AivoiceThinkingView)
             {
-                // delete p_AivoiceThinkingView;
-                // p_AivoiceThinkingView = nullptr;
-                p_AivoiceThinkingView->StartOrStopAiVoiceThinkingImageAnimatorView(false);
+                delete p_AivoiceThinkingView;
+                p_AivoiceThinkingView = nullptr;
+                // p_AivoiceThinkingView->StartOrStopAiVoiceThinkingImageAnimatorView(false);
             }
             break;
         case AIVOICE_SELECT_VIEW:
index b13ebac..cea1dd8 100644 (file)
@@ -28,6 +28,7 @@
 #include "media_log.h"
 #include "media_thread_adapt.h"
 #include "ogg.h"
+#include "custom_utils.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -135,6 +136,7 @@ typedef struct CaptureOggContext{
 static CaptureOggContext g_oggCtx = {};
 static bool g_interruptHintStop = false;
 static std::shared_ptr<AudioCapturer> g_audioCap;
+static uint32_t g_ai_record_thread_handle = 0; /* AI录音线程句柄(自定义线程API创建) */
 static NameAudioFormat g_audioCodecFormat[] = {
     {"mp3", MP3},
     {"ape", APE},
@@ -663,7 +665,7 @@ EXIT:
 }
 
 /* ------------------------------- AI录音数据上传接口 ------------------------------- */
-#define AI_RECORD_TEST 1 //若需要调试可以打开该宏
+#define AI_RECORD_TEST 0 //若需要调试可以打开该宏
 #ifdef SUPPORT_BLE_SERVICE
 #include "bleService.h"
 static uint32_t AI_audio_size=0;
@@ -715,7 +717,7 @@ static void* AudioCaptureProcess_AI(void* arg)
                     readCnt, timeStamp.time.tv_sec, timeStamp.time.tv_nsec);
             }
         }
-        MEDIA_INFO_LOG("audioCap Read readCnt = %d, size = %d", readCnt, ret);
+        // MEDIA_INFO_LOG("audioCap Read readCnt = %d, size = %d", readCnt, ret);
         #endif
     }
     #if AI_RECORD_TEST
@@ -728,6 +730,8 @@ static void* AudioCaptureProcess_AI(void* arg)
 
 
     AudioCaptureStop();
+    /* 清空线程句柄,标记线程已退出 */
+    g_ai_record_thread_handle = 0;
     MEDIA_INFO_LOG("AudioCaptureProcess end");
     return NULL;
 }
@@ -792,16 +796,64 @@ int32_t streamingRecordAndSend_AI(int type)
         (void)g_amInstance.DeactivateAudioInterrupt(g_sample.interrupt);
         goto EXIT;
     }
-    g_sample.audioCaptureProcess = MediaThreadCreate(AudioCaptureProcess_AI, pfd, &attr);
-    if (g_sample.audioCaptureProcess == nullptr) {
-        MEDIA_ERR_LOG("thread create failed");
-        goto EXIT;
+    /* 使用自定义线程API创建录音线程,支持PSRAM栈与参数传递 */
+    {
+        app_task_definition_ext_t task_cfg;
+        memset(&task_cfg, 0, sizeof(task_cfg));
+        task_cfg.attr.name = "AI_AudioCaptureTask";
+        task_cfg.attr.priority = osPriorityNormal;
+        task_cfg.attr.stack_size = 0x1000; /* 与原MediaThreadattr一致 */
+        task_cfg.func = (osThreadFunc_t)AudioCaptureProcess_AI;
+        task_cfg.task_handle = &g_ai_record_thread_handle;
+        task_cfg.create_queue_handle = NULL;
+        task_cfg.use_mem = USE_EXTEND_MEM; /* 将线程栈放到扩展内存,降低TCB/heap压力 */
+        task_cfg.inst_args = pfd; /* 传递文件句柄(调试打开时使用) */
+        errcode_t tret = uapi_create_osThread_custom_with_args(&task_cfg);
+        if (tret != ERRCODE_SUCC || g_ai_record_thread_handle == 0) {
+            MEDIA_ERR_LOG("thread create failed: 0x%x", tret);
+            goto EXIT;
+        }
     }
     return 0;
 EXIT:
     g_audioSourceProcessInput.bThreadRun = false;
     return -1;
 }
+
+/* ------------------------------- 停止AI录音线程 ------------------------------- */
+int32_t StopStreamingRecordAndSend_AI(void)
+{
+    /* 若未在运行,直接返回 */
+    if (!g_audioSourceProcessInput.bThreadRun) {
+        MEDIA_ERR_LOG("StopStreamingRecordAndSend_AI not running");
+        return 0;
+    }
+
+    /* 请求线程优雅退出 */
+    g_sample.needStop = true;
+
+    /* 等待线程自行结束(AudioCaptureProcess_AI 结束时会调用 AudioCaptureStop) */
+    int wait_count = 0;
+    while (g_audioSourceProcessInput.bThreadRun && wait_count < 100) { /* 最多等待 ~1s */
+        usleep(10000);
+        wait_count++;
+    }
+
+    /* 若仍未退出,强制终止并做兜底清理 */
+    if (g_audioSourceProcessInput.bThreadRun) {
+        MEDIA_ERR_LOG("StopStreamingRecordAndSend_AI still running");
+        if (g_ai_record_thread_handle != 0) {
+            MEDIA_ERR_LOG("StopStreamingRecordAndSend_AI terminate thread");
+            (void)uapi_terminate_thread((void*)g_ai_record_thread_handle);
+            g_ai_record_thread_handle = 0;
+        }
+        /* 兜底释放音频资源 */
+        MEDIA_ERR_LOG("StopStreamingRecordAndSend_AI release audio resource");
+        AudioCaptureStop();
+    }
+    MEDIA_ERR_LOG("StopStreamingRecordAndSend_AI wait thread end");
+    return 0;
+}
 #endif
 
 #ifdef __cplusplus
index e455d25..a06e69e 100644 (file)
@@ -25,6 +25,7 @@ extern "C" {
 int32_t AudioCaptureSample(int32_t argc, const char *argv[]);
 
 int32_t streamingRecordAndSend_AI(int type);
+int32_t StopStreamingRecordAndSend_AI(void);
 
 void factory_set_recoder_streamType(void);
 
index bfb9b1a..d2e8787 100644 (file)
@@ -9493,7 +9493,7 @@ void cancel_AI_cur_chat_(void)
 {
     //if(AI_is_end_state)
     {
-          WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"取消当前AI对话\r\n");
+          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"取消当前AI对话\r\n");
         uint8_t data=1;
         ble_data_type type_={0x05,0x07,1,1,1};
         send_big_data(type_,(char *)&data,1);
index 3e25fb3..b5c0808 100644 (file)
@@ -1710,6 +1710,7 @@ void uapi_systemVolumeSet(int32_t volume)
 {
     printf("uapi_systemVolume:%d\n",volume);
     AudioServiceSetVolume(AUDIO_STREAM_MUSIC, volume);
+    AudioServiceSetVolume(AUDIO_STREAM_VOICE_ASSISTANT, volume);
 }
 
 /*系统声音获取*/