From d383ee5c771f3672261d2f5eca48e1f6a31bd678 Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Tue, 30 Sep 2025 12:03:04 +0800 Subject: [PATCH] =?utf8?q?=E4=BC=98=E5=8C=96=E5=BC=80=E6=9C=BA=E8=A7=92?= =?utf8?q?=E8=89=B2=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../thunderbird/include/ThunderBirdModel.h | 16 ++ .../thunderbird/src/ThunderBirdMainView.cpp | 30 +++- .../thunderbird/src/ThunderBirdModel.cpp | 152 +++++++++++++++++- 3 files changed, 195 insertions(+), 3 deletions(-) diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h index 3022283ed..a7cce68c6 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h @@ -122,6 +122,10 @@ namespace OHOS void ClearTextStr(); size_t GetTextLength() const; bool IsTextEmpty() const; + + void Readlocalconfig(); + // 解析JSON中的角色配置数据 + void ParseCharacterConfigData(const char* jsonData); // 二维码相关函数 std::string GetQrcodeContent(); @@ -153,6 +157,11 @@ namespace OHOS void SetCurrentView(int16_t view); void SetCurrentSubView(int16_t subView); void SetViewModel(); + + //存储表情和发型信息函数 + std::string ReadlocalExpression(); + std::string ReadlocalHair(); + bool ReadlocalScreenImage(); // 对话状态相关函数 int GetConversationStatus(); @@ -257,6 +266,13 @@ namespace OHOS bool bind_status = false; int16_t currentView_model = -1; int16_t currentSubView_model = -1; + + std::string eyesShape_; + std::string hairColor_; + std::string eyesColor_; + std::string hairStyle_; + std::string screenImage_; + bool screenImageAsEmoji_{false}; }; } diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp index ab7c1b8b8..9c2cc7a39 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp @@ -270,6 +270,14 @@ namespace OHOS AddViewToRootContainer(ScrollView_); Initback(); // 最底层 + if(ThunderBirdModel::GetInstance()->ReadlocalScreenImage() == true)//开启屏保模式 + { + OpenScreenImageModel(); + } + else + { + CloseScreenImageModel(); + } iconView = new UIImageView(); //(表情图片)需要遮罩时启用,预先增加在对应图层 iconView->SetAutoEnable(false); @@ -675,7 +683,15 @@ namespace OHOS curFace->SetResizeMode(UIImageView::COVER); curFace->SetStyle(STYLE_BACKGROUND_OPA, 0x00); //curFace->SetStyle(STYLE_BACKGROUND_COLOR, 0xffe0c7c1); - curFace->SetSrc("/user/res/hair/curly-hair/orange.bin"); + std::string newhair = ThunderBirdModel::GetInstance()->ReadlocalHair(); + if(newhair.empty() == false) + { + curFace->SetSrc(newhair.c_str()); + } + else + { + curFace->SetSrc("/user/res/hair/curly-hair/orange.bin"); + } surfaceView_ = new UILiteSurfaceView(); if (surfaceView_ == nullptr) @@ -704,6 +720,11 @@ namespace OHOS if (videoPlay_ == nullptr) { std::string uri("/user/res/video/CloseEyes/round-eyes/amber.mp4"); + std::string newuri = ThunderBirdModel::GetInstance()->ReadlocalExpression(); + if(newuri.empty() == false) + { + uri = newuri; + } videoPlay_ = new MediaVideoPlay(surface, nullptr, uri, true); if (videoPlay_ == nullptr) { @@ -744,7 +765,7 @@ namespace OHOS WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchIconImage: Invalid parameters"); return; } - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchIconImage: Switching to image: %s", imagePath); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchIconImage: Switching to image: %s", imagePath); iconView->SetSrc(imagePath); iconView->Invalidate(); } @@ -755,6 +776,11 @@ namespace OHOS { return false; } + //判断文件是否存在 + if(access(LN_DEVICE_SCREEN_IMAGE_FILE, F_OK) == -1) + { + return false; + } IsOpenScreenImageModel_ = true; //暂停视频播放 if (videoPlay_ != nullptr) { diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp index 75f8808aa..7ce88dfa2 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp @@ -33,6 +33,7 @@ #include "AppViewIDs.h" #include "NativeRegisterManager.h" #include "graphic_service_wrapper.h" +#include "cJSON.h" #define JUHEPINGTAI 0 #if JUHEPINGTAI #include "websocket_server_manager.h" @@ -88,6 +89,13 @@ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "目前绑定状态 %s", temp); uapi_setScreenDuration(30000);//自动息屏30秒 + Readlocalconfig(); + + printf(" eyesShape_ = %s", eyesShape_.c_str()); + printf(" hairColor_ = %s", hairColor_.c_str()); + printf(" eyesColor_ = %s", eyesColor_.c_str()); + printf(" hairStyle_ = %s", hairStyle_.c_str()); + printf(" screenImageAsEmoji_ = %d", screenImageAsEmoji_); } ThunderBirdModel::~ThunderBirdModel() @@ -878,6 +886,116 @@ 4、事项提醒 */ + void ThunderBirdModel::Readlocalconfig() + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] read character config"); + FILE *file = fopen(LN_CHARACTER_CONFIG_FILE, "rb"); + if (!file) + { + printf("[DEVICE_CHARACTER] fopen failed\n"); + return; + } + char json_buf[1024] = {0}; + size_t n = fread(json_buf, 1, sizeof(json_buf) - 1, file); + if (n == 0) + { + printf("[DEVICE_CHARACTER] empty config file\n"); + fclose(file); + return; + } + json_buf[n] = '\0'; + ParseCharacterConfigData(json_buf); + fclose(file); + printf("[DEVICE_CHARACTER] read character config success\n"); + } + + // 解析JSON中的data数据 + void ThunderBirdModel::ParseCharacterConfigData(const char* jsonData) + { + if (jsonData == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: jsonData is null"); + return; + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: parsing JSON data"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "JSON data: %s", jsonData); + + // 检查JSON数据是否为空或只包含空白字符 + if (strlen(jsonData) == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: JSON data is empty"); + return; + } + + // 解析JSON数据 + cJSON *root = cJSON_Parse(jsonData); + if (root == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: failed to parse JSON"); + return; + } + + // 获取data字段 + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (data == nullptr || !cJSON_IsObject(data)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: data field not found or not an object"); + cJSON_Delete(root); + return; + } + + // 解析characterAvatar字段 + cJSON *characterAvatar = cJSON_GetObjectItem(data, "characterAvatar"); + if (characterAvatar == nullptr || !cJSON_IsObject(characterAvatar)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: characterAvatar field not found or not an object"); + cJSON_Delete(root); + return; + } + + // 解析并保存各个字段 + cJSON *eyesShape = cJSON_GetObjectItem(characterAvatar, "eyesShape"); + if (eyesShape && cJSON_IsString(eyesShape)) { + eyesShape_ = std::string(eyesShape->valuestring); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: eyesShape = %s", eyesShape_.c_str()); + } + + cJSON *hairColor = cJSON_GetObjectItem(characterAvatar, "hairColor"); + if (hairColor && cJSON_IsString(hairColor)) { + hairColor_ = std::string(hairColor->valuestring); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: hairColor = %s", hairColor_.c_str()); + } + + cJSON *eyesColor = cJSON_GetObjectItem(characterAvatar, "eyesColor"); + if (eyesColor && cJSON_IsString(eyesColor)) { + eyesColor_ = std::string(eyesColor->valuestring); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: eyesColor = %s", eyesColor_.c_str()); + } + + cJSON *hairStyle = cJSON_GetObjectItem(characterAvatar, "hairStyle"); + if (hairStyle && cJSON_IsString(hairStyle)) { + hairStyle_ = std::string(hairStyle->valuestring); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: hairStyle = %s", hairStyle_.c_str()); + } + + cJSON *deviceScreen = cJSON_GetObjectItem(characterAvatar, "deviceScreen"); + if (deviceScreen && cJSON_IsString(deviceScreen)) { + screenImage_ = std::string(deviceScreen->valuestring); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: screenImage = %s", screenImage_.c_str()); + } + + cJSON *screenImageAsEmoji = cJSON_GetObjectItem(characterAvatar, "screenImageAsEmoji"); + if (screenImageAsEmoji && cJSON_IsBool(screenImageAsEmoji)) { + screenImageAsEmoji_ = cJSON_IsTrue(screenImageAsEmoji); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: screenImageAsEmoji = %s", screenImageAsEmoji_ ? "true" : "false"); + } + + // 清理JSON对象 + cJSON_Delete(root); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ParseCharacterConfigData: parsing completed"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Final values: eyesShape=%s, hairColor=%s, eyesColor=%s, hairStyle=%s, screenImage=%s, screenImageAsEmoji=%s", + eyesShape_.c_str(), hairColor_.c_str(), eyesColor_.c_str(), hairStyle_.c_str(), screenImage_.c_str(), + screenImageAsEmoji_ ? "true" : "false"); + } + + // ==================== 时间显示定时器实现 ==================== /** @@ -1497,6 +1615,13 @@ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " hairStyle: %s", hairStyle ? hairStyle : "null"); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " screenImageAsEmoji: %d", screenImageAsEmoji); + eyesShape_ = eyesShape; + hairColor_ = hairColor; + eyesColor_ = eyesColor; + hairStyle_ = hairStyle; + screenImageAsEmoji_ = screenImageAsEmoji; + + // 这里可以添加角色配置更改的具体处理逻辑 // 例如: // 1. 更新角色外观显示 @@ -1516,6 +1641,31 @@ // SaveCharacterConfig(characterId, characterName, eyesShape, hairColor, eyesColor, hairStyle, screenImageAsEmoji); } + //开机读取表情 + std::string ThunderBirdModel::ReadlocalExpression() + { + // 如果eyesShape_或eyesColor_为空,则返回空字符串 + if (eyesShape_.empty() || eyesColor_.empty()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ReadlocalExpression: eyesShape or eyesColor is empty"); + return ""; + } + return "/user/res/video/CloseEyes/" + eyesShape_ + "/" + eyesColor_ + ".mp4"; + } + //开机读取发型 + std::string ThunderBirdModel::ReadlocalHair() + { + // 如果hairStyle_或hairColor_为空,则返回空字符串 + if (hairStyle_.empty() || hairColor_.empty()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ReadlocalHair: hairStyle or hairColor is empty"); + return ""; + } + return "/user/res/hair/" + hairStyle_ + "/" + hairColor_ + ".bin"; + } + //是否开启屏保模式 + bool ThunderBirdModel::ReadlocalScreenImage() + { + return screenImageAsEmoji_; + } void ThunderBirdModel::HandleChatStaminaChange(int chatLeft, const char* chatDesc, int flowLeft, const char* flowDesc, const char* qrcodeUrl) @@ -1583,7 +1733,7 @@ expressionPath += "/"; expressionPath += eyeColor; expressionPath += ".mp4"; - + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SwitchExpression: switching to %s", expressionPath.c_str()); // 通过图形服务调用 ThunderBirdMainView 的 SwitchVideo 函数 // 注意:PostGraphicEvent 是异步的,这里直接返回 true 表示调用已提交 -- 2.17.1