From e2def15a30e23f54fec3eb21b2dbe299d647f75e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E8=A2=81=E6=B8=85=E6=A2=A6?= <3449750381@qq.com> Date: Sat, 28 Sep 2024 23:35:10 +0000 Subject: [PATCH] Merge #1050 into sdk602patch0626 from refs/changes/1050/head MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Code review from 袁清梦 * refs/changes/1050/head: (8 commits squashed) - 室外跑步,走路。统一使用室内算法 - Merge branch 'sdk602patch0626' of https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230 into sdk602patch0626 - 修改遥控拍照Slice析构 - 增加topic发送错误的错误打印 - 增加判断文件是否存在的统一接口 - 增加训练的配速表,心率表相关接口 - 修改卡片list为不循环 - 修改消息Slice的显示以及读取 Signed-off-by: Caisking <3449750381@qq.com> Reviewed-by: snickersun@163.com Merged-by: snickersun@163.com CR-link: https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230/change/1050 --- .../uicomponents/UIComponents.cpp | 10 + .../uicomponents/UIComponents.h | 2 + .../nativelauncher/include/UiConfig.h | 53 +- .../nativelauncher/src/NativeLauncher.cpp | 12 +- .../nativeui/add_card/src/AddCardView.cpp | 2 +- .../message/include/MessageCardView.h | 34 +- .../message/include/MessageLackView.h | 1 - .../message/include/MessageShowView.h | 1 - .../nativeui/message/include/MessageView.h | 5 +- .../nativeui/message/src/MessageAdapter.cpp | 6 + .../nativeui/message/src/MessageCardView.cpp | 36 +- .../message/src/MessageControlView.cpp | 2 + .../nativeui/message/src/MessageLackView.cpp | 7 - .../nativeui/message/src/MessageModel.cpp | 45 +- .../nativeui/message/src/MessagePresenter.cpp | 5 +- .../nativeui/message/src/MessageShowView.cpp | 13 +- .../nativeui/message/src/MessageView.cpp | 542 ++- .../takephotos/include/TakephotosView.h | 1 - .../takephotos/src/TakephotosView.cpp | 141 +- .../nativeui/traing/include/TraingModel.h | 652 +-- .../nativeui/traing/src/TraingModel.cpp | 3507 +++++++++-------- .../peripheral/utilscpp/custom_utilscpp.cpp | 86 +- 22 files changed, 2661 insertions(+), 2502 deletions(-) diff --git a/code/sdk/application/wearable/CustomUIComponentTool/uicomponents/UIComponents.cpp b/code/sdk/application/wearable/CustomUIComponentTool/uicomponents/UIComponents.cpp index 800087976..cfb778daf 100644 --- a/code/sdk/application/wearable/CustomUIComponentTool/uicomponents/UIComponents.cpp +++ b/code/sdk/application/wearable/CustomUIComponentTool/uicomponents/UIComponents.cpp @@ -9,6 +9,10 @@ #include #include #include +#include +#include +#include + namespace OHOS { @@ -911,5 +915,11 @@ namespace OHOS path.c_str()); } } + + // 检查文件是否可打开并且不为空 + bool IsFileAccessibleAndNotEmpty(const std::string& filePath) { + std::ifstream file(filePath); + return file.is_open() && file.peek() != std::ifstream::traits_type::eof(); + } } diff --git a/code/sdk/application/wearable/CustomUIComponentTool/uicomponents/UIComponents.h b/code/sdk/application/wearable/CustomUIComponentTool/uicomponents/UIComponents.h index 41dccf9c3..1b28230ca 100644 --- a/code/sdk/application/wearable/CustomUIComponentTool/uicomponents/UIComponents.h +++ b/code/sdk/application/wearable/CustomUIComponentTool/uicomponents/UIComponents.h @@ -306,6 +306,8 @@ namespace OHOS void CreateDirectoryIfNotExists(const std::string &path); + bool IsFileAccessibleAndNotEmpty(const std::string& filePath); + #endif } // namespace OHOS diff --git a/code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h b/code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h index 0a59850c1..9f3572e87 100644 --- a/code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h +++ b/code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h @@ -201,7 +201,7 @@ namespace OHOS static constexpr const char *PNG_COUNTDOWN_TIME_IMAGE_21 = APP_RES_PATH "/COUNTDOWN_IMAGE_22.bin"; static constexpr const char *PNG_COUNTDOWN_TIME_IMAGE_22 = APP_RES_PATH "/COUNTDOWN_IMAGE_23.bin"; static constexpr const char *PNG_COUNTDOWN_TIME_IMAGE_23 = APP_RES_PATH "/COUNTDOWN_IMAGE_24.bin"; - + /*血氧动画*/ static constexpr const char *PNG_CHECK_TIME_IMAGE_0 = APP_RES_PATH "/Blood/spo2_gif/spo2_01.bin"; static constexpr const char *PNG_CHECK_TIME_IMAGE_1 = APP_RES_PATH "/Blood/spo2_gif/spo2_02.bin"; static constexpr const char *PNG_CHECK_TIME_IMAGE_2 = APP_RES_PATH "/Blood/spo2_gif/spo2_03.bin"; @@ -232,6 +232,57 @@ namespace OHOS static constexpr const char *PNG_CHECK_TIME_IMAGE_27 = APP_RES_PATH "/Blood/spo2_gif/spo2_28.bin"; static constexpr const char *PNG_CHECK_TIME_IMAGE_28 = APP_RES_PATH "/Blood/spo2_gif/spo2_29.bin"; static constexpr const char *PNG_CHECK_TIME_IMAGE_29 = APP_RES_PATH "/Blood/spo2_gif/spo2_30.bin"; + /*遥控拍照动画*/ + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_0 = APP_RES_PATH "/takephotos/cream/1.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_1 = APP_RES_PATH "/takephotos/cream/2.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_2 = APP_RES_PATH "/takephotos/cream/3.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_3 = APP_RES_PATH "/takephotos/cream/4.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_4 = APP_RES_PATH "/takephotos/cream/5.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_5 = APP_RES_PATH "/takephotos/cream/6.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_6 = APP_RES_PATH "/takephotos/cream/7.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_7 = APP_RES_PATH "/takephotos/cream/8.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_8 = APP_RES_PATH "/takephotos/cream/9.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_9 = APP_RES_PATH "/takephotos/cream/10.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_10 = APP_RES_PATH "/takephotos/cream/11.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_11 = APP_RES_PATH "/takephotos/cream/12.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_12 = APP_RES_PATH "/takephotos/cream/13.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_13 = APP_RES_PATH "/takephotos/cream/14.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_14 = APP_RES_PATH "/takephotos/cream/15.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_15 = APP_RES_PATH "/takephotos/cream/16.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_16 = APP_RES_PATH "/takephotos/cream/17.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_17 = APP_RES_PATH "/takephotos/cream/18.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_18 = APP_RES_PATH "/takephotos/cream/19.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_19 = APP_RES_PATH "/takephotos/cream/20.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_20 = APP_RES_PATH "/takephotos/cream/21.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_21 = APP_RES_PATH "/takephotos/cream/22.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_22 = APP_RES_PATH "/takephotos/cream/23.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_23 = APP_RES_PATH "/takephotos/cream/24.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_24 = APP_RES_PATH "/takephotos/cream/25.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_25 = APP_RES_PATH "/takephotos/cream/26.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_26 = APP_RES_PATH "/takephotos/cream/27.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_27 = APP_RES_PATH "/takephotos/cream/28.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_28 = APP_RES_PATH "/takephotos/cream/29.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_29 = APP_RES_PATH "/takephotos/cream/30.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_30 = APP_RES_PATH "/takephotos/cream/31.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_31 = APP_RES_PATH "/takephotos/cream/32.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_32 = APP_RES_PATH "/takephotos/cream/33.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_33 = APP_RES_PATH "/takephotos/cream/34.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_34 = APP_RES_PATH "/takephotos/cream/35.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_35 = APP_RES_PATH "/takephotos/cream/36.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_36 = APP_RES_PATH "/takephotos/cream/37.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_37 = APP_RES_PATH "/takephotos/cream/38.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_38 = APP_RES_PATH "/takephotos/cream/39.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_39 = APP_RES_PATH "/takephotos/cream/40.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_40 = APP_RES_PATH "/takephotos/cream/41.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_41 = APP_RES_PATH "/takephotos/cream/42.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_42 = APP_RES_PATH "/takephotos/cream/43.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_43 = APP_RES_PATH "/takephotos/cream/44.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_44 = APP_RES_PATH "/takephotos/cream/45.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_45 = APP_RES_PATH "/takephotos/cream/46.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_46 = APP_RES_PATH "/takephotos/cream/47.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_47 = APP_RES_PATH "/takephotos/cream/48.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_48 = APP_RES_PATH "/takephotos/cream/49.bin"; + static constexpr const char *PNG_TAKE_PHOTO_IMAGE_49 = APP_RES_PATH "/takephotos/cream/50.bin"; /* -------------------------------------------------------------------------- */ static constexpr const char *PNG_ALIPAY_BIND_FAILURE = APP_RES_PATH "/alipay/ALIPAY_BIND_FAILURE.bin"; static constexpr const char *PNG_ALIPAY_BIND_SUCCESS = APP_RES_PATH "/alipay/ALIPAY_BIND_SUCCESS.bin"; diff --git a/code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp b/code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp index 5d58f7281..5804b385a 100644 --- a/code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp +++ b/code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp @@ -538,16 +538,22 @@ namespace OHOS C_ScheduleDataReadFromFile(); mmi_sleep_mode_switch_read(); - /*开机如果设置了密码锁,进行锁屏*/ + /*开机读取消息历史数据*/ + if(!MessageModel::GetInstance().LoadMessagesFromStorage()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadMessagesFromStorage failed!"); + } + + /*开机检查如果设置了密码锁,进行锁屏*/ int lockstate = OHOS::ConfigModel::GetInstance()->get_configData_int(OHOS::ConfigModel::CONFIGMODEL_ITEM_PASSWORD_SWITCH); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "lockstate = %d", lockstate); // 打印锁定状态判断 if (lockstate == 1) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Native ability state is active."); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Device is locked (lock state == 1)"); if (uapi_dev_runtime_get_lock_status() == 0) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Device is unlocked (lock status == 0)."); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Device is unlocked (lock status == 0)"); uapi_dev_runtime_set_lock_status(1); // 上锁 OHOS::MainModel::GetInstance().setDialState(OHOS::DialState::LOCK, true); } diff --git a/code/sdk/application/wearable/fd230app/nativeui/add_card/src/AddCardView.cpp b/code/sdk/application/wearable/fd230app/nativeui/add_card/src/AddCardView.cpp index 5c7bb939d..6dfd26b45 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/add_card/src/AddCardView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/add_card/src/AddCardView.cpp @@ -110,7 +110,7 @@ namespace OHOS contentList_.SetScrollStateListener(presenter_); contentList_.SetOnDragListener(presenter_); contentList_.SetMaxScrollDistance(1000); - contentList_.SetLoopState(true); + contentList_.SetLoopState(false);//设置不循环 contentList_.SetAdapter(addCardAdapter_); contentList_.SetVisible(true); diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageCardView.h b/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageCardView.h index 004871412..526eca9c6 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageCardView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageCardView.h @@ -1,33 +1,4 @@ -/*** - * @Date: 2024-07-10 16:58:06 - * @LastEditors: Caisking 3449750381@qq.com - * @LastEditTime: 2024-08-24 17:36:42 - * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageCardView.h - */ -/*** - * @Date: 2024-07-10 16:58:06 - * @LastEditors: Caisking 3449750381@qq.com - * @LastEditTime: 2024-07-25 10:57:25 - * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageCardView.h - */ -/*** - * @Date: 2024-04-15 10:55:58 - * @LastEditors: Caisking 3449750381@qq.com - * @LastEditTime: 2024-06-22 17:52:45 - * @FilePath: /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageCardView.h - */ -/*** - * @Date: 2024-04-15 10:55:58 - * @LastEditors: Caisking 3449750381@qq.com - * @LastEditTime: 2024-06-19 17:56:08 - * @FilePath: /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageCardView.h - */ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: MessageCardView.h - * Author: - * Create: 2021-12-21 - */ + #ifndef MESSAGE_CARD_VIEW_H #define MESSAGE_CARD_VIEW_H @@ -66,11 +37,8 @@ namespace OHOS private: void ClearAll(void); - UILabelExt *title{nullptr}; MessageListAdapter *p_MessageListAdapter{nullptr}; UIList *MessageList = nullptr; - UILabelButtonExt *DeleteButton = nullptr; // 删除按键 - MessageModel *p_MessageModel{nullptr}; UIImageView *imageline{nullptr}; }; } diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageLackView.h b/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageLackView.h index a6174653a..53adf1f38 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageLackView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageLackView.h @@ -42,7 +42,6 @@ namespace OHOS private: UIImageView *imageline{nullptr}; UIImageView *imagemeage{nullptr}; - UILabelExt *labeltitle{nullptr}; UILabelExt *labelmeage{nullptr}; void ClearAll(void); diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageShowView.h b/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageShowView.h index 457d57e2e..d8bdf8c26 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageShowView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageShowView.h @@ -59,7 +59,6 @@ namespace OHOS UILabel *title{nullptr}; UILabel *time{nullptr}; - UILabel *message{nullptr}; UILabelButton *messageButton{nullptr}; // 消息 UILabelButtonExt *deleteButton{nullptr}; // 清除按键 diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageView.h b/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageView.h index 1a56c244d..dd549502b 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageView.h @@ -63,15 +63,12 @@ namespace OHOS /*消息列表界面*/ UIScrollView *messageView{nullptr}; - UILabelExt *title{nullptr}; + UIImageView *imageline2{nullptr}; MessageListAdapter *p_MessageListAdapter{nullptr}; UIList *MessageList = nullptr; - UILabelButtonExt *DeleteButton = nullptr; // 删除按键 - UIView::OnDragListener *draglistener{nullptr}; bool viewInitStatus{false}; - MessageModel *g_MessageModel{nullptr}; }; } // namespace OHOS #endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageAdapter.cpp b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageAdapter.cpp index 75a2403c5..3e7aceaca 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageAdapter.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageAdapter.cpp @@ -20,6 +20,11 @@ namespace OHOS MessageListAdapter::~MessageListAdapter() { + if(DeleteButton) + { + delete DeleteButton; + DeleteButton = nullptr; + } listData.clear(); } @@ -98,6 +103,7 @@ namespace OHOS else { item = static_cast(inView); + item->TearDownChild(); item->RemoveAll(); } item->SetUpChild(); diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageCardView.cpp b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageCardView.cpp index 3cbf62096..861644ef9 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageCardView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageCardView.cpp @@ -4,6 +4,7 @@ * Author: * Create: 2021-12-21 */ + #include #include "common/image_cache_manager.h" #include "ui_resource_image.h" @@ -52,14 +53,11 @@ namespace OHOS delete MessageList; MessageList = nullptr; } - if (DeleteButton != nullptr) + if(p_MessageListAdapter != nullptr) { - delete DeleteButton; - DeleteButton = nullptr; - } - - delete p_MessageListAdapter; - p_MessageListAdapter = nullptr; + delete p_MessageListAdapter; + p_MessageListAdapter = nullptr; + } } void MessageCardView::AddMessageToList(const MessageListItem &item) { @@ -75,15 +73,20 @@ namespace OHOS Add(imageline); // UIList 的适配器 - p_MessageListAdapter = new MessageListAdapter(); + if(p_MessageListAdapter == nullptr) + { + p_MessageListAdapter = new MessageListAdapter(); + } + p_MessageListAdapter->SetItemClickListener(MessageControlPresenter::GetInstance()); if (MessageList == nullptr) { MessageList = new UIList(); } + // MessageList->SetPosition(MORE_LIST_POSITION_X, MORE_LIST_POSITION_Y, 466, 466); MessageList->SetPosition(MORE_LIST_POSITION_X, MORE_LIST_POSITION_Y, 466, 466); - MessageList->SetScrollBlankSize(35); - MessageList->SetReboundSize(50); + // MessageList->SetScrollBlankSize(35); + // MessageList->SetReboundSize(50); MessageList->SetThrowDrag(true); MessageList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); MessageList->SetMaxScrollDistance(1000); // 1000: max scroll distance @@ -130,16 +133,11 @@ namespace OHOS } void MessageCardView::SetUpView(MessageCardView *messageCardView) { - p_MessageModel = &MessageModel::GetInstance(); - if (p_MessageModel == nullptr) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_MessageModel fail"); - return; - } /* 加载list */ - p_MessageModel->InitMessageListItems(); - const MessageListItem *itemInfo = p_MessageModel->GetMessageListItems(); - for (int i = 0; i < p_MessageModel->GetMessageCount(); i++) + MessageModel::GetInstance().InitMessageListItems(); + const MessageListItem *itemInfo = MessageModel::GetInstance().GetMessageListItems(); + uint8_t num = MessageModel::GetInstance().GetMessageCount(); + for (int i = 0; i < num; i++) { messageCardView->AddMessageToList(itemInfo[i]); } diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageControlView.cpp b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageControlView.cpp index d7347151c..dbca24ac4 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageControlView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageControlView.cpp @@ -34,11 +34,13 @@ namespace OHOS RemoveAll(); if (messageLackView != nullptr) { + messageLackView->RemoveAll(); delete messageLackView; messageLackView = nullptr; } if (messageCardView != nullptr) { + messageCardView->RemoveAll(); delete messageCardView; messageCardView = nullptr; } diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageLackView.cpp b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageLackView.cpp index 3df4d0cb7..7edac4bd2 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageLackView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageLackView.cpp @@ -47,11 +47,6 @@ namespace OHOS delete imagemeage; imagemeage = nullptr; } - if (labeltitle != nullptr) - { - delete labeltitle; - labeltitle = nullptr; - } if (labelmeage != nullptr) { delete labelmeage; @@ -69,7 +64,6 @@ namespace OHOS WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageLackView::CreateUIViewGroup"); /*初始化label*/ - InitLabelExt(labeltitle, 83, 50, 300, 35, "labletitle", STR_MESSAGE_NOTIFICATION, DEFAULT_VECTOR_FONT_FILENAME, 30); InitLabelExt(labelmeage, 53, 276, 360, 40, "labelMessage", STR_MESSAGENO, DEFAULT_VECTOR_FONT_FILENAME, 30); labelmeage->SetTextColor(Color::GetColorFromRGBA(0x66, 0x66, 0x66, 0xff)); /*初始化image*/ @@ -78,7 +72,6 @@ namespace OHOS Add(imageline); Add(imagemeage); - Add(labeltitle); Add(labelmeage); SetDraggable(false); diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageModel.cpp index 5b83e40c1..8ad2b498b 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageModel.cpp @@ -109,7 +109,13 @@ extern "C" WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "request %d\r\n", request->msgId); if (request->msgId == TOPIC_EVENT_MESSAGE_UPDATA) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TOPIC_EVENT_MESSAGE_UPDATA"); ancs_data_info_t *messageInfo = new ancs_data_info_t(); + if(messageInfo == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new ancs_data_info_t fail"); + return; + } int rets = memcpy_s(messageInfo, sizeof(ancs_data_info_t), (ancs_data_info_t *)request->data, request->len); if (rets != EOK) { @@ -142,7 +148,7 @@ namespace OHOS MessageModel::MessageModel() { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageModel"); - LoadMessagesFromStorage(); + // LoadMessagesFromStorage(); } MessageModel::~MessageModel() { @@ -202,7 +208,7 @@ namespace OHOS } // 清空现有数据 - MessageVector.clear(); + // MessageVector.clear(); // 将JSON数据转换为MessageData并添加到消息数组中 int dataCount = cJSON_GetArraySize(messageArray); @@ -321,8 +327,12 @@ namespace OHOS bool unread_state = false; // 初始化未读状态 numberOfItems = MessageVector.size(); // 获取 MessageVector 的大小 - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "当前的项数是 %d", numberOfItems); - + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前的项数是 %d", numberOfItems); + if(numberOfItems == 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageVector is empty"); + return; + } // 从 MessageVector 的末尾开始迭代 for (int i = numberOfItems - 1, count = 0; i >= 0 && count < MaxMessageListCount; i--, count++) { @@ -369,7 +379,7 @@ namespace OHOS data.labelTitle = messageInfo->title; data.timestamp = messageInfo->time; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddMessageData data.isRead is %d,data.labelDetails is %s,data.labelTitle is %s,data.timestamp is %d", data.isRead, data.labelDetails.c_str(), data.labelTitle.c_str(), data.timestamp); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddMessageData data.isRead is %d,data.labelDetails is %s,data.labelTitle is %s,data.timestamp is %d", data.isRead, data.labelDetails.c_str(), data.labelTitle.c_str(), data.timestamp); char labelTime[20]; if (uapi_get_TIME_STR(data.timestamp, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC) @@ -470,31 +480,8 @@ namespace OHOS void MessageModel::UpdateMessageView() { // 更新主界面卡片 - if (MessageControlView::GetInstance()) + if (MessageControlView::GetInstance()&&MainViewSample::GetInstance()) { -#if 0 - MessageControlView::GetInstance()->SetLackView(false); - auto messageCard = MessageCardView::GetInstance(); - if (messageCard) // 检查主界面卡片实例 - { - uint8_t status = MessageModel::GetInstance().HasDataVector(); - if (status) - { - InitMessageListItems(); // 更新列表item - MessageListAdapter *p_MessageListAdapter = new MessageListAdapter(); - messageCard->GetList()->RefreshList(); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateListView messageCardView"); - } - else - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "No new data to refresh the message card list."); - } - } - else - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateListView: messageCardView instance is nullptr"); - } -#endif // 配置主界面回退界面 CardId Id = MainViewSample::GetInstance()->GetHorCurrentCard(); MainModel::GetInstance().SetFromSetCardView(true); diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessagePresenter.cpp b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessagePresenter.cpp index cf5397be8..ae92dbe11 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessagePresenter.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessagePresenter.cpp @@ -84,7 +84,10 @@ namespace OHOS { NativeAbility::GetInstance().Back(); } - + if(event.GetDragDirection() == DragEvent::DIRECTION_TOP_TO_BOTTOM) + { + NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN); + } return true; } diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageShowView.cpp b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageShowView.cpp index 3cc5de923..abb9c33cc 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageShowView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageShowView.cpp @@ -66,15 +66,17 @@ namespace OHOS } void MessageShowView::DeInitView() { + if(container_) + { + container_->RemoveAll(); + } + delete title; title = nullptr; delete time; time = nullptr; - delete message; - message = nullptr; - delete messageButton; messageButton = nullptr; @@ -190,9 +192,6 @@ namespace OHOS messageButton->SetText(messageStr.c_str()); // messageButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); /* -------------------------------------------------------------------------- */ - InitUILabel(message, 63, 165, 340, 100, "message", messageStr.c_str(), DEFAULT_VECTOR_FONT_FILENAME, 30); - message->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); // 宽固定 高度变长! - message->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); /*加载清除按键*/ InitButtonExt(deleteButton, 43, 157 + defaultRectWidth + 20, 380, 100, DELETEBUTTON, STR_CLEAN, 30); deleteButton->SetOnClickListener(static_cast(MessageShowPresenter::GetInstance())); @@ -200,7 +199,6 @@ namespace OHOS container_->Add(title); container_->Add(time); container_->Add(messageButton); - // container_->Add(message); container_->Add(deleteButton); /* -------------------------------------------------------------------------- */ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitView is ok!"); @@ -219,6 +217,7 @@ namespace OHOS titleStr = data->labelTitle; timeStr = data->labelTime; messageStr = data->labelDetails; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateMessage title %s time %s message %s", titleStr.c_str(), timeStr.c_str(), messageStr.c_str()); } void MessageShowView::PreLoad(void) { diff --git a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageView.cpp b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageView.cpp index 71d272d2f..bbb2b4fd9 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageView.cpp @@ -2,290 +2,274 @@ * @Date: 2024-07-12 11:19:45 * @LastEditors: Caisking 3449750381@qq.com * @LastEditTime: 2024-08-09 14:03:51 - * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageView.cpp + * @FilePath: + * /FD230/code/sdk/application/wearable/fd230app/nativeui/message/src/MessageView.cpp */ #include "message/include/MessageView.h" -#include "message/include/MessagePresenter.h" #include "message/include/MessageModel.h" +#include "message/include/MessagePresenter.h" #include "UiConfig.h" -#include "wearable_log.h" #include "uicomponents/UIComponents.h" -namespace OHOS -{ - static constexpr char *lineimagePath = "/user/res/message/Line.bin"; - static constexpr char *messageimagePath = "/user/res/message/message.bin"; - static const uint32_t BACK_GROUND_COLOR = 0xfff6f6f6; - static constexpr int16_t More_LIST_POSITION_X = 43; - static constexpr int16_t More_LIST_POSITION_Y = 120; - static constexpr int16_t More_SCROLLBLANKSIZE = 35; // 设置此滚动视图的空白大小。 - static constexpr int16 MAX_SCR_DIS = 1000; - static constexpr int16 LIST_POS = 20; - static constexpr int16 SNUM_2 = 2; - static constexpr uint8_t NUM_2 = 2; - - static MessageView *g_pMessageView{nullptr}; - - MessageView::MessageView() - { - // SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); - g_pMessageView = this; - } - - MessageView::~MessageView() - { - // if (viewInitStatus == true) - // { - // DeInitView(); - // } - UIViewGroup *tmpGroup = dynamic_cast(container_); - UIViewGroup::RemoveAndDeleteAllRecursively(tmpGroup); - - g_pMessageView = nullptr; - } - - MessageView *MessageView::GetInstance() - { - return g_pMessageView; - } - void MessageView::InitView() - { - // 展示界面 - if (MessageModel::GetInstance().HasDataVector()) - { - printf("存在数据!\r\n"); - SetPopupViewStatus(PopupMessage::MessagePopup, true); - } - else - { - printf("不存在数据!\r\n"); - SetPopupViewStatus(PopupMessage::LackPopup, true); - } - } - void MessageView::DeInitView() - { - lackView->RemoveAll(); - messageView->RemoveAll(); - MessageList->RemoveAll(); - - delete labeltitle; - labeltitle = nullptr; - - delete labelmeage; - labelmeage = nullptr; - - delete imageline; - imageline = nullptr; - - delete imagemeage; - imagemeage = nullptr; - - delete lackView; - lackView = nullptr; - - delete title; - title = nullptr; - delete title; - title = nullptr; - - delete DeleteButton; - DeleteButton = nullptr; - - delete MessageList; - MessageList = nullptr; - - delete messageView; - messageView = nullptr; - - delete draglistener; - draglistener = nullptr; - } - - void MessageView::PreLoad(void) - { - if (!viewInitStatus) - { - InitView(); - viewInitStatus = true; - } - } - - /*无数据界面*/ - void MessageView::ShowLackView() - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowLackView start"); - lackView = new UIScrollView(); - if (lackView == nullptr) - { - return; - } - lackView->SetPosition(0, 0); - lackView->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); - lackView->SetScrollBlankSize(20); - lackView->SetReboundSize(50); - lackView->SetDirection(1); - /*初始化label*/ - InitLabelExt(labeltitle, 83, 50, 300, 35, "labletitle", STR_MESSAGE_NOTIFICATION, DEFAULT_VECTOR_FONT_FILENAME, 30); - InitLabelExt(labelmeage, 53, 276, 360, 40, "labelMessage", STR_MESSAGENO, DEFAULT_VECTOR_FONT_FILENAME, 30); - labelmeage->SetTextColor(Color::GetColorFromRGBA(0x66, 0x66, 0x66, 0xff)); - /*初始化image*/ - InitImageView(imageline, 193, 30, 365, 35, "image", lineimagePath); - InitImageView(imagemeage, 183, 156, 100, 100, "image", messageimagePath); - - lackView->Add(imageline); - lackView->Add(imagemeage); - lackView->Add(labeltitle); - lackView->Add(labelmeage); - - container_->Add(lackView); - lackView->SetDraggable(true); - lackView->SetTouchable(true); - - lackView->SetOnDragListener(presenter_); - - lackView->SetVisible(false); // 界面隐藏 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowLackView end"); - } - - /*数据界面*/ - void MessageView::ShowMessageView() - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowmessageView start"); - messageView = new UIScrollView(); - if (messageView == nullptr) - { - return; - } - messageView->SetPosition(0, 0); - messageView->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); - messageView->SetScrollBlankSize(20); - messageView->SetReboundSize(50); - messageView->SetDirection(1); - - /*初始化label*/ - InitLabelExt(title, 83, 50, 300, 35, "labletitle", STR_MESSAGE_NOTIFICATION, DEFAULT_VECTOR_FONT_FILENAME, 30); - messageView->Add(title); - - // UIList 的适配器 - p_MessageListAdapter = new MessageListAdapter(); - p_MessageListAdapter->SetItemClickListener(presenter_); - if (MessageList == nullptr) - { - MessageList = new UIList(); - } - MessageList->SetPosition(More_LIST_POSITION_X, More_LIST_POSITION_Y, 466, 466); - MessageList->SetScrollStateListener(this); - MessageList->SetThrowDrag(true); - MessageList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); - // 设置手指抬起屏幕后的最大滚动距离 - MessageList->SetMaxScrollDistance(1000); // 1000: max scroll distance - // 设置手指抬起屏幕后的补偿距离 - MessageList->SetSwipeACCLevel(800); // 800: compensation distance - // 设置拖动加速 - MessageList->SetDragACCLevel(5); // 5: drag acceleration - MessageList->SetYScrollBarVisible(true); - - MessageList->SetOnClickListener(presenter_); - messageView->SetOnDragListener(presenter_); - - messageView->SetVisible(false); // 隐藏界面 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowmessageView end"); - } - void MessageView::UpdataButton(int num) - { - int top = num * 240; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "old top %d", top); - top > 466 ? top += 130 : top -= 100; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new top %d", top); - DeleteButton->SetPosition(43, top); - } - /*控制显示界面*/ - void MessageView::SetPopupViewStatus(PopupMessage view, bool status) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetPopupViewStatus %d", view); - - if (view == PopupMessage::LackPopup) - { - MessageModel::GetInstance().SetPopupViewState(false); // 设置状态为无消息 - lackView->SetVisible(true); // 隐藏界面 - messageView->SetVisible(false); // 隐藏界面 - } - else if (view == PopupMessage::MessagePopup) - { - MessageModel::GetInstance().SetPopupViewState(true); // 设置状态为有消息 - lackView->SetVisible(false); // 隐藏界面 - messageView->SetVisible(true); // 隐藏界面 - } - } - - /// @brief 页面启动时需要执行的代码逻辑 - void MessageView::OnStart() - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartResultView::OnStart"); - View::OnStart(); - - // SetContainerView(new UIScrollView()); - container_ = new UIScrollView(); - container_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); - container_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); - container_->SetOnDragListener(presenter_); - container_->SetTouchable(true); - container_->SetDraggable(true); - // container_->SetFullScreenBlur(true); // 设置高斯模糊 - - ShowLackView(); - ShowMessageView(); - PreLoad(); - - SetContainerView(container_); - - RootView::GetInstance()->SetOnKeyActListener(presenter_); - } - void MessageView::AddMessageToList(const MessageListItem &item) - { - p_MessageListAdapter->AddListItem(item); - } - // 获取列表 - UIList *MessageView::GetList() - { - return MessageList; - } - /// @brief 创建页面的视图 - void MessageView::OnSetUpView() - { - View::OnSetUpView(); - if (MessageModel::GetInstance().HasDataVector()) - { - messageView->Add(MessageList); - messageView->Add(DeleteButton); - // messageView->SetFullScreenBlur(true); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageList is add"); - container_->Add(messageView); - // container_->SetFullScreenBlur(true); - MessageList->SetAdapter(p_MessageListAdapter); - } - Draw(); - } - - /// @brief 销毁页面的视图 - void MessageView::OnTearDownView() - { - View::OnTearDownView(); - return; - } - - /// @brief 页面结束时需要执行的销毁逻辑。 - void MessageView::OnStop() - { - View::OnStop(); - if (container_ != nullptr) - { - container_->RemoveAll(); - delete container_; - container_ = nullptr; - } - RootView::GetInstance()->RemoveAll(); - return; +#include "wearable_log.h" +namespace OHOS { +static constexpr char *lineimagePath = "/user/res/message/Line.bin"; +static constexpr char *messageimagePath = "/user/res/message/message.bin"; +static const uint32_t BACK_GROUND_COLOR = 0xfff6f6f6; +static constexpr int16_t More_LIST_POSITION_X = 43; +static constexpr int16_t More_LIST_POSITION_Y = 120; +static constexpr int16_t More_SCROLLBLANKSIZE = + 35; // 设置此滚动视图的空白大小。 +static constexpr int16 MAX_SCR_DIS = 1000; +static constexpr int16 LIST_POS = 20; +static constexpr int16 SNUM_2 = 2; +static constexpr uint8_t NUM_2 = 2; + +static MessageView *g_pMessageView{nullptr}; + +MessageView::MessageView() { + // SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + g_pMessageView = this; +} + +MessageView::~MessageView() { + if (viewInitStatus == true) { + DeInitView(); + } + // UIViewGroup *tmpGroup = dynamic_cast(container_); + // UIViewGroup::RemoveAndDeleteAllRecursively(tmpGroup); + + g_pMessageView = nullptr; +} + +MessageView *MessageView::GetInstance() { return g_pMessageView; } +void MessageView::InitView() { + // 展示界面 + if (MessageModel::GetInstance().HasDataVector()) { + printf("存在数据!\r\n"); + SetPopupViewStatus(PopupMessage::MessagePopup, true); + } else { + printf("不存在数据!\r\n"); + SetPopupViewStatus(PopupMessage::LackPopup, true); + } +} +void MessageView::DeInitView() { + // 移除视图中的所有子项 + if (lackView) { + lackView->RemoveAll(); + } + + if (messageView) { + messageView->RemoveAll(); + } + + if (p_MessageListAdapter) { + delete p_MessageListAdapter; + p_MessageListAdapter = nullptr; + } + + if (MessageList) { + MessageList->RemoveAll(); + delete MessageList; + MessageList = nullptr; + } + + // 删除所有标签和图像指针,确保指针非空 + if (labeltitle) { + delete labeltitle; + labeltitle = nullptr; + } + + if (labelmeage) { + delete labelmeage; + labelmeage = nullptr; + } + + if (imageline) { + delete imageline; + imageline = nullptr; + } + + if (imageline2) { + delete imageline2; + imageline2 = nullptr; + } + + if (imagemeage) { + delete imagemeage; + imagemeage = nullptr; + } + + if (lackView) { + delete lackView; + lackView = nullptr; + } + + if (messageView) { + delete messageView; + messageView = nullptr; + } +} + +void MessageView::PreLoad(void) { + if (!viewInitStatus) { + InitView(); + viewInitStatus = true; + } +} + +/*无数据界面*/ +void MessageView::ShowLackView() { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowLackView start"); + lackView = new UIScrollView(); + if (lackView == nullptr) { + return; + } + lackView->SetPosition(0, 0); + lackView->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + lackView->SetScrollBlankSize(20); + lackView->SetReboundSize(50); + lackView->SetDirection(1); + /*初始化label*/ + InitLabelExt(labeltitle, 83, 50, 300, 35, "labletitle", + STR_MESSAGE_NOTIFICATION, DEFAULT_VECTOR_FONT_FILENAME, 30); + InitLabelExt(labelmeage, 53, 276, 360, 40, "labelMessage", STR_MESSAGENO, + DEFAULT_VECTOR_FONT_FILENAME, 30); + labelmeage->SetTextColor(Color::GetColorFromRGBA(0x66, 0x66, 0x66, 0xff)); + /*初始化image*/ + InitImageView(imageline, 193, 30, 365, 35, "image", lineimagePath); + InitImageView(imagemeage, 183, 156, 100, 100, "image", messageimagePath); + + lackView->Add(imageline); + lackView->Add(imagemeage); + lackView->Add(labeltitle); + lackView->Add(labelmeage); + + container_->Add(lackView); + lackView->SetDraggable(true); + lackView->SetTouchable(true); + + lackView->SetOnDragListener(presenter_); + + lackView->SetVisible(false); // 界面隐藏 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowLackView end"); +} + +/*数据界面*/ +void MessageView::ShowMessageView() { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowmessageView start"); + messageView = new UIScrollView(); + if (messageView == nullptr) { + return; + } + messageView->SetPosition(0, 0); + messageView->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + messageView->SetHorizontalScrollState(false); // 设置横向不可以滚动 + messageView->SetDirection(0); + messageView->SetVerticalScrollState(false); // 禁止垂直滑动 + + InitImageView(imageline2, 193, 30, 80, 8, "image", lineimagePath); + messageView->Add(imageline2); + + // UIList 的适配器 + if (p_MessageListAdapter == nullptr) { + p_MessageListAdapter = new MessageListAdapter(); + } + + p_MessageListAdapter->SetItemClickListener(presenter_); + if (MessageList == nullptr) { + MessageList = new UIList(); + } + // MessageList->SetPosition(More_LIST_POSITION_X, More_LIST_POSITION_Y, 466, + // 466); + MessageList->SetPosition(43, 95, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + MessageList->SetScrollStateListener(this); + MessageList->SetThrowDrag(true); + MessageList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + MessageList->SetMaxScrollDistance(1000); + MessageList->SetSwipeACCLevel(800); + MessageList->SetDragACCLevel(5); + MessageList->SetIntercept(true); + + MessageList->SetOnClickListener(presenter_); + messageView->SetOnDragListener(presenter_); + + messageView->SetVisible(false); // 隐藏界面 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowmessageView end"); +} + +/*控制显示界面*/ +void MessageView::SetPopupViewStatus(PopupMessage view, bool status) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetPopupViewStatus %d", view); + + if (view == PopupMessage::LackPopup) { + MessageModel::GetInstance().SetPopupViewState(false); // 设置状态为无消息 + lackView->SetVisible(true); // 隐藏界面 + messageView->SetVisible(false); // 隐藏界面 + } else if (view == PopupMessage::MessagePopup) { + MessageModel::GetInstance().SetPopupViewState(true); // 设置状态为有消息 + lackView->SetVisible(false); // 隐藏界面 + messageView->SetVisible(true); // 隐藏界面 + } +} + +/// @brief 页面启动时需要执行的代码逻辑 +void MessageView::OnStart() { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartResultView::OnStart"); + View::OnStart(); + + // SetContainerView(new UIScrollView()); + container_ = new UIScrollView(); + container_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), + Screen::GetInstance().GetHeight()); + container_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + container_->SetOnDragListener(presenter_); + container_->SetTouchable(true); + container_->SetDraggable(true); + // container_->SetFullScreenBlur(true); // 设置高斯模糊 + ShowMessageView(); + ShowLackView(); + + PreLoad(); + SetContainerView(container_); + + RootView::GetInstance()->SetOnKeyActListener(presenter_); +} +void MessageView::AddMessageToList(const MessageListItem &item) { + p_MessageListAdapter->AddListItem(item); +} +// 获取列表 +UIList *MessageView::GetList() { return MessageList; } +/// @brief 创建页面的视图 +void MessageView::OnSetUpView() { + View::OnSetUpView(); + if (MessageModel::GetInstance().HasDataVector()) { + messageView->Add(MessageList); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageList is add"); + container_->Add(messageView); + if (p_MessageListAdapter) { + MessageList->SetAdapter(p_MessageListAdapter); } -} \ No newline at end of file + } + Draw(); +} + +/// @brief 销毁页面的视图 +void MessageView::OnTearDownView() { + View::OnTearDownView(); + return; +} + +/// @brief 页面结束时需要执行的销毁逻辑。 +void MessageView::OnStop() { + View::OnStop(); + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + RootView::GetInstance()->RemoveAll(); + return; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/takephotos/include/TakephotosView.h b/code/sdk/application/wearable/fd230app/nativeui/takephotos/include/TakephotosView.h index e15d0b176..66e5bd781 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/takephotos/include/TakephotosView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/takephotos/include/TakephotosView.h @@ -72,7 +72,6 @@ namespace OHOS UILabelExt *labeltitle_ = nullptr; UILabel *labelnote_ = nullptr; UILabelButtonExt *buttongo = nullptr; - UIImageView *imagerecord = nullptr; UIImageAnimatorView *creamAnimator{nullptr}; /*拍照界面*/ diff --git a/code/sdk/application/wearable/fd230app/nativeui/takephotos/src/TakephotosView.cpp b/code/sdk/application/wearable/fd230app/nativeui/takephotos/src/TakephotosView.cpp index 8813516dd..0e16e2171 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/takephotos/src/TakephotosView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/takephotos/src/TakephotosView.cpp @@ -17,25 +17,77 @@ #include namespace OHOS { static const uint32_t BACK_GROUND_COLOR = 0xfff6f6f6; +// 遥控拍照 +static constexpr int IMAGE_SIZE = 140; +static constexpr int CREAM_IMAGE_X = 163; +static constexpr int CREAM_IMAGE_Y = 103; +static constexpr int CREAM_IMAGE_NUM = 50; +static constexpr int CREAM_DELAY = 50; +// 遥控拍照 +static ImageAnimatorInfo g_imageAnimatorInfo_takephoto[50] = { +{PNG_TAKE_PHOTO_IMAGE_0, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_1, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_2, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_3, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_4, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_5, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_6, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_7, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_8, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_9, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_10, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_11, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_12, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_13, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_14, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_15, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_16, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_17, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_18, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_19, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_20, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_21, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_22, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_23, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_24, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_25, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_26, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_27, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_28, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_30, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_31, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_32, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_33, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_34, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_35, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_36, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_37, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_38, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_39, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_40, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_41, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_42, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_43, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_44, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_45, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_46, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_47, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_48, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +{PNG_TAKE_PHOTO_IMAGE_49, {CREAM_IMAGE_X, CREAM_IMAGE_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, +}; + + static TakephotosView *g_pTakephotosView{nullptr}; TakephotosView::TakephotosView() { g_pTakephotosView = this; } TakephotosView::~TakephotosView() { - // DeInit(); - if (creamimageInfos != nullptr) - FreeImageInfoArray(creamimageInfos, creambasePath.c_str(), 50); - if (smileimageInfos != nullptr) - FreeImageInfoArray(smileimageInfos, smilebasePath.c_str(), 50); - creamAnimator->Stop(); - smileAnimator->Stop(); - ReleaseImageAnimatorSource(smileimageAnimatorInfo, 50); - ReleaseImageAnimatorSource(creamimageAnimatorInfo, 50); + // UIViewGroup *tmpGroup = dynamic_cast(container_); + // UIViewGroup::RemoveAndDeleteAllRecursively(tmpGroup); - UIViewGroup *tmpGroup = dynamic_cast(container_); - UIViewGroup::RemoveAndDeleteAllRecursively(tmpGroup); + DeInit(); g_pTakephotosView = nullptr; } @@ -56,8 +108,16 @@ void TakephotosView ::InitView() { /* DeInit:删除组件 */ void TakephotosView::DeInit() { - creamView->RemoveAll(); - takeView->RemoveAll(); + + if (container_) { + container_->RemoveAll(); + } + if (creamView) { + creamView->RemoveAll(); + } + if (takeView) { + takeView->RemoveAll(); + } delete labeltitle_; labeltitle_ = nullptr; @@ -65,6 +125,18 @@ void TakephotosView::DeInit() { delete labelnote_; labelnote_ = nullptr; + delete labelnote_; + labelnote_ = nullptr; + + delete buttongo; + buttongo = nullptr; + + if (creamAnimator) { + creamAnimator->Stop(); + delete creamAnimator; + creamAnimator = nullptr; + } + delete labeltake_; labeltake_ = nullptr; @@ -74,16 +146,11 @@ void TakephotosView::DeInit() { delete buttontake; buttontake = nullptr; - delete buttongo; - buttongo = nullptr; - - smileAnimator->Stop(); - delete smileAnimator; - smileAnimator = nullptr; - - creamAnimator->Stop(); - delete creamAnimator; - creamAnimator = nullptr; + if (smileAnimator) { + smileAnimator->Stop(); + delete smileAnimator; + smileAnimator = nullptr; + } delete creamView; creamView = nullptr; @@ -128,8 +195,6 @@ void TakephotosView::ShowCreamView() { labelnote_->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); SetLabelId(labelnote_, STR_TACK); - /*初始化image*/ - // InitImageView(imageTake, 174, 120, 118, 120, "image", RECOED_IMAGE); /*初始化按键*/ InitButtonExt(buttongo, 0, 366, 466, 100, BUTTONGO, STR_KONW, 30); buttongo->SetImageSrc(PNG_466x100BUTTON_IMAGE, PNG_466x100BUTTON_IMAGE); @@ -137,10 +202,14 @@ void TakephotosView::ShowCreamView() { TakephotosPresenter::GetInstance())); // 初始化图片数组以及动画 - creamimageInfos = CreateImageInfoArray(creambasePath.c_str(), 50); - InitImageAnimatorSource(creamAnimator, creamimageAnimatorInfo, - creamimageInfos, 50, 163, 103, 140, 140, - "imageAnimator", 100); + creamAnimator = new UIImageAnimatorView(); + if (creamAnimator == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodBandoffView::new UIImageAnimatorView fail"); + return; + } + creamAnimator->SetImageAnimatorSrc(g_imageAnimatorInfo_takephoto, CREAM_IMAGE_NUM, CREAM_DELAY); + creamAnimator->SetRepeat(true); creamView->Add(creamAnimator); creamView->Add(labeltitle_); @@ -189,11 +258,15 @@ void TakephotosView::ShowTakeView() { buttontake->SetOnClickListener(static_cast( TakephotosPresenter::GetInstance())); - // 初始化图片数组以及动画 {修改为统一动画} - smileimageInfos = CreateImageInfoArray(smilebasePath.c_str(), 50); - InitImageAnimatorSource(smileAnimator, smileimageAnimatorInfo, - smileimageInfos, 50, 163, 140, 140, 140, - "imageAnimator", 100); + // 初始化图片数组以及动画 + smileAnimator = new UIImageAnimatorView(); + if (smileAnimator == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodBandoffView::new UIImageAnimatorView fail"); + return; + } + smileAnimator->SetImageAnimatorSrc(g_imageAnimatorInfo_takephoto, CREAM_IMAGE_NUM, CREAM_DELAY); + smileAnimator->SetRepeat(true); takeView->Add(smileAnimator); takeView->Add(labeltake_); diff --git a/code/sdk/application/wearable/fd230app/nativeui/traing/include/TraingModel.h b/code/sdk/application/wearable/fd230app/nativeui/traing/include/TraingModel.h index dbec9b1cb..47d665dd0 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/traing/include/TraingModel.h +++ b/code/sdk/application/wearable/fd230app/nativeui/traing/include/TraingModel.h @@ -12,329 +12,373 @@ #include "traing/Training_UiConfig.h" #include "ui_resource_string.h" -#include "cywee_service.h" #include "cywee_hal.h" +#include "cywee_service.h" -#include -#include #include -#include -#include #include +#include +#include +#include #include +#include #define TRAINING_PATH "user/userdata/sport/TrainingData/" #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif - struct Trainingdata_hard - { - uint32_t num; - }; - /* - "src":0, - "ty":0, - "st":1657865201, - "sp":1657867001, - "tgt":0, - "tg":5000, - "pg":60, - "du":1800, - "ca":2355,//卡路里为该数值乘以0.1 - "di":3000, - "hr":127, - "stp":10000 - */ - struct Trainingdata - { - // 0:手表开启的训练1:APP开启的训练 - uint32_t src; - // 0:健身类1:舞蹈类2:休闲运动3:球类4:水上项目5:冰上项目6:极限运动 7:其他 - uint32_t bt; - // 训练类型0:健走1:跑步2:骑行 - uint32_t ty; - // 开始时间戳 - uint32_t st; - // 结束时间戳 - uint32_t sp; - // 训练目标类型 - uint32_t tgt; - // 训练目标 - uint32_t tg; - // 目标完成度 - uint32_t pg; - // 训练时长 - uint32_t du; - // 卡路里 - uint32_t ca; - // 距离 - uint32_t di; - // 平均心率 - uint32_t hr; - // 步数 - uint32_t stp; - // 训练强度 - uint32_t ti; - // 圈数 - uint32_t cir; - // 最高海拔高度 - uint32_t alt; - // 平均配速 - uint32_t apc; - // 最快配速 - uint32_t fpc; - // 最慢配速 - uint32_t spc; - // 步幅 - uint32_t std; - // 步频 - uint32_t cdc; - }; - Trainingdata *read_Trainingdata_data(char *timedata, uint16_t offset); - - int write_Trainingdata_data(Trainingdata data); +struct Trainingdata_hard { + uint32_t num; +}; +/* +"src":0, +"ty":0, +"st":1657865201, +"sp":1657867001, +"tgt":0, +"tg":5000, +"pg":60, +"du":1800, +"ca":2355,//卡路里为该数值乘以0.1 +"di":3000, +"hr":127, +"stp":10000 +*/ +struct Trainingdata { + // 0:手表开启的训练1:APP开启的训练 + uint32_t src; + // 0:健身类1:舞蹈类2:休闲运动3:球类4:水上项目5:冰上项目6:极限运动 + // 7:其他 + uint32_t bt; + // 训练类型0:健走1:跑步2:骑行 + uint32_t ty; + // 开始时间戳 + uint32_t st; + // 结束时间戳 + uint32_t sp; + // 训练目标类型 + uint32_t tgt; + // 训练目标 + uint32_t tg; + // 目标完成度 + uint32_t pg; + // 训练时长 + uint32_t du; + // 卡路里 + uint32_t ca; + // 距离 + uint32_t di; + // 平均心率 + uint32_t hr; + // 步数 + uint32_t stp; + // 训练强度 + uint32_t ti; + // 圈数 + uint32_t cir; + // 最高海拔高度 + uint32_t alt; + // 平均配速 + uint32_t apc; + // 最快配速 + uint32_t fpc; + // 最慢配速 + uint32_t spc; + // 步幅 + uint32_t std; + // 步频 + uint32_t cdc; +}; +Trainingdata *read_Trainingdata_data(char *timedata, uint16_t offset); + +int write_Trainingdata_data(Trainingdata data); #ifdef __cplusplus } #endif -namespace OHOS -{ +namespace OHOS { #define TIME_INTERVAL 10; #define CALORIES_INTERVAL 100; #define DISTANCE_INTERVAL 1; #define STEPS_INTERVAL 500; - // 运动状态 - enum class ExerciseState - { - End = 0, - Start, - Pause, - Continue, - General, - }; - // 运动项目 - enum class ExerciseClass - { - NORMAL = 0, - TREADMILL, - OUTDOOR, - INDOOR, - FITNESS_PEDOMETER, - FREE_TRAINING, - }; - // 运动类型 - enum class Exercisetype - { - // 0:健身类 1:舞蹈类 2:休闲运动 3:球类 4:水上项目 5:冰上项目 6:极限运动 7:其他 - FITNESS = 0, - DANCE, - LEISURE, - BALL, - WATER, - ICE, - EXTREME, - OTHER - }; - // 训练目标类型 - enum class ExerciseTag - { - Distance, - Calories, - Duration, - Steps, - UNKNOW, - }; - - enum Exercise - { - LOW_INTENSITY = 0, - MEDIUM_INTENSITY, - HIGH_INTENSITY, - VERY_HIGH_INTENSITY - }; - - enum ENTEYTYPE - { - MAIN_ENTER = 0, - APPLIST_ENTER, - }; - struct SportData - { - uint32 starttime; // 开始时间时间戳 - uint32 endtime; // 结束时间时间戳 - int duration; // 训练时长 - int goaldegree; // 目标完成度 - int calories; // 训练卡路里 - int steps; // 训练步数 - int distance; // 训练距离 - int intensity; // 训练强度 (0:较低强度 1:中等强度 2:高等强度 3:超高强度) - int heart; // 运动心率 - int avgheart; // 训练平均心率 - int tag; // 训练目标 - int pc; // 训练配速 - std::string start_date; // 训练开始日期 - std::string start_time; // 训练开始时间 - std::string end_time; // 训练结束时间 - Exercisetype sportType; // 训练类型(0:健身类 1:跳舞类 2:休闲运动 3:球类 4:水上运动:5:冰上运动:6:极限运动:7:其他) - UIResourceTextId sportId; // 训练Id - ExerciseTag sportTagType; // 训练目标类型(0: 距离 1:时长 2:卡路里 3:步数) - int apc; // 平均配速 - int fpc; // 最快配速 - int spc; // 最慢配速 - int cdc; // 步频 - int std; // 步幅 - - void Initialize() - { - starttime = 0; - endtime = 0; - duration = 0; - goaldegree = 0; - calories = 0; - steps = 0; - distance = 0; - intensity = 0; - heart = 0; - avgheart = 0; - tag = 0; - start_date = ""; - start_time = ""; - end_time = ""; - sportType = Exercisetype::FITNESS; - sportId = UIResourceTextId::STR_EXTREME_SPORTS; - sportTagType = ExerciseTag::UNKNOW; - apc = 0; - fpc = 0; - spc = 0; - cdc = 0; - std = 0; - } - - void Reset() - { - Initialize(); // 调用初始化函数将数据重置为初始状态 - } - }; - - class TraingModel - { - public: - TraingModel(); - ~TraingModel(); - static TraingModel *GetInstance(void); - void Init(); - - /*定时器 */ - std::string DisplayMotionDuration(); - - // 训练存储相关配置 - bool CheckDataJson(); /*判断json文件是否存在*/ - bool SaveDataToJson(SportData *data); /*保存训练记录到json文件*/ - bool LoadDataFormJson(std::vector& sportDataVector); /*加载json文件*/ - void RecordSportData(); /*保存数据*/ - - // 训练数据相关配置 - void AnalysisData(cywee_activity_result_t *cyweeInfo); /*解析传输过来的数据*/ - void AnalysisExtraData(cywee_activity_result_extre_info_t *cyweeInfo); /*解析运动额外数据*/ - void AnalysisHeartData(uint8_t hrs); /*解析运动心率数据*/ - SportData *GetSportdata(); /*获取训练数据*/ - void SetIntensity(int heart); /*设置训练强度*/ - UIResourceTextId GetIntensity(); /*获取训练强度STR*/ - uint32_t GetSportTime(); /*获取目前运动时长*/ - bool SaveSportData(); /*保存数据*/ - void SendLiveData(); /*发送实时数据*/ - int CalculateAverageHeartRate(int newHeartRate); /*平均心率计算*/ - int CalculateFilteredHeartRate(int newHeartRate); /*显示心率计算*/ - int Averageheartrate(int newHeartRate); /*平均心率窗口数*/ - void SetSportdata(SportData *data); /*设置训练数据[为训练记录准备]*/ - int GetCal(); /*获取运动卡路里*/ - int GetDuration(); //获取运动时长 - - // 训练状态相关配置 - void SetEntryType(ENTEYTYPE type); /*设置进入训练方式*/ - ENTEYTYPE GetEntryType(); /*获取训练进入方式*/ - void SetSportOpenWay(bool way); /*设置运动开始方式*/ - void SetSportOpenState(bool state); /*设置运动是否开始*/ - bool GetSportOpenState(); /*获取运动是否开始*/ - bool GetMomentum(); /*获取训练量是否达标*/ - void SetSportState(ExerciseState state); /*设置运动状态*/ - ExerciseState GetSportState(); /*获取运动状态*/ - void ResetSharedTrainingData(); /*重新初始化训练配置*/ - void set_sport_config(UIResourceTextId id); // 运动识别进入运动 - - // 训练时间相关配置 - std::string AnalysisTimestamp(uint64_t timestamp); /*解析时间戳*/ - std::string GetTrainingTime(); /*获取运动总时长*/ - std::string GetStartTiemStr(); /*获取开始时间Str*/ - std::string GetEndTiemStr(); /*获取结束时间Str*/ - void SetTimestamp(); /*设置训练开始与结束*/ - void SetStartDateTime(); /*设置开始时间*/ - void SetEndTime(); /*设置结束时间*/ - bool GetFormattedDate(std::string &dateOutput, const char *errorMsg); /*获取日期*/ - bool GetFormattedTime(std::string &timeOutput, const char *errorMsg); /*获取时间*/ - - // 训练项相关配置 - void IsSpecialSport(UIResourceTextId sportId_); /*判断是否为特殊训练*/ - bool GetIsSpecial(); /*获取是否为特殊训练*/ - void SetSportEvent(UIResourceTextId id); /*设置运动项目*/ - UIResourceTextId GetSportEvent(); /*获取运动项目*/ - ExerciseClass GetSportId(); /*获取运动项目Id*/ - int GetBleSportId(Exercisetype sporttype, UIResourceTextId id); /*获取协议Id*/ - UIResourceTextId GetSportTypeId(Exercisetype type); /*获取训练类Id*/ - void SetSportType(Exercisetype type); /*设置运动类型*/ - std::string GetSportType(Exercisetype sporttype); /*获取训练类型type图片*/ - std::string GetSportIcon(Exercisetype sporttype); /*获取训练类型icon图片*/ - - // 训练目标相关配置 - void SetSportTag(ExerciseTag tagtpye, int tag); /*设置训练目标类型以及训练目标*/ - int GetSportTag(); /*获取训练目标*/ - ExerciseTag GetSportTagtype(); /*获取项目目标类型*/ - int GetSportTagData(); /*获取对应的训练目标的值*/ - int GetGoaldegree(); /*获取训练目标完成百分比*/ - std::string GetTagStr(); /*获取训练目标Str*/ - - // 打印配置 - void printTrainingData(const Trainingdata &data); /*打印数据*/ - void printf_data(SportData *data); /*打印函数*/ - - private: - TraingModel(const TraingModel &) = delete; - TraingModel &operator=(const TraingModel &) = delete; - - std::string motionDuration; // 显示训练时长 - UIResourceTextId sportId_ = STR_EXERCISE_OUTDOORWALKING; // 训练项目 - Exercisetype sportType_ = Exercisetype::FITNESS; // 训练类型 - ExerciseState sportState_ = ExerciseState::General; // 训练状态 - ExerciseTag sportTagType_ = ExerciseTag::UNKNOW; // 训练目标类型 - - ENTEYTYPE entey_type = ENTEYTYPE::MAIN_ENTER; // 进入方式 - - bool isspecialsport_{false}; - int sportTag_ = 0; // 训练目标 - int freq = 0; // 训练发送数据频率 - - bool Gettagstuats{false}; // 训练达标标志位 - bool Startstate{false}; // 开始训练标志位 - bool Endstate{false}; // 结束训练标志位 - bool Openingway{false}; // 运动开启方式 [0 手表 1 app] - bool MomentumFlag{false}; // 训练量达标标志位 - bool Openstate{false}; // 运动是否开始 - - std::vector heartRateData; // 存储所有心率数据 - std::vector recentHeartRates; // 显示心率 - std::unordered_map delayed; // 延迟删除的心率值 - std::priority_queue maxHeap; // 最大堆,存储最大心率值 - std::priority_queue, std::greater> minHeap; // 最小堆,存储最小心率值 - int totalHeartRate; // 总心率 - int countHeartRate; // 心率计数 - const int windowSize = 5; // 移动平均窗口大小 - - /*std::unique_ptr sportdata;*/ // 使用 std::unique_ptr 管理 SportData 对象 - }; -} +#define MAX_FILE_PATH_LENGTH 128 +#define TRAINING_DATA_DIRECTORY "user/userdata/sport/" +#define TRAINING_RECORD_FILE "user/userdata/sport/Record.json" +#define TRAINING_HEART_FILE "user/userdata/sport/HeartTabel/" +#define TRAINING_PACE_FILE "user/userdata/sport/PaceTabel/" +#define MAX_DATA_COUNT 10 + +#define TIMER 1 +#define BLETEST 0 +#define HARD_OFF 1 +#define READTEST 0 + +#define MAX_HEART_RATE 220 +#define AGE_THRESHOLD 59 +#define LOW_INTENSITY_THRESHOLD 59 +#define MEDIUM_INTENSITY_LOWER_THRESHOLD 60 +#define MEDIUM_INTENSITY_UPPER_THRESHOLD 69 +#define HIGH_INTENSITY_LOWER_THRESHOLD 70 +#define HIGH_INTENSITY_UPPER_THRESHOLD 79 + +#define MAXSPORTID 176 + +// 运动状态 +enum class ExerciseState { + End = 0, + Start, + Pause, + Continue, + General, +}; +// 运动项目 +enum class ExerciseClass { + NORMAL = 0, + TREADMILL, + OUTDOOR, + INDOOR, + FITNESS_PEDOMETER, + FREE_TRAINING, +}; +// 运动类型 +enum class Exercisetype { + // 0:健身类 1:舞蹈类 2:休闲运动 3:球类 4:水上项目 5:冰上项目 6:极限运动 + // 7:其他 + FITNESS = 0, + DANCE, + LEISURE, + BALL, + WATER, + ICE, + EXTREME, + OTHER +}; +// 训练目标类型 +enum class ExerciseTag { + Distance, + Calories, + Duration, + Steps, + UNKNOW, +}; + +enum Exercise { + LOW_INTENSITY = 0, + MEDIUM_INTENSITY, + HIGH_INTENSITY, + VERY_HIGH_INTENSITY +}; + +enum ENTEYTYPE { + MAIN_ENTER = 0, + APPLIST_ENTER, +}; +//心率表结构体 +struct HeartRateEntry { + uint32_t timestamp; + uint16_t heartRate; +}; +//配速结果体 +struct PaceEntry { + uint32_t timestamp; + uint16_t pace; +}; +struct SportData { + uint32 starttime; // 开始时间时间戳 + uint32 endtime; // 结束时间时间戳 + int duration; // 训练时长 + int goaldegree; // 目标完成度 + int calories; // 训练卡路里 + int steps; // 训练步数 + int distance; // 训练距离 + int intensity; // 训练强度 (0:较低强度 1:中等强度 2:高等强度 3:超高强度) + int heart; // 运动心率 + int avgheart; // 训练平均心率 + int tag; // 训练目标 + int pc; // 训练配速 + std::string start_date; // 训练开始日期 + std::string start_time; // 训练开始时间 + std::string end_time; // 训练结束时间 + Exercisetype sportType; // 训练类型(0:健身类 1:跳舞类 2:休闲运动 3:球类 + // 4:水上运动:5:冰上运动:6:极限运动:7:其他) + UIResourceTextId sportId; // 训练Id + ExerciseTag sportTagType; // 训练目标类型(0: 距离 1:时长 2:卡路里 3:步数) + int apc; // 平均配速 + int fpc; // 最快配速 + int spc; // 最慢配速 + int cdc; // 步频 + int std; // 步幅 + + void Initialize() { + starttime = 0; + endtime = 0; + duration = 0; + goaldegree = 0; + calories = 0; + steps = 0; + distance = 0; + intensity = 0; + heart = 0; + avgheart = 0; + tag = 0; + start_date = ""; + start_time = ""; + end_time = ""; + sportType = Exercisetype::FITNESS; + sportId = UIResourceTextId::STR_EXTREME_SPORTS; + sportTagType = ExerciseTag::UNKNOW; + apc = 0; + fpc = 0; + spc = 0; + cdc = 0; + std = 0; + } + + void Reset() { + Initialize(); // 调用初始化函数将数据重置为初始状态 + } +}; + +class TraingModel { +public: + TraingModel(); + ~TraingModel(); + static TraingModel *GetInstance(void); + void Init(); + + /*定时器 */ + std::string DisplayMotionDuration(); + + // 训练存储相关配置 + bool CheckDataJson(); /*判断json文件是否存在*/ + bool SaveDataToJson(SportData *data); /*保存训练记录到json文件*/ + bool + LoadDataFormJson(std::vector &sportDataVector); /*加载json文件*/ + void RecordSportData(); /*保存数据*/ + + // 训练数据相关配置 + void AnalysisData(cywee_activity_result_t *cyweeInfo); /*解析传输过来的数据*/ + void AnalysisExtraData( + cywee_activity_result_extre_info_t *cyweeInfo); /*解析运动额外数据*/ + void AnalysisHeartData(uint8_t hrs); /*解析运动心率数据*/ + SportData *GetSportdata(); /*获取训练数据*/ + void SetIntensity(int heart); /*设置训练强度*/ + UIResourceTextId GetIntensity(); /*获取训练强度STR*/ + uint32_t GetSportTime(); /*获取目前运动时长*/ + bool SaveSportData(); /*保存数据*/ + void SendLiveData(); /*发送实时数据*/ + int CalculateAverageHeartRate(int newHeartRate); /*平均心率计算*/ + int CalculateFilteredHeartRate(int newHeartRate); /*显示心率计算*/ + int Averageheartrate(int newHeartRate); /*平均心率窗口数*/ + void SetSportdata(SportData *data); /*设置训练数据[为训练记录准备]*/ + int GetCal(); /*获取运动卡路里*/ + int GetDuration(); //获取运动时长 + + // 训练状态相关配置 + void SetEntryType(ENTEYTYPE type); /*设置进入训练方式*/ + ENTEYTYPE GetEntryType(); /*获取训练进入方式*/ + void SetSportOpenWay(bool way); /*设置运动开始方式*/ + void SetSportOpenState(bool state); /*设置运动是否开始*/ + bool GetSportOpenState(); /*获取运动是否开始*/ + bool GetMomentum(); /*获取训练量是否达标*/ + void SetSportState(ExerciseState state); /*设置运动状态*/ + ExerciseState GetSportState(); /*获取运动状态*/ + void ResetSharedTrainingData(); /*重新初始化训练配置*/ + void set_sport_config(UIResourceTextId id); // 运动识别进入运动 + + // 训练时间相关配置 + std::string AnalysisTimestamp(uint64_t timestamp); /*解析时间戳*/ + std::string GetTrainingTime(); /*获取运动总时长*/ + std::string GetStartTiemStr(); /*获取开始时间Str*/ + std::string GetEndTiemStr(); /*获取结束时间Str*/ + void SetTimestamp(); /*设置训练开始与结束*/ + void SetStartDateTime(); /*设置开始时间*/ + void SetEndTime(); /*设置结束时间*/ + bool GetFormattedDate(std::string &dateOutput, + const char *errorMsg); /*获取日期*/ + bool GetFormattedTime(std::string &timeOutput, + const char *errorMsg); /*获取时间*/ + + // 训练项相关配置 + void IsSpecialSport(UIResourceTextId sportId_); /*判断是否为特殊训练*/ + bool GetIsSpecial(); /*获取是否为特殊训练*/ + void SetSportEvent(UIResourceTextId id); /*设置运动项目*/ + UIResourceTextId GetSportEvent(); /*获取运动项目*/ + ExerciseClass GetSportId(); /*获取运动项目Id*/ + int GetBleSportId(Exercisetype sporttype, UIResourceTextId id); /*获取协议Id*/ + UIResourceTextId GetSportTypeId(Exercisetype type); /*获取训练类Id*/ + void SetSportType(Exercisetype type); /*设置运动类型*/ + std::string GetSportType(Exercisetype sporttype); /*获取训练类型type图片*/ + std::string GetSportIcon(Exercisetype sporttype); /*获取训练类型icon图片*/ + + // 训练目标相关配置 + void SetSportTag(ExerciseTag tagtpye, + int tag); /*设置训练目标类型以及训练目标*/ + int GetSportTag(); /*获取训练目标*/ + ExerciseTag GetSportTagtype(); /*获取项目目标类型*/ + int GetSportTagData(); /*获取对应的训练目标的值*/ + int GetGoaldegree(); /*获取训练目标完成百分比*/ + std::string GetTagStr(); /*获取训练目标Str*/ + + /*配速表以及心率表配置*/ + bool AddHeartRateData(uint32_t timestamp, uint16_t heartRate); + bool AddPaceData(uint32_t timestamp, uint16_t pace); + bool SaveHeartTable(); + bool SavePaceTable(); + void ClearHeartTable(); + void ClearPaceTable(); + std::string GetHeartTablePath(uint32_t timestamp); + std::string GetPaceTablePath(uint32_t timestamp); + void StoreDataIfMinutePassed(); + void SendLiveDataIfNecessary(); + + // 打印配置 + void printTrainingData(const Trainingdata &data); /*打印数据*/ + void printf_data(SportData *data); /*打印函数*/ + +private: + TraingModel(const TraingModel &) = delete; + TraingModel &operator=(const TraingModel &) = delete; + + std::string motionDuration; // 显示训练时长 + UIResourceTextId sportId_ = STR_EXERCISE_OUTDOORWALKING; // 训练项目 + Exercisetype sportType_ = Exercisetype::FITNESS; // 训练类型 + ExerciseState sportState_ = ExerciseState::General; // 训练状态 + ExerciseTag sportTagType_ = ExerciseTag::UNKNOW; // 训练目标类型 + + ENTEYTYPE entey_type = ENTEYTYPE::MAIN_ENTER; // 进入方式 + + bool isspecialsport_{false}; + int sportTag_ = 0; // 训练目标 + int freq = 0; // 训练发送数据频率 + + bool Gettagstuats{false}; // 训练达标标志位 + bool Startstate{false}; // 开始训练标志位 + bool Endstate{false}; // 结束训练标志位 + bool Openingway{false}; // 运动开启方式 [0 手表 1 app] + bool MomentumFlag{false}; // 训练量达标标志位 + bool Openstate{false}; // 运动是否开始 + + std::vector heartRateData; // 存储所有心率数据 + std::vector recentHeartRates; // 显示心率 + std::unordered_map delayed; // 延迟删除的心率值 + std::priority_queue maxHeap; // 最大堆,存储最大心率值 + std::priority_queue, std::greater> + minHeap; // 最小堆,存储最小心率值 + int totalHeartRate; // 总心率 + int countHeartRate; // 心率计数 + const int windowSize = 5; // 移动平均窗口大小 + uint32_t heartcount{0}; + + std::vector heartRateTable; // 心率表 + std::vector paceTable; //配速表 + const size_t MAX_ENTRIES = 10000; // 规定最大进场条目数 + /*std::unique_ptr sportdata;*/ // 使用 std::unique_ptr 管理 + // SportData 对象 +}; +} // namespace OHOS #endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp index af44d5bdc..a9fe901ca 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp @@ -2,539 +2,466 @@ * @Date: 2024-04-15 11:46:23 * @LastEditors: Caisking 3449750381@qq.com * @LastEditTime: 2024-04-15 15:09:35 - * @FilePath: /sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp + * @FilePath: + * /sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp */ #include "traing/include/TraingModel.h" +#include "cmsis_os.h" +#include "custom_utils.h" +#include "thread_adapter.h" +#include "traing/training_card/include/TraingCardPresenter.h" #include "uicomponents/UIComponents.h" #include "wearable_log.h" -#include -#include -#include "custom_utils.h" #include +#include +#include +#include #include -#include "thread_adapter.h" #include -#include -#include -#include "cmsis_os.h" -#include "traing/training_card/include/TraingCardPresenter.h" +#include +#include "ConfigModel.h" +#include "bleEvent.h" +#include "bletest.h" #include "broadcast_feature.h" #include "broadcast_service.h" -#include "bletest.h" -#include "ConfigModel.h" +#include "custom_runtime.h" +#include "power_display_service.h" #include "samgr_lite.h" +#include "traingrecord/include/TraingRecordModel.h" #include "vibrator_service.h" -#include +#include +#include +#include +#include +#include #include -#include "bleEvent.h" -#include "power_display_service.h" +#include +#include +#include #include #include #include #include #include -#include -#include -#include -#include -#include -#include "samgr_lite.h" #include -#include -#include -#include "custom_runtime.h" -#include "traingrecord/include/TraingRecordModel.h" - -#define MAX_FILE_PATH_LENGTH 128 -#define TRAINING_DATA_DIRECTORY "user/userdata/sport/" -#define TRAINING_RECORD_FILE "user/userdata/sport/Record.json" -#define MAX_DATA_COUNT 10 - -#define TIMER 1 -#define BLETEST 0 -#define HARD_OFF 1 -#define READTEST 0 - -#define MAX_HEART_RATE 220 -#define AGE_THRESHOLD 59 -#define LOW_INTENSITY_THRESHOLD 59 -#define MEDIUM_INTENSITY_LOWER_THRESHOLD 60 -#define MEDIUM_INTENSITY_UPPER_THRESHOLD 69 -#define HIGH_INTENSITY_LOWER_THRESHOLD 70 -#define HIGH_INTENSITY_UPPER_THRESHOLD 79 - -#define MAXSPORTID 176 extern "C" errcode_t uapi_get_timestampe_ms(uint32_t *tm); #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif - static void Notify(void *args, const Topic topic, Request *request); - - using namespace OHOS; - - Subscriber TraingSubscirber = { - .identity = NULL, - .args = NULL, - .Notify = Notify, - }; - - void TraingSubscribeTopic(Topic topic) - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "stepsubscribeTopic, topic=%u", topic); - BroadcastApi *broadcastApi = NULL; - IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME); - if (api == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "stepsubscribeTopic, GetFeatureApi failed"); - return; - } - int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); - if (result != 0 || broadcastApi == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "stepsubscribeTopic, QueryInterface failed"); - return; - } - broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic, &TraingSubscirber); - broadcastApi->Release((IUnknown *)broadcastApi); - } +static void Notify(void *args, const Topic topic, Request *request); + +using namespace OHOS; + +Subscriber TraingSubscirber = { + .identity = NULL, + .args = NULL, + .Notify = Notify, +}; + +void TraingSubscribeTopic(Topic topic) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "stepsubscribeTopic, topic=%u", topic); + BroadcastApi *broadcastApi = NULL; + IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, + BROADCAST_FEATURE_NAME); + if (api == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "stepsubscribeTopic, GetFeatureApi failed"); + return; + } + int result = + api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); + if (result != 0 || broadcastApi == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "stepsubscribeTopic, QueryInterface failed"); + return; + } + broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic, + &TraingSubscirber); + broadcastApi->Release((IUnknown *)broadcastApi); +} - void TraingUnsubscribeTopic(Topic topic) - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingUnsubscribeTopic, topic=%u", topic); - BroadcastApi *broadcastApi = NULL; - IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME); - if (api == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingUnsubscribeTopic, GetFeatureApi failed"); - return; - } - int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); - if (result != 0 || broadcastApi == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingUnsubscribeTopic, QueryInterface failed"); - return; - } - broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic, &TraingSubscirber); - broadcastApi->Release((IUnknown *)broadcastApi); - } - int flag = 0; - static void Notify(void *args, const Topic topic, Request *request) - { - UNUSED(args); - UNUSED(topic); - if (request == NULL) - { - return; - } - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "request %d\r\n", request->msgId); - if (request->msgId == TOPIC_EVENT_ACTIVITY_UPDATE) - { +void TraingUnsubscribeTopic(Topic topic) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingUnsubscribeTopic, topic=%u", + topic); + BroadcastApi *broadcastApi = NULL; + IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, + BROADCAST_FEATURE_NAME); + if (api == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "TraingUnsubscribeTopic, GetFeatureApi failed"); + return; + } + int result = + api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); + if (result != 0 || broadcastApi == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "TraingUnsubscribeTopic, QueryInterface failed"); + return; + } + broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic, + &TraingSubscirber); + broadcastApi->Release((IUnknown *)broadcastApi); +} +int flag = 0; +static void Notify(void *args, const Topic topic, Request *request) { + UNUSED(args); + UNUSED(topic); + if (request == NULL) { + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "request %d\r\n", request->msgId); + if (request->msgId == TOPIC_EVENT_ACTIVITY_UPDATE) { #if BLETEST - if (!flag) - { - training_ble *traingbleInfo = new training_ble(); - traingbleInfo->sportType = 1; - traingbleInfo->controlmd = 0; - TraingCardPresenter::GetInstance()->send_sport_cmd(traingbleInfo); - delete traingbleInfo; - flag = 1; - } -#endif - cywee_activity_result_t *cyweeInfo = new cywee_activity_result_t(); - int rets = memcpy_s(cyweeInfo, sizeof(cywee_activity_result_t), (cywee_activity_result_t *)request->data, request->len); - if (rets != EOK) - { - delete cyweeInfo; // 处理内存分配失败的情况 - cyweeInfo = NULL; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "memcpy_s cywee_activity_result_t fail ret = %d", rets); - return; - } - TraingModel::GetInstance()->AnalysisData(cyweeInfo); - delete cyweeInfo; // 释放内存 - } - if (request->msgId == TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE) - { - cywee_activity_result_extre_info_t *cyweeInfo_ext = new cywee_activity_result_extre_info_t(); - int rets = memcpy_s(cyweeInfo_ext, sizeof(cywee_activity_result_extre_info_t), (cywee_activity_result_extre_info_t *)request->data, request->len); - if (rets != EOK) - { - delete cyweeInfo_ext; // 处理内存分配失败的情况 - cyweeInfo_ext = NULL; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "memcpy_s cywee_activity_result_extre_info_t fail ret = %d", rets); - return; - } - TraingModel::GetInstance()->AnalysisExtraData(cyweeInfo_ext); - delete cyweeInfo_ext; // 释放内存 - } - if(request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA) - { - uint8_t heart = *((u_int8_t*)(request->data)); // 进行类型转换 - TraingModel::GetInstance()->AnalysisHeartData(heart); - } - if (request->msgId == TOPIC_EVENT_BLE_TRAINING) - { - training_ble *traingbleInfo = new training_ble(); - int rets = memcpy_s(traingbleInfo, sizeof(training_ble), (training_ble *)request->data, request->len); - if (rets != EOK) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "memcpy_s cywee_activity_result_t fail ret = %d", rets); - return; - } - TraingCardPresenter::GetInstance()->send_sport_cmd(traingbleInfo); - delete traingbleInfo; - } + if (!flag) { + training_ble *traingbleInfo = new training_ble(); + traingbleInfo->sportType = 1; + traingbleInfo->controlmd = 0; + TraingCardPresenter::GetInstance()->send_sport_cmd(traingbleInfo); + delete traingbleInfo; + flag = 1; } +#endif + cywee_activity_result_t *cyweeInfo = new cywee_activity_result_t(); + int rets = memcpy_s(cyweeInfo, sizeof(cywee_activity_result_t), + (cywee_activity_result_t *)request->data, request->len); + if (rets != EOK) { + delete cyweeInfo; // 处理内存分配失败的情况 + cyweeInfo = NULL; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "memcpy_s cywee_activity_result_t fail ret = %d", rets); + return; + } + TraingModel::GetInstance()->AnalysisData(cyweeInfo); + delete cyweeInfo; // 释放内存 + } + if (request->msgId == TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE) { + cywee_activity_result_extre_info_t *cyweeInfo_ext = + new cywee_activity_result_extre_info_t(); + int rets = memcpy_s( + cyweeInfo_ext, sizeof(cywee_activity_result_extre_info_t), + (cywee_activity_result_extre_info_t *)request->data, request->len); + if (rets != EOK) { + delete cyweeInfo_ext; // 处理内存分配失败的情况 + cyweeInfo_ext = NULL; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "memcpy_s cywee_activity_result_extre_info_t fail ret = %d", + rets); + return; + } + TraingModel::GetInstance()->AnalysisExtraData(cyweeInfo_ext); + delete cyweeInfo_ext; // 释放内存 + } + if (request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA) { + uint8_t heart = *((u_int8_t *)(request->data)); // 进行类型转换 + TraingModel::GetInstance()->AnalysisHeartData(heart); + } + if (request->msgId == TOPIC_EVENT_BLE_TRAINING) { + training_ble *traingbleInfo = new training_ble(); + int rets = memcpy_s(traingbleInfo, sizeof(training_ble), + (training_ble *)request->data, request->len); + if (rets != EOK) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "memcpy_s cywee_activity_result_t fail ret = %d", rets); + return; + } + TraingCardPresenter::GetInstance()->send_sport_cmd(traingbleInfo); + delete traingbleInfo; + } +} #ifdef __cplusplus } #endif -namespace OHOS -{ +namespace OHOS { #if TIMER - // 声明定时器变量 - static osTimerId_t g_startCounting = NULL; // 定时器 - static constexpr uint64_t MS_ONE_SECONDS = 1000; - static int g_motionTimes{0}; - static constexpr int32 NUM_TEN = 10; - static constexpr int16 ERROR = 0; - static constexpr int16 SUCCESS = 1; - static constexpr int16 NUM_TIME_MIN = 60; - static constexpr int16 NUM_TIME_HOUR = 3600; - static constexpr int32 NUM_TIME_DAY = 86400; +// 声明定时器变量 +static osTimerId_t g_startCounting = NULL; // 定时器 +static constexpr uint64_t MS_ONE_SECONDS = 1000; +static int g_motionTimes{0}; +static constexpr int32 NUM_TEN = 10; +static constexpr int16 ERROR = 0; +static constexpr int16 SUCCESS = 1; +static constexpr int16 NUM_TIME_MIN = 60; +static constexpr int16 NUM_TIME_HOUR = 3600; +static constexpr int32 NUM_TIME_DAY = 86400; #endif - SportData *sportdata = new SportData(); - TraingModel ::TraingModel() - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::TraingModel()"); - // sportdata->Initialize(); // 初始化结构体 - } - TraingModel ::~TraingModel() - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::~TraingModel()"); - TraingUnsubscribeTopic(TOPIC_EVENT_ACTIVITY_UPDATE); // 取消订阅 - TraingUnsubscribeTopic(TOPIC_EVENT_BLE_TRAINING); - TraingUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA); - TraingUnsubscribeTopic(TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE); - } - TraingModel *TraingModel::GetInstance(void) - { - static TraingModel instance; - return &instance; - } - - void TraingModel ::Init() - { - TraingSubscribeTopic(TOPIC_EVENT_ACTIVITY_UPDATE); // 进行消息订阅 - TraingSubscribeTopic(TOPIC_EVENT_BLE_TRAINING); - TraingSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA); - TraingSubscribeTopic(TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE); - } - /*设置运动类型*/ - void TraingModel::SetSportType(Exercisetype type) - { - sportType_ = type; - } - /*结束数据icon*/ - std::string sportImages[8] = { - FITNESS_54_IMAGE, - DANCE_54_IMAGE, - REST_54_IMAGE, - BALL_54_IMAGE, - SWIMMING_54_IMAGE, - ICE_54_IMAGE, - LIMIT_54_IMAGE, - OTHER_54_IMAGE, - }; - /*训练记录Icon*/ - std::string sportIcons[8] = { - FITNESS_IMAGE, - DANCE_IMAGE, - REST_IMAGE, - BALL_IMAGE, - SWIMMING_IMAGE, - ICE_IMAGE, - LIMIT_IMAGE, - OTHER_IMAGE, - }; - /*获取训练Id->协议*/ - int TraingModel::GetBleSportId(Exercisetype sporttype, UIResourceTextId id) - { - int offset = 0; - - switch (sporttype) - { - case Exercisetype::FITNESS: // 0~57 - offset = 0; - break; - case Exercisetype::DANCE: // 0~9 - offset = 58; - break; - case Exercisetype::LEISURE: // 0~23 - offset = 58 + 10; - break; - case Exercisetype::BALL: // 0~28 - offset = 58 + 10 + 24; - break; - case Exercisetype::WATER: // 0~23 - offset = 58 + 10 + 24 + 29; - break; - case Exercisetype::ICE: // 0~11 - offset = 58 + 10 + 24 + 29 + 24; - break; - case Exercisetype::EXTREME: // 0~9 - offset = 58 + 10 + 24 + 29 + 24 + 12; - break; - case Exercisetype::OTHER: // 0~8 - offset = 58 + 10 + 24 + 29 + 24 + 12 + 10; - break; - default: - offset = 0; - break; - } - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " offset %d id %d", offset, id); - return id - offset; - } - /*获取运动类型图片*/ - std::string TraingModel::GetSportType(Exercisetype sporttype) - { - int index = static_cast(sporttype); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportType index %d", index); - return sportImages[index]; - } - /*获取运动类型icon*/ - std::string TraingModel::GetSportIcon(Exercisetype sporttype) - { - int index = static_cast(sporttype); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportIcon index %d", index); - return sportIcons[static_cast(sporttype)]; - } - /*设置运动Id*/ - void TraingModel::SetSportEvent(UIResourceTextId id) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SetSportType %d", sportId_); - IsSpecialSport(id); // 设置特殊性 - sportId_ = id; - } - /*获取运动Id*/ - UIResourceTextId TraingModel::GetSportEvent() - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportEvent %d", sportId_); - return sportId_; - } - /*获取运动项目*/ - ExerciseClass TraingModel::GetSportId() - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportType %d", sportId_); - // 设置结构体里面的运动类型 - sportdata->sportId = sportId_; - sportdata->sportType = sportType_; - - switch (sportId_) - { - // 室外跑步 室外走路 - case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING: - case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING: - return ExerciseClass::OUTDOOR; - - // 室内跑步 室内走路 - case UIResourceTextId::STR_EXERCISE_INDOORRUNNING: - case UIResourceTextId::STR_EXERCISE_INDOORWALKING: - return ExerciseClass::INDOOR; - - // 跑步机 - case UIResourceTextId::STR_EXERCISE_TREADMILL: - case UIResourceTextId::STR_EXERCISE_STROLLMACHINE: - return ExerciseClass::TREADMILL; - - // 自由训练 - default: - return ExerciseClass::FREE_TRAINING; - } - } - /*判断是否为特殊运动*/ - void TraingModel::IsSpecialSport(UIResourceTextId sportId_) - { - switch (sportId_) - { - case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING: // 室外跑步 室外走路 - case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING: - case UIResourceTextId::STR_EXERCISE_INDOORRUNNING: // 室内跑步 室内走路 - case UIResourceTextId::STR_EXERCISE_INDOORWALKING: - case UIResourceTextId::STR_EXERCISE_TREADMILL: // 跑步机 - case UIResourceTextId::STR_EXERCISE_STROLLMACHINE: - isspecialsport_ = true; - break; - default: // 自由训练 - isspecialsport_ = false; - break; - } - } - - bool TraingModel::GetIsSpecial() - { - return isspecialsport_; - } - /*获取目标字符串*/ - std::string TraingModel::GetTagStr() - { - /* - 通用目标配置: 时长、卡路里 - 不通用目标配置: 步数、距离 +SportData *sportdata = new SportData(); +TraingModel ::TraingModel() { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::TraingModel()"); + // sportdata->Initialize(); // 初始化结构体 +} +TraingModel ::~TraingModel() { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::~TraingModel()"); + TraingUnsubscribeTopic(TOPIC_EVENT_ACTIVITY_UPDATE); // 取消订阅 + TraingUnsubscribeTopic(TOPIC_EVENT_BLE_TRAINING); + TraingUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA); + TraingUnsubscribeTopic(TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE); +} +TraingModel *TraingModel::GetInstance(void) { + static TraingModel instance; + return &instance; +} - 如果配置项是特殊目标 - -> 普通训练: 无训练目标 - -> 特殊训练: 有训练目标 - */ +void TraingModel ::Init() { + TraingSubscribeTopic(TOPIC_EVENT_ACTIVITY_UPDATE); // 进行消息订阅 + TraingSubscribeTopic(TOPIC_EVENT_BLE_TRAINING); + TraingSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA); + TraingSubscribeTopic(TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE); +} +/*设置运动类型*/ +void TraingModel::SetSportType(Exercisetype type) { sportType_ = type; } +/*结束数据icon*/ +std::string sportImages[8] = { + FITNESS_54_IMAGE, DANCE_54_IMAGE, REST_54_IMAGE, BALL_54_IMAGE, + SWIMMING_54_IMAGE, ICE_54_IMAGE, LIMIT_54_IMAGE, OTHER_54_IMAGE, +}; +/*训练记录Icon*/ +std::string sportIcons[8] = { + FITNESS_IMAGE, DANCE_IMAGE, REST_IMAGE, BALL_IMAGE, + SWIMMING_IMAGE, ICE_IMAGE, LIMIT_IMAGE, OTHER_IMAGE, +}; +/*获取训练Id->协议*/ +int TraingModel::GetBleSportId(Exercisetype sporttype, UIResourceTextId id) { + int offset = 0; + + switch (sporttype) { + case Exercisetype::FITNESS: // 0~57 + offset = 0; + break; + case Exercisetype::DANCE: // 0~9 + offset = 58; + break; + case Exercisetype::LEISURE: // 0~23 + offset = 58 + 10; + break; + case Exercisetype::BALL: // 0~28 + offset = 58 + 10 + 24; + break; + case Exercisetype::WATER: // 0~23 + offset = 58 + 10 + 24 + 29; + break; + case Exercisetype::ICE: // 0~11 + offset = 58 + 10 + 24 + 29 + 24; + break; + case Exercisetype::EXTREME: // 0~9 + offset = 58 + 10 + 24 + 29 + 24 + 12; + break; + case Exercisetype::OTHER: // 0~8 + offset = 58 + 10 + 24 + 29 + 24 + 12 + 10; + break; + default: + offset = 0; + break; + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " offset %d id %d", offset, id); + return id - offset; +} +/*获取运动类型图片*/ +std::string TraingModel::GetSportType(Exercisetype sporttype) { + int index = static_cast(sporttype); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportType index %d", index); + return sportImages[index]; +} +/*获取运动类型icon*/ +std::string TraingModel::GetSportIcon(Exercisetype sporttype) { + int index = static_cast(sporttype); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportIcon index %d", index); + return sportIcons[static_cast(sporttype)]; +} +/*设置运动Id*/ +void TraingModel::SetSportEvent(UIResourceTextId id) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SetSportType %d", sportId_); + IsSpecialSport(id); // 设置特殊性 + sportId_ = id; +} +/*获取运动Id*/ +UIResourceTextId TraingModel::GetSportEvent() { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportEvent %d", sportId_); + return sportId_; +} +/*获取运动项目*/ +ExerciseClass TraingModel::GetSportId() { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportType %d", sportId_); + // 设置结构体里面的运动类型 + sportdata->sportId = sportId_; + sportdata->sportType = sportType_; + + switch (sportId_) { + // 室外跑步 室外走路 + case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING: + case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING: + // return ExerciseClass::OUTDOOR; 统一使用室内 + + // 室内跑步 室内走路 + case UIResourceTextId::STR_EXERCISE_INDOORRUNNING: + case UIResourceTextId::STR_EXERCISE_INDOORWALKING: + return ExerciseClass::INDOOR; + + // 跑步机 + case UIResourceTextId::STR_EXERCISE_TREADMILL: + case UIResourceTextId::STR_EXERCISE_STROLLMACHINE: + return ExerciseClass::TREADMILL; + + // 自由训练 + default: + return ExerciseClass::FREE_TRAINING; + } +} +/*判断是否为特殊运动*/ +void TraingModel::IsSpecialSport(UIResourceTextId sportId_) { + switch (sportId_) { + case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING: // 室外跑步 室外走路 + case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING: + case UIResourceTextId::STR_EXERCISE_INDOORRUNNING: // 室内跑步 室内走路 + case UIResourceTextId::STR_EXERCISE_INDOORWALKING: + case UIResourceTextId::STR_EXERCISE_TREADMILL: // 跑步机 + case UIResourceTextId::STR_EXERCISE_STROLLMACHINE: + isspecialsport_ = true; + break; + default: // 自由训练 + isspecialsport_ = false; + break; + } +} - std::string tagStr; +bool TraingModel::GetIsSpecial() { return isspecialsport_; } +/*获取目标字符串*/ +std::string TraingModel::GetTagStr() { + /* + 通用目标配置: 时长、卡路里 + 不通用目标配置: 步数、距离 - switch (sportTagType_) - { - case ExerciseTag::Duration: - tagStr = std::to_string(sportTag_) + " min"; // 时长目标 - break; + 如果配置项是特殊目标 + -> 普通训练: 无训练目标 + -> 特殊训练: 有训练目标 + */ - case ExerciseTag::Calories: - tagStr = std::to_string(sportTag_) + " kcal"; // 卡路里目标 - break; + std::string tagStr; - case ExerciseTag::Steps: - case ExerciseTag::Distance: - if (isspecialsport_) // 检查是否为特殊训练 - { - // 只在特殊训练模式下使用步数和距离目标 - if (sportTagType_ == ExerciseTag::Steps) - { - tagStr = std::to_string(sportTag_) + " steps"; // 步数目标 - } - else - { - tagStr = std::to_string(sportTag_) + " km"; // 距离目标 - } - } - else - { - tagStr = ""; // 普通训练下不使用目标 - } - break; + switch (sportTagType_) { + case ExerciseTag::Duration: + tagStr = std::to_string(sportTag_) + " min"; // 时长目标 + break; - default: - tagStr = ""; // 未知目标类型 - break; - } + case ExerciseTag::Calories: + tagStr = std::to_string(sportTag_) + " kcal"; // 卡路里目标 + break; - return tagStr; - } - /*设置运动状态*/ - void TraingModel::SetSportState(ExerciseState state) - { - if (state != ExerciseState::General) - { - /*运动开始并且是app发起的运动*/ - if (Openingway == true && state != ExerciseState::End) - { - sendtraningstatedata(static_cast(state), sportdata->duration); - } - } - sportState_ = state; - } - /*获取运动状态*/ - ExerciseState TraingModel::GetSportState() - { - return sportState_; - } - // 计算平均心率的函数 - double CalculateAverageHeartRate(const std::vector &heartRates) + case ExerciseTag::Steps: + case ExerciseTag::Distance: + if (isspecialsport_) // 检查是否为特殊训练 { - if (heartRates.size() <= 2) - { - // 如果心率数据点少于等于2,无法去掉最高和最低值 - return 0.0; // 或者返回心率的平均值 - } - - // 创建一个副本以避免修改原始数据 - std::vector sortedHeartRates = heartRates; - - // 排序 - std::sort(sortedHeartRates.begin(), sortedHeartRates.end()); - - // 去掉一个最高值和一个最低值 - sortedHeartRates.erase(sortedHeartRates.begin()); // 去掉最低值 - sortedHeartRates.pop_back(); // 去掉最高值 - - // 计算剩余心率的平均值 - double sum = 0; - for (int rate : sortedHeartRates) - { - sum += rate; - } - - return sum / sortedHeartRates.size(); // 返回平均值 + // 只在特殊训练模式下使用步数和距离目标 + if (sportTagType_ == ExerciseTag::Steps) { + tagStr = std::to_string(sportTag_) + " steps"; // 步数目标 + } else { + tagStr = std::to_string(sportTag_) + " km"; // 距离目标 + } + } else { + tagStr = ""; // 普通训练下不使用目标 } - /*分析数据*/ - void TraingModel::AnalysisData(cywee_activity_result_t *cyweeInfo) - { - // 不同的运动类型解析不同的数据 - // 通用数据 - sportdata->steps = cyweeInfo->steps; - sportdata->distance = cyweeInfo->distance; - sportdata->calories = cyweeInfo->calories; + break; - // sportdata->cdc = cyweeInfo->step_frequency; - // sportdata->std = cyweeInfo->step_length; + default: + tagStr = ""; // 未知目标类型 + break; + } - sportdata->pc = cyweeInfo->pace; - - // 更新最慢配速 - if (sportdata->spc < sportdata->pc) - { - sportdata->spc = sportdata->pc; - } - - - - // 计算平均心率 - if (sportdata->heart > 50) - { - sportdata->avgheart = Averageheartrate(sportdata->heart); - } - - // 心率提醒 - int maxHeartRate = ConfigModel::GetInstance()->get_configData_int(ConfigModel::CONFIGMODEL_ITEM_TRAINING_HEART_MAX); - if (sportdata->heart >= maxHeartRate) - { - uapi_set_screen_on_api(); // 亮屏检测 - if (true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb() && (!uapi_sleep_mode_flag_get())) - { - ui_api_vibrate_once_func(); - } - TraingCardView::GetInstance()->SetPopupViewStatus(HeartPopup, true); - } - - // 训练目标检查 - if (sportdata->tag && !Gettagstuats) - { - sportdata->goaldegree = GetGoaldegree(); - - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->goaldegree %d", sportdata->goaldegree); - if (sportdata->goaldegree == 100) - { - // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "currentdata%d", currentdata); - uapi_set_screen_on_api(); // 亮屏检测 - if (true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb()) - { - ui_api_vibrate_once_func(); - } - TraingCardView::GetInstance()->SetPopupViewStatus(GetTagPopup, true); - TraingCardView::GetInstance()->GetAnimator()->Start(); - Gettagstuats = true; - } - } + return tagStr; +} +/*设置运动状态*/ +void TraingModel::SetSportState(ExerciseState state) { + if (state != ExerciseState::General) { + /*运动开始并且是app发起的运动*/ + if (Openingway == true && state != ExerciseState::End) { + sendtraningstatedata(static_cast(state), sportdata->duration); + } + } + sportState_ = state; +} +/*获取运动状态*/ +ExerciseState TraingModel::GetSportState() { return sportState_; } +// 计算平均心率的函数 +double CalculateAverageHeartRate(const std::vector &heartRates) { + if (heartRates.size() <= 2) { + // 如果心率数据点少于等于2,无法去掉最高和最低值 + return 0.0; // 或者返回心率的平均值 + } + + // 创建一个副本以避免修改原始数据 + std::vector sortedHeartRates = heartRates; + + // 排序 + std::sort(sortedHeartRates.begin(), sortedHeartRates.end()); + + // 去掉一个最高值和一个最低值 + sortedHeartRates.erase(sortedHeartRates.begin()); // 去掉最低值 + sortedHeartRates.pop_back(); // 去掉最高值 + + // 计算剩余心率的平均值 + double sum = 0; + for (int rate : sortedHeartRates) { + sum += rate; + } + + return sum / sortedHeartRates.size(); // 返回平均值 +} +/*分析数据*/ +void TraingModel::AnalysisData(cywee_activity_result_t *cyweeInfo) { + // 不同的运动类型解析不同的数据 + // 通用数据 + sportdata->steps = cyweeInfo->steps; + sportdata->distance = cyweeInfo->distance; + sportdata->calories = cyweeInfo->calories; + + // sportdata->cdc = cyweeInfo->step_frequency; + // sportdata->std = cyweeInfo->step_length; + + sportdata->pc = cyweeInfo->pace; + + // 更新最慢配速 + if (sportdata->spc < sportdata->pc) { + sportdata->spc = sportdata->pc; + } + + // 计算平均心率 + if (sportdata->heart > 50) { + sportdata->avgheart = Averageheartrate(sportdata->heart); + } + + // 心率提醒 + int maxHeartRate = ConfigModel::GetInstance()->get_configData_int( + ConfigModel::CONFIGMODEL_ITEM_TRAINING_HEART_MAX); + if (sportdata->heart >= maxHeartRate) { + uapi_set_screen_on_api(); // 亮屏检测 + if (true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb() && + (!uapi_sleep_mode_flag_get())) { + ui_api_vibrate_once_func(); + } + TraingCardView::GetInstance()->SetPopupViewStatus(HeartPopup, true); + } + + // 训练目标检查 + if (sportdata->tag && !Gettagstuats) { + sportdata->goaldegree = GetGoaldegree(); + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->goaldegree %d", + sportdata->goaldegree); + if (sportdata->goaldegree == 100) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "currentdata%d", currentdata); + uapi_set_screen_on_api(); // 亮屏检测 + if (true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb()) { + ui_api_vibrate_once_func(); + } + TraingCardView::GetInstance()->SetPopupViewStatus(GetTagPopup, true); + TraingCardView::GetInstance()->GetAnimator()->Start(); + Gettagstuats = true; } + } +} #if 0 int avg_step_freq;//平均步频 @@ -549,706 +476,608 @@ namespace OHOS int distance_motion;//体感距离 #endif - /*分析activity extra info数据*/ - void TraingModel::AnalysisExtraData(cywee_activity_result_extre_info_t *cyweeInfo) - { - sportdata->apc = cyweeInfo->avg_pace; - sportdata->fpc = cyweeInfo->max_pace; - sportdata->cdc = cyweeInfo->avg_step_freq; - sportdata->std = cyweeInfo->avg_step_len * 100; // 前者cm 后者m - } - /*分析运动心率数据*/ - void TraingModel::AnalysisHeartData(u_int8_t hrs) - { - sportdata->heart = hrs; - SetIntensity(sportdata->heart); // 设置训练强度 - } - - /*打印函数*/ - void TraingModel::printf_data(SportData *data) - { - /*打印测试一下数据*/ - printf("\r\n****************************************\r\n"); - printf("Sport type: %d\n", data->sportType); - printf("Sport ID: %d\n", data->sportId); - printf("Start date: %s\n", data->start_date.c_str()); - printf("Start time: %s\n", data->start_time.c_str()); - printf("End time: %s\n", data->end_time.c_str()); - printf("Goal degree: %d\n", data->goaldegree); - printf("Duration: %d\n", data->duration); - printf("Distance: %d\n", data->distance); - printf("Average heart rate: %d\n", data->avgheart); - printf("Steps: %d\n", data->steps); - printf("Intensity: %d\n", data->intensity); - printf("\r\n****************************************\r\n"); - } - /*获取数据*/ - SportData *TraingModel::GetSportdata() - { - // printf_data(sportdata); - return sportdata; - } - /* 设置训练数据[为训练记录准备] */ - void TraingModel::SetSportdata(SportData *data) - { - if (data != nullptr && sportdata != nullptr) - { - sportdata->sportType = data->sportType; - sportdata->sportId = data->sportId; - sportdata->start_date = data->start_date; - sportdata->start_time = data->start_time; - sportdata->end_time = data->end_time; - sportdata->goaldegree = data->goaldegree; - sportdata->duration = data->duration; - sportdata->distance = data->distance; - sportdata->avgheart = data->avgheart; - sportdata->steps = data->steps; - sportdata->intensity = data->intensity; - sportdata->apc = data->apc; - sportdata->fpc = data->fpc; - sportdata->spc = data->spc; - sportdata->std = data->std; - sportdata->cdc = data->cdc; - printf_data(data); - IsSpecialSport(sportdata->sportId); // 配置训练特殊性 - } - } - /*获取训练卡路里*/ - int TraingModel::GetCal() - { - return sportdata->calories; - } - /*获取训练目标*/ - int TraingModel::GetSportTag() - { - return sportdata->tag; - } - /*获取训练项目类型*/ - ExerciseTag TraingModel::GetSportTagtype() - { - return sportdata->sportTagType; - } - /*重置训练配置*/ - void TraingModel::ResetSharedTrainingData() - { - sportdata->Reset(); // 重置结构体 - heartRateData.clear(); // 清空心率数据 - recentHeartRates.clear(); - delayed.clear(); // 重置 delayed 字典 - - while (!maxHeap.empty()) - { // 清空最大堆 - maxHeap.pop(); - } - while (!minHeap.empty()) - { // 清空最小堆 - minHeap.pop(); - } - - totalHeartRate = 0; - countHeartRate = 0; +/*分析activity extra info数据*/ +void TraingModel::AnalysisExtraData( + cywee_activity_result_extre_info_t *cyweeInfo) { + sportdata->apc = cyweeInfo->avg_pace; + sportdata->fpc = cyweeInfo->max_pace; + sportdata->cdc = cyweeInfo->avg_step_freq; + sportdata->std = cyweeInfo->avg_step_len * 100; // 前者cm 后者m +} +/*分析运动心率数据*/ +void TraingModel::AnalysisHeartData(u_int8_t hrs) { + sportdata->heart = hrs; + SetIntensity(sportdata->heart); // 设置训练强度 +} - Gettagstuats = false; // 重置训练达标标志位 - Openstate = true; // 开启运动开始标志位 - } +/*打印函数*/ +void TraingModel::printf_data(SportData *data) { + /*打印测试一下数据*/ + printf("\r\n****************************************\r\n"); + printf("Sport type: %d\n", data->sportType); + printf("Sport ID: %d\n", data->sportId); + printf("Start date: %s\n", data->start_date.c_str()); + printf("Start time: %s\n", data->start_time.c_str()); + printf("End time: %s\n", data->end_time.c_str()); + printf("Goal degree: %d\n", data->goaldegree); + printf("Duration: %d\n", data->duration); + printf("Distance: %d\n", data->distance); + printf("Average heart rate: %d\n", data->avgheart); + printf("Steps: %d\n", data->steps); + printf("Intensity: %d\n", data->intensity); + printf("\r\n****************************************\r\n"); +} +/*获取数据*/ +SportData *TraingModel::GetSportdata() { + // printf_data(sportdata); + return sportdata; +} +/* 设置训练数据[为训练记录准备] */ +void TraingModel::SetSportdata(SportData *data) { + if (data != nullptr && sportdata != nullptr) { + sportdata->sportType = data->sportType; + sportdata->sportId = data->sportId; + sportdata->start_date = data->start_date; + sportdata->start_time = data->start_time; + sportdata->end_time = data->end_time; + sportdata->goaldegree = data->goaldegree; + sportdata->duration = data->duration; + sportdata->distance = data->distance; + sportdata->avgheart = data->avgheart; + sportdata->steps = data->steps; + sportdata->intensity = data->intensity; + sportdata->apc = data->apc; + sportdata->fpc = data->fpc; + sportdata->spc = data->spc; + sportdata->std = data->std; + sportdata->cdc = data->cdc; + printf_data(data); + IsSpecialSport(sportdata->sportId); // 配置训练特殊性 + } +} +/*获取训练卡路里*/ +int TraingModel::GetCal() { return sportdata->calories; } +/*获取训练目标*/ +int TraingModel::GetSportTag() { return sportdata->tag; } +/*获取训练项目类型*/ +ExerciseTag TraingModel::GetSportTagtype() { return sportdata->sportTagType; } +/*重置训练配置*/ +void TraingModel::ResetSharedTrainingData() { + sportdata->Reset(); // 重置结构体 + heartRateData.clear(); // 清空心率数据 + + ClearPaceTable(); //重置配速数据 + ClearHeartTable(); // 清空心率数据 + + recentHeartRates.clear(); + delayed.clear(); // 重置 delayed 字典 + + while (!maxHeap.empty()) { // 清空最大堆 + maxHeap.pop(); + } + while (!minHeap.empty()) { // 清空最小堆 + minHeap.pop(); + } + + totalHeartRate = 0; + countHeartRate = 0; + heartcount = 0; + + Gettagstuats = false; // 重置训练达标标志位 + Openstate = true; // 开启运动开始标志位 +} - /*设置运动开始与结束*/ - void TraingModel::SetTimestamp() - { - uint32_t time; - if (uapi_get_timestampe_ss(&time) != ERRCODE_SUCC) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp"); - return; - } +/*设置运动开始与结束*/ +void TraingModel::SetTimestamp() { + uint32_t time; + if (uapi_get_timestampe_ss(&time) != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp"); + return; + } - ExerciseState currentState = GetSportState(); // 获取当前运动状态 + ExerciseState currentState = GetSportState(); // 获取当前运动状态 - // 增加标志位互斥保障"开始"和"结束"的唯一性操作 - if (currentState == ExerciseState::Start && !Startstate) - { - // 设置训练 runtime 为 1 训练中 - uapi_dev_runtime_set_train_status(1); + // 增加标志位互斥保障"开始"和"结束"的唯一性操作 + if (currentState == ExerciseState::Start && !Startstate) { + // 设置训练 runtime 为 1 训练中 + uapi_dev_runtime_set_train_status(1); - ResetSharedTrainingData(); // 重置共享训练数据 + ResetSharedTrainingData(); // 重置共享训练数据 - printf("SetTimestamp::time:%u \r\n", time); - sportdata->starttime = time; - sportdata->sportType = sportType_; // 训练类型 - sportdata->sportId = sportId_; - IsSpecialSport(sportdata->sportId); // 配置运动特殊性状态 + printf("SetTimestamp::time:%u \r\n", time); + sportdata->starttime = time; + sportdata->sportType = sportType_; // 训练类型 + sportdata->sportId = sportId_; + IsSpecialSport(sportdata->sportId); // 配置运动特殊性状态 - if (sportTag_) // 有值才设置[训练目标] - { - sportdata->sportTagType = sportTagType_; - sportdata->tag = sportTag_; - } + if (sportTag_) // 有值才设置[训练目标] + { + sportdata->sportTagType = sportTagType_; + sportdata->tag = sportTag_; + } - (Openingway == true) ? (printf("app发起运动\n")) : (printf("手表发起运动\n")); + (Openingway == true) ? (printf("app发起运动\n")) + : (printf("手表发起运动\n")); - // 设置起始日期和时间 - SetStartDateTime(); + // 设置起始日期和时间 + SetStartDateTime(); - Startstate = true; - Endstate = false; // 确保"开始"和"结束"状态互斥 + Startstate = true; + Endstate = false; // 确保"开始"和"结束"状态互斥 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始运动"); - } - else if (currentState == ExerciseState::End && !Endstate) - { - // 设置训练 runtime 为 0 训练结束 - uapi_dev_runtime_set_train_status(0); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始运动"); + } else if (currentState == ExerciseState::End && !Endstate) { + // 设置训练 runtime 为 0 训练结束 + uapi_dev_runtime_set_train_status(0); - sportdata->endtime = time; + sportdata->endtime = time; - SetEndTime(); + SetEndTime(); - sportState_ = ExerciseState::General; - Openstate = false; // 关闭运动标志位 + sportState_ = ExerciseState::General; + Openstate = false; // 关闭运动标志位 - // 记录运动数据 - RecordSportData(); + // 记录运动数据 + RecordSportData(); - Startstate = false; - Endstate = true; + Startstate = false; + Endstate = true; #if 0 // 重置训练目标 [发生在训练前] sportTag_ = 0; sportTagType_ = ExerciseTag::UNKNOW; #endif - /*运动结束并且是手表发起的运动*/ - if (Openingway == false) - { - sendtraningstateend(); - } - /*运动结束并且是app发起的运动*/ - else - { - sendtraningstatedata(0, sportdata->duration); - } - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "结束运动"); - } - } - /*设置开始时间*/ - void TraingModel::SetStartDateTime() - { - std::string startDate, startTime; - - if (!GetFormattedDate(startDate, "Failed to get start date")) - return; - if (!GetFormattedTime(startTime, "Failed to get start time")) - return; - - sportdata->start_date = startDate; - sportdata->start_time = startTime; - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->start_time [%s]\r\n", sportdata->start_time.c_str()); - } - /*设置结束时间*/ - void TraingModel::SetEndTime() - { - std::string endTime; - - if (GetFormattedTime(endTime, "Failed to get end time")) - { - sportdata->end_time = endTime; - } - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->end_time [%s]\r\n", sportdata->end_time.c_str()); - } - /*获取日期字符串*/ - bool TraingModel::GetFormattedDate(std::string &dateOutput, const char *errorMsg) - { - char *date = (char *)malloc(9 * sizeof(char)); // 分配内存给start_date - if (uapi_get_YYMMDD_Time(date, '/') != ERRCODE_SUCC) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", errorMsg); - free(date); - return false; - } - dateOutput = std::string(date); - free(date); // 释放内存 - return true; - } - /*获取时间字符串*/ - bool TraingModel::GetFormattedTime(std::string &timeOutput, const char *errorMsg) - { - char *time = (char *)malloc(9 * sizeof(char)); // 分配内存给start_time - if (uapi_get_HHMMSS_Time(time, ':', true) != ERRCODE_SUCC) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", errorMsg); - free(time); - return false; - } - timeOutput = std::string(time); - free(time); // 释放内存 - return true; - } - /*保存数据*/ - void TraingModel::RecordSportData() - { -#if READTEST - if (SaveSportData() == false) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData error!"); - } -#else - if (MomentumFlag) - { - // GetGoaldegree(); // 设置目标完成度 - if (SaveSportData()) - { - TraingRecordModel::GetInstance().SetJsonStatus(true); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData ok!"); - } - else - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData error!"); - } - } -#endif - } - // 获取训练时长时间 - std::string TraingModel::GetTrainingTime() - { - int hour = sportdata->duration / NUM_TIME_HOUR; - int min = (sportdata->duration % NUM_TIME_HOUR) / NUM_TIME_MIN; - int sec = (sportdata->duration % NUM_TIME_HOUR) % NUM_TIME_MIN; - - std::ostringstream oss; - oss << std::setfill('0') << std::setw(2) << hour << ":" << std::setw(2) << min << ":" << std::setw(2) << sec; - - std::string triningtime = oss.str(); - return triningtime; - } - /*解析时间戳 返回例如:13:00:22*/ - std::string TraingModel::AnalysisTimestamp(uint64_t timestamp) - { - // 将时间戳转换为小时、分钟、秒 - int hours = timestamp / 3600000; // 1小时 = 3600000毫秒 - int minutes = (timestamp % 3600000) / 60000; // 1分钟 = 60000毫秒 - int seconds = (timestamp % 60000) / 1000; // 1秒 = 1000毫秒 - - // 将小时、分钟、秒转换为字符串 - std::string hoursStr = std::to_string(hours); - std::string minutesStr = std::to_string(minutes); - std::string secondsStr = std::to_string(seconds); - - // 格式化输出为 HH:MM:SS - std::stringstream ss; - ss << std::setfill('0') << std::setw(2) << hoursStr << ":" << std::setw(2) << minutesStr << ":" << std::setw(2) << secondsStr; - - return ss.str(); - } - int TraingModel::CalculateAverageHeartRate(int newHeartRate) - { - // 将新的心率添加到数据列表 - heartRateData.push_back(newHeartRate); - totalHeartRate += newHeartRate; - countHeartRate++; - - // 将新的心率插入到堆中 - maxHeap.push(newHeartRate); - minHeap.push(newHeartRate); - - // 如果超过窗口大小,移除最早的心率 - if (heartRateData.size() > windowSize) - { - int oldestRate = heartRateData[0]; - totalHeartRate -= oldestRate; - countHeartRate--; - - // 将老旧值从列表中移除 - heartRateData.erase(heartRateData.begin()); - - // 标记老旧值为待删除 - delayed[oldestRate]++; - } - - // 清理堆中的老旧值 - while (!maxHeap.empty() && delayed[maxHeap.top()] > 0) - { - delayed[maxHeap.top()]--; - maxHeap.pop(); - } - - while (!minHeap.empty() && delayed[minHeap.top()] > 0) - { - delayed[minHeap.top()]--; - minHeap.pop(); - } - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "新心率: %d, 当前心率总和: %d, 心率计数: %d", - newHeartRate, totalHeartRate, countHeartRate); - - // 如果心率数量少于 3,直接返回当前的平均值 - if (countHeartRate < 3) - { - return totalHeartRate / countHeartRate; // 无法去除最大最小值 - } - - // 取出当前未被删除的最大和最小的心率 - int maxRate = maxHeap.top(); - int minRate = minHeap.top(); - - // 进行去极值后的平均计算 - int average = (totalHeartRate - maxRate - minRate) / (countHeartRate - 2); - - // 打印计算结果 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "去极值后的平均心率: %d (去掉最大值: %d, 去掉最小值: %d)", - average, maxRate, minRate); - - return average; - } - // 显示心率 - int TraingModel::CalculateFilteredHeartRate(int newHeartRate) - { - // 将新的心率添加到最近心率列表 - recentHeartRates.push_back(newHeartRate); - - // 如果超过窗口大小,移除最早的心率 - if (recentHeartRates.size() > windowSize) - { - recentHeartRates.erase(recentHeartRates.begin()); - } - - // 计算当前窗口中的平均心率 - int total = std::accumulate(recentHeartRates.begin(), recentHeartRates.end(), 0); - - // 打印当前窗口的平均心率 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "过滤后当前窗口的平均心率: %d", - (total / recentHeartRates.size())); - - return total / recentHeartRates.size(); // 返回计算后的平均值 - } - int TraingModel::Averageheartrate(int newHeartRate) - { - if (totalHeartRate == 0) - { - totalHeartRate = newHeartRate; - } - totalHeartRate = (totalHeartRate + newHeartRate) / 2; - - return totalHeartRate; - } - // 设置训练目标类型以及训练目标 - void TraingModel::SetSportTag(ExerciseTag tagtpye, int tag) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "tagtpye[%d] tag[%d]", tagtpye, tag); - sportTagType_ = tagtpye; - sportTag_ = tag; - } - - /* 设置训练强度 */ - void TraingModel::SetIntensity(int heart) - { - // sportdata->intensity = active_state; -#if 1 - /* - 训练强度 - 220-年龄=最高心率 - - 分为四个强度区间 - 较低强度=最高心率*59%以下 - 中等强度=最高心率*60%~69% - 高等强度=最高心率*70%~79% - 超高强度=最高心率*80%以上 - */ - int age = ConfigModel::GetInstance()->GetUserAge(); - int maxHeartRate = MAX_HEART_RATE - age; - - // 确保最大心率为正值 - if (maxHeartRate <= 0) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "maxHeartRate %d is error", maxHeartRate); - return; - } - - // 将 heart 转换为 double 以避免整数除法 - double heartRateAsDouble = static_cast(heart); - double intensityPercentage = (heartRateAsDouble / (double)maxHeartRate) * 100; - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "heart: %d, maxHeartRate: %d, intensityPercentage: %.2f", heart, maxHeartRate, intensityPercentage); - - if (intensityPercentage < LOW_INTENSITY_THRESHOLD) - { - // 较低强度 - sportdata->intensity = LOW_INTENSITY; - } - else if (intensityPercentage >= MEDIUM_INTENSITY_LOWER_THRESHOLD && intensityPercentage <= MEDIUM_INTENSITY_UPPER_THRESHOLD) - { - // 中等强度 - sportdata->intensity = MEDIUM_INTENSITY; - } - else if (intensityPercentage >= HIGH_INTENSITY_LOWER_THRESHOLD && intensityPercentage <= HIGH_INTENSITY_UPPER_THRESHOLD) - { - // 高等强度 - sportdata->intensity = HIGH_INTENSITY; - } - else - { - // 超高强度 - sportdata->intensity = VERY_HIGH_INTENSITY; - } - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "maxHeartRate: %d, heartRate: %d, intensityPercentage: %.2f", maxHeartRate, heart, intensityPercentage); -#endif - } - /*获取训练强度STR*/ - UIResourceTextId TraingModel::GetIntensity() - { - switch (sportdata->intensity) - { - case LOW_INTENSITY: - return UIResourceTextId::STR_LOWER_STRENGTH; - break; - case MEDIUM_INTENSITY: - return UIResourceTextId::STR_MEDIUM_STRENGTH; - break; - case HIGH_INTENSITY: - return UIResourceTextId::STR_HIGH_STRENGTH; - break; - case VERY_HIGH_INTENSITY: - return UIResourceTextId::STR_ULTRA_HIGH_STRENGTH; - break; - default: - return UIResourceTextId::STR_LOWER_STRENGTH; - break; - } - } - /*获取当前的目标值*/ - int TraingModel::GetSportTagData() - { - if (sportdata->tag) - { - // 根据设置的训练目标类型去对应相对的数据 - switch (sportdata->sportTagType) - { - case ExerciseTag::Duration: - return int(sportdata->duration / 60); // 时间是秒需要转换为目标的分钟 - break; - case ExerciseTag::Calories: - return sportdata->calories; //卡路里是kcal - break; - case ExerciseTag::Distance: - return int(sportdata->distance / 1000); //距离是米需要转换为km - break; - case ExerciseTag::Steps: - return sportdata->steps; //步数是步 - break; - default: - break; - } - } - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Not set Sport_Tag!"); - return 0; // 添加默认返回值 - } - //获取运动时长 - int TraingModel::GetDuration() { return sportdata->duration; } - /*获取训练类型Id*/ - UIResourceTextId TraingModel::GetSportTypeId(Exercisetype type) - { - // 根据设置的训练类型去对应相对的数据 - switch (type) - { - // 健身类 - case Exercisetype::FITNESS: - return STR_EXERCISE_LIST; - // 舞蹈类 - case Exercisetype::DANCE: - return STR_DANCING_LIST; - // 休闲运动 - case Exercisetype::LEISURE: - return STR_RECREATIONAL_LIST; - // 球类 - case Exercisetype::BALL: - return STR_BALL_LIST; - // 水上运动 - case Exercisetype::WATER: - return STR_WATER_LIST; - // 冰上运动 - case Exercisetype::ICE: - return STR_ICE_LIST; - // 极限运动 - case Exercisetype::EXTREME: - return STR_EXTREME_LIST; - // 其他 - case Exercisetype::OTHER: - return STR_OTHER_LIST; - default: - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Not ExerciseClass type!"); - break; - } - - return STR_EXERCISE_LIST; // 添加默认返回值[健身类] - } - /*打印存储数据*/ - void TraingModel::printTrainingData(const Trainingdata &data) - { - printf("Trainingdata:\n"); - printf("src: %d\n", data.src); - printf("bt: %u\n", data.bt); - printf("ty: %u\n", data.ty); - printf("st: %u\n", data.st); - printf("sp: %u\n", data.sp); - printf("tgt: %u\n", data.tgt); - printf("tg: %u\n", data.tg); - printf("pg: %u\n", data.pg); - printf("du: %u\n", data.du); - printf("ca: %u\n", data.ca); - printf("di: %u\n", data.di); - printf("hr: %u\n", data.hr); - printf("stp: %u\n", data.stp); - printf("ti: %u\n", data.ti); - printf("cir: %u\n", data.cir); - printf("alt: %u\n", data.alt); - } - /*获取训练目标完成百分比*/ - int TraingModel::GetGoaldegree() - { - if (sportTag_ == 0) - { - return 0; - } - int currentdata = GetSportTagData(); - float completeness = (static_cast(currentdata) / sportdata->tag) * 100; - - return round(completeness); // 四舍五入 - } - /* - uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练 - uint32_t bt; // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4 - 水上项目,5 - 冰上项目,6 - 极限运动,7 - 其他 - uint32_t ty; // 训练类型:自由训练 - uint32_t st; // 开始时间戳(单位:秒) - uint32_t sp; // 结束时间戳(单位:秒) - uint32_t tgt; // 训练目标类型:0 - 距离,1 - 卡路里,2 - 时间,3 - 步数 - uint32_t tg; // 训练目标值:路程(单位:米),卡路里(单位:kcal),时间(单位:分钟),步数(单位:步) - uint32_t pg; // 目标完成度(单位:%) - uint32_t du; // 训练总时长(单位:秒) - uint32_t ca; // 消耗卡路里(单位:kcal) - uint32_t di; // 完成的距离(单位:米) - uint32_t hr; // 平均心率 - uint32_t stp; // 步数 - uint32_t ti; // 训练强度:0 - 较低强度,1 - 中等强度,2 - 高等强度,3 - 超高强度 - uint32_t cir; // 圈数 - uint32_t alt; // 最高海拔高度 - */ - /*保存数据*/ - bool TraingModel::SaveSportData() - { - Trainingdata data; - data.src = Openingway; - data.bt = static_cast(sportdata->sportType); - data.ty = static_cast(GetBleSportId(sportdata->sportType, sportdata->sportId)); - data.st = static_cast(sportdata->starttime); - data.sp = static_cast(sportdata->endtime); - data.tgt = static_cast(sportdata->sportTagType); - data.tg = static_cast(sportdata->tag); - data.pg = static_cast(sportdata->goaldegree); - data.du = static_cast(sportdata->duration); - data.ca = static_cast(sportdata->calories * 10); - data.di = static_cast(sportdata->distance); - data.hr = static_cast(sportdata->avgheart); - data.stp = static_cast(sportdata->steps); - data.ti = static_cast(sportdata->intensity); - /*230目前不支持【圈数】【最高海拔高度】*/ - data.cir = 0; - data.alt = 0; - /*配速相关还未处理 暂时保存0*/ - data.apc = static_cast(sportdata->apc); - data.fpc = static_cast(sportdata->fpc); - data.spc = static_cast(sportdata->spc); - data.std = static_cast(sportdata->std); - data.cdc = static_cast(sportdata->cdc); - - // 保存数据到bin - if (write_Trainingdata_data(data) != 1) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "write_Trainingdata_data is error!"); - // return false; - } - // 保存数据到json - if (SaveDataToJson(sportdata) != true) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDataToJson is error!"); - return false; - } -/*json读取测试*/ -#if READTEST - SportData *sportDataArray = LoadDataFormJson(); - if (sportDataArray != nullptr) - { - int dataCount = 0; - for (int i = 0; i < MAX_DATA_COUNT; i++) // 最多只有10条数据 - { - SportData sportData = sportDataArray[i]; - printf("Sport type: %d\n", sportData.sportType); - printf("Sport ID: %d\n", sportData.sportId); - printf("Start date: %s\n", sportData.start_date.c_str()); - printf("Start time: %d\n", sportData.starttime); - printf("End time: %d\n", sportData.endtime); - printf("Goal degree: %d\n", sportData.goaldegree); - printf("Duration: %d\n", sportData.duration); - printf("Distance: %d\n", sportData.distance); - printf("Average heart rate: %d\n", sportData.avgheart); - printf("Steps: %d\n", sportData.steps); - printf("Intensity: %d\n", sportData.intensity); - - dataCount++; - } - - delete[] sportDataArray; // 记得释放内存 - } -#endif -/*bin 读取测试*/ -#if 0 - Trainingdata *readdata{nullptr}; - int i = 0; - while (readdata = read_Trainingdata_data("2024_04_25", i)) - { - if (readdata == NULL) - return; - printTrainingData(*readdata); - // delete readdata; - free(readdata); - i++; - } -#endif - return true; - // delete data; - } - /*设置进入方式*/ - void TraingModel::SetEntryType(ENTEYTYPE type) - { - entey_type = type; - } - /*获取进入方式*/ - ENTEYTYPE TraingModel::GetEntryType() - { - return entey_type; - } - /*设置开启方式*/ - void TraingModel::SetSportOpenWay(bool way) - { - Openingway = way; - } - /*设置运动是否开始*/ - void TraingModel::SetSportOpenState(bool state) - { - Openstate = state; - } - /*获取运动是否开始*/ - bool TraingModel::GetSportOpenState() - { - return Openstate; + /*运动结束并且是手表发起的运动*/ + if (Openingway == false) { + sendtraningstateend(); } - /*获取运动时长*/ - uint32_t TraingModel::GetSportTime() - { - return sportdata->duration; + /*运动结束并且是app发起的运动*/ + else { + sendtraningstatedata(0, sportdata->duration); } - /*获取训练量是否达标*/ - bool TraingModel::GetMomentum() { + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "结束运动"); + } +} +/*设置开始时间*/ +void TraingModel::SetStartDateTime() { + std::string startDate, startTime; + + if (!GetFormattedDate(startDate, "Failed to get start date")) + return; + if (!GetFormattedTime(startTime, "Failed to get start time")) + return; + + sportdata->start_date = startDate; + sportdata->start_time = startTime; + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->start_time [%s]\r\n", + sportdata->start_time.c_str()); +} +/*设置结束时间*/ +void TraingModel::SetEndTime() { + std::string endTime; + + if (GetFormattedTime(endTime, "Failed to get end time")) { + sportdata->end_time = endTime; + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->end_time [%s]\r\n", + sportdata->end_time.c_str()); +} +/*获取日期字符串*/ +bool TraingModel::GetFormattedDate(std::string &dateOutput, + const char *errorMsg) { + char *date = (char *)malloc(9 * sizeof(char)); // 分配内存给start_date + if (uapi_get_YYMMDD_Time(date, '/') != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", errorMsg); + free(date); + return false; + } + dateOutput = std::string(date); + free(date); // 释放内存 + return true; +} +/*获取时间字符串*/ +bool TraingModel::GetFormattedTime(std::string &timeOutput, + const char *errorMsg) { + char *time = (char *)malloc(9 * sizeof(char)); // 分配内存给start_time + if (uapi_get_HHMMSS_Time(time, ':', true) != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", errorMsg); + free(time); + return false; + } + timeOutput = std::string(time); + free(time); // 释放内存 + return true; +} +/*保存数据*/ +void TraingModel::RecordSportData() { +#if READTEST + if (SaveSportData() == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData error!"); + } +#else + if (MomentumFlag) { + // GetGoaldegree(); // 设置目标完成度 + if (SaveSportData()) { + TraingRecordModel::GetInstance().SetJsonStatus(true); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData ok!"); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData error!"); + } + } +#endif +} +// 获取训练时长时间 +std::string TraingModel::GetTrainingTime() { + int hour = sportdata->duration / NUM_TIME_HOUR; + int min = (sportdata->duration % NUM_TIME_HOUR) / NUM_TIME_MIN; + int sec = (sportdata->duration % NUM_TIME_HOUR) % NUM_TIME_MIN; + + std::ostringstream oss; + oss << std::setfill('0') << std::setw(2) << hour << ":" << std::setw(2) << min + << ":" << std::setw(2) << sec; + + std::string triningtime = oss.str(); + return triningtime; +} +/*解析时间戳 返回例如:13:00:22*/ +std::string TraingModel::AnalysisTimestamp(uint64_t timestamp) { + // 将时间戳转换为小时、分钟、秒 + int hours = timestamp / 3600000; // 1小时 = 3600000毫秒 + int minutes = (timestamp % 3600000) / 60000; // 1分钟 = 60000毫秒 + int seconds = (timestamp % 60000) / 1000; // 1秒 = 1000毫秒 + + // 将小时、分钟、秒转换为字符串 + std::string hoursStr = std::to_string(hours); + std::string minutesStr = std::to_string(minutes); + std::string secondsStr = std::to_string(seconds); + + // 格式化输出为 HH:MM:SS + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << hoursStr << ":" << std::setw(2) + << minutesStr << ":" << std::setw(2) << secondsStr; + + return ss.str(); +} +int TraingModel::CalculateAverageHeartRate(int newHeartRate) { + // 将新的心率添加到数据列表 + heartRateData.push_back(newHeartRate); + totalHeartRate += newHeartRate; + countHeartRate++; + + // 将新的心率插入到堆中 + maxHeap.push(newHeartRate); + minHeap.push(newHeartRate); + + // 如果超过窗口大小,移除最早的心率 + if (heartRateData.size() > windowSize) { + int oldestRate = heartRateData[0]; + totalHeartRate -= oldestRate; + countHeartRate--; + + // 将老旧值从列表中移除 + heartRateData.erase(heartRateData.begin()); + + // 标记老旧值为待删除 + delayed[oldestRate]++; + } + + // 清理堆中的老旧值 + while (!maxHeap.empty() && delayed[maxHeap.top()] > 0) { + delayed[maxHeap.top()]--; + maxHeap.pop(); + } + + while (!minHeap.empty() && delayed[minHeap.top()] > 0) { + delayed[minHeap.top()]--; + minHeap.pop(); + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "新心率: %d, 当前心率总和: %d, 心率计数: %d", newHeartRate, + totalHeartRate, countHeartRate); + + // 如果心率数量少于 3,直接返回当前的平均值 + if (countHeartRate < 3) { + return totalHeartRate / countHeartRate; // 无法去除最大最小值 + } + + // 取出当前未被删除的最大和最小的心率 + int maxRate = maxHeap.top(); + int minRate = minHeap.top(); + + // 进行去极值后的平均计算 + int average = (totalHeartRate - maxRate - minRate) / (countHeartRate - 2); + + // 打印计算结果 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "去极值后的平均心率: %d (去掉最大值: %d, 去掉最小值: %d)", + average, maxRate, minRate); + + return average; +} +// 显示心率 +int TraingModel::CalculateFilteredHeartRate(int newHeartRate) { + // 将新的心率添加到最近心率列表 + recentHeartRates.push_back(newHeartRate); + + // 如果超过窗口大小,移除最早的心率 + if (recentHeartRates.size() > windowSize) { + recentHeartRates.erase(recentHeartRates.begin()); + } + + // 计算当前窗口中的平均心率 + int total = + std::accumulate(recentHeartRates.begin(), recentHeartRates.end(), 0); + + // 打印当前窗口的平均心率 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "过滤后当前窗口的平均心率: %d", + (total / recentHeartRates.size())); + + return total / recentHeartRates.size(); // 返回计算后的平均值 +} +int TraingModel::Averageheartrate(int newHeartRate) { + heartcount++; + totalHeartRate += newHeartRate; + return totalHeartRate / heartcount; // 返回计算的平均值 +} +// 设置训练目标类型以及训练目标 +void TraingModel::SetSportTag(ExerciseTag tagtpye, int tag) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "tagtpye[%d] tag[%d]", tagtpye, tag); + sportTagType_ = tagtpye; + sportTag_ = tag; +} + +/* 设置训练强度 */ +void TraingModel::SetIntensity(int heart) { + // sportdata->intensity = active_state; +#if 1 + /* + 训练强度 + 220-年龄=最高心率 + + 分为四个强度区间 + 较低强度=最高心率*59%以下 + 中等强度=最高心率*60%~69% + 高等强度=最高心率*70%~79% + 超高强度=最高心率*80%以上 + */ + int age = ConfigModel::GetInstance()->GetUserAge(); + int maxHeartRate = MAX_HEART_RATE - age; + + // 确保最大心率为正值 + if (maxHeartRate <= 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "maxHeartRate %d is error", + maxHeartRate); + return; + } + + // 将 heart 转换为 double 以避免整数除法 + double heartRateAsDouble = static_cast(heart); + double intensityPercentage = (heartRateAsDouble / (double)maxHeartRate) * 100; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, + "heart: %d, maxHeartRate: %d, intensityPercentage: %.2f", heart, + maxHeartRate, intensityPercentage); + + if (intensityPercentage < LOW_INTENSITY_THRESHOLD) { + // 较低强度 + sportdata->intensity = LOW_INTENSITY; + } else if (intensityPercentage >= MEDIUM_INTENSITY_LOWER_THRESHOLD && + intensityPercentage <= MEDIUM_INTENSITY_UPPER_THRESHOLD) { + // 中等强度 + sportdata->intensity = MEDIUM_INTENSITY; + } else if (intensityPercentage >= HIGH_INTENSITY_LOWER_THRESHOLD && + intensityPercentage <= HIGH_INTENSITY_UPPER_THRESHOLD) { + // 高等强度 + sportdata->intensity = HIGH_INTENSITY; + } else { + // 超高强度 + sportdata->intensity = VERY_HIGH_INTENSITY; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, + "maxHeartRate: %d, heartRate: %d, intensityPercentage: %.2f", + maxHeartRate, heart, intensityPercentage); +#endif +} +/*获取训练强度STR*/ +UIResourceTextId TraingModel::GetIntensity() { + switch (sportdata->intensity) { + case LOW_INTENSITY: + return UIResourceTextId::STR_LOWER_STRENGTH; + break; + case MEDIUM_INTENSITY: + return UIResourceTextId::STR_MEDIUM_STRENGTH; + break; + case HIGH_INTENSITY: + return UIResourceTextId::STR_HIGH_STRENGTH; + break; + case VERY_HIGH_INTENSITY: + return UIResourceTextId::STR_ULTRA_HIGH_STRENGTH; + break; + default: + return UIResourceTextId::STR_LOWER_STRENGTH; + break; + } +} +/*获取当前的目标值*/ +int TraingModel::GetSportTagData() { + if (sportdata->tag) { + // 根据设置的训练目标类型去对应相对的数据 + switch (sportdata->sportTagType) { + case ExerciseTag::Duration: + return int(sportdata->duration / 60); // 时间是秒需要转换为目标的分钟 + break; + case ExerciseTag::Calories: + return sportdata->calories; //卡路里是kcal + break; + case ExerciseTag::Distance: + return int(sportdata->distance / 1000); //距离是米需要转换为km + break; + case ExerciseTag::Steps: + return sportdata->steps; //步数是步 + break; + default: + break; + } + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Not set Sport_Tag!"); + return 0; // 添加默认返回值 +} +//获取运动时长 +int TraingModel::GetDuration() { return sportdata->duration; } +/*获取训练类型Id*/ +UIResourceTextId TraingModel::GetSportTypeId(Exercisetype type) { + // 根据设置的训练类型去对应相对的数据 + switch (type) { + // 健身类 + case Exercisetype::FITNESS: + return STR_EXERCISE_LIST; + // 舞蹈类 + case Exercisetype::DANCE: + return STR_DANCING_LIST; + // 休闲运动 + case Exercisetype::LEISURE: + return STR_RECREATIONAL_LIST; + // 球类 + case Exercisetype::BALL: + return STR_BALL_LIST; + // 水上运动 + case Exercisetype::WATER: + return STR_WATER_LIST; + // 冰上运动 + case Exercisetype::ICE: + return STR_ICE_LIST; + // 极限运动 + case Exercisetype::EXTREME: + return STR_EXTREME_LIST; + // 其他 + case Exercisetype::OTHER: + return STR_OTHER_LIST; + default: + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Not ExerciseClass type!"); + break; + } + + return STR_EXERCISE_LIST; // 添加默认返回值[健身类] +} +/*打印存储数据*/ +void TraingModel::printTrainingData(const Trainingdata &data) { + printf("Trainingdata:\n"); + printf("src: %d\n", data.src); + printf("bt: %u\n", data.bt); + printf("ty: %u\n", data.ty); + printf("st: %u\n", data.st); + printf("sp: %u\n", data.sp); + printf("tgt: %u\n", data.tgt); + printf("tg: %u\n", data.tg); + printf("pg: %u\n", data.pg); + printf("du: %u\n", data.du); + printf("ca: %u\n", data.ca); + printf("di: %u\n", data.di); + printf("hr: %u\n", data.hr); + printf("stp: %u\n", data.stp); + printf("ti: %u\n", data.ti); + printf("cir: %u\n", data.cir); + printf("alt: %u\n", data.alt); +} +/*获取训练目标完成百分比*/ +int TraingModel::GetGoaldegree() { + if (sportTag_ == 0) { + return 0; + } + int currentdata = GetSportTagData(); + float completeness = (static_cast(currentdata) / sportdata->tag) * 100; + + return round(completeness); // 四舍五入 +} +/* + uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练 + uint32_t bt; // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4 + - 水上项目,5 - 冰上项目,6 - 极限运动,7 - 其他 uint32_t ty; // + 训练类型:自由训练 uint32_t st; // 开始时间戳(单位:秒) uint32_t sp; // + 结束时间戳(单位:秒) uint32_t tgt; // 训练目标类型:0 - 距离,1 - 卡路里,2 + - 时间,3 - 步数 uint32_t tg; // + 训练目标值:路程(单位:米),卡路里(单位:kcal),时间(单位:分钟),步数(单位:步) + uint32_t pg; // 目标完成度(单位:%) + uint32_t du; // 训练总时长(单位:秒) + uint32_t ca; // 消耗卡路里(单位:kcal) + uint32_t di; // 完成的距离(单位:米) + uint32_t hr; // 平均心率 + uint32_t stp; // 步数 + uint32_t ti; // 训练强度:0 - 较低强度,1 - 中等强度,2 - 高等强度,3 - + 超高强度 uint32_t cir; // 圈数 uint32_t alt; // 最高海拔高度 +*/ +/*保存数据*/ +bool TraingModel::SaveSportData() { + Trainingdata data; + data.src = Openingway; + data.bt = static_cast(sportdata->sportType); + data.ty = static_cast( + GetBleSportId(sportdata->sportType, sportdata->sportId)); + data.st = static_cast(sportdata->starttime); + data.sp = static_cast(sportdata->endtime); + data.tgt = static_cast(sportdata->sportTagType); + data.tg = static_cast(sportdata->tag); + data.pg = static_cast(sportdata->goaldegree); + data.du = static_cast(sportdata->duration); + data.ca = static_cast(sportdata->calories * 10); + data.di = static_cast(sportdata->distance); + data.hr = static_cast(sportdata->avgheart); + data.stp = static_cast(sportdata->steps); + data.ti = static_cast(sportdata->intensity); + /*230目前不支持【圈数】【最高海拔高度】*/ + data.cir = 0; + data.alt = 0; + /*配速相关还未处理 暂时保存0*/ + data.apc = static_cast(sportdata->apc); + data.fpc = static_cast(sportdata->fpc); + data.spc = static_cast(sportdata->spc); + data.std = static_cast(sportdata->std); + data.cdc = static_cast(sportdata->cdc); + + // 保存数据到bin + if (write_Trainingdata_data(data) != 1) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "write_Trainingdata_data is error!"); + // return false; + } + // 保存数据到json + if (SaveDataToJson(sportdata) != true) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDataToJson is error!"); + return false; + } + if (isspecialsport_) { + //保存心率表 + if (SaveHeartTable() != true) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveHeartRateData is error!"); + return false; + } + //保存速度表 + if (SavePaceTable() != true) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSpeedData is error!"); + return false; + } + } + + return true; + // delete data; +} +/*设置进入方式*/ +void TraingModel::SetEntryType(ENTEYTYPE type) { entey_type = type; } +/*获取进入方式*/ +ENTEYTYPE TraingModel::GetEntryType() { return entey_type; } +/*设置开启方式*/ +void TraingModel::SetSportOpenWay(bool way) { Openingway = way; } +/*设置运动是否开始*/ +void TraingModel::SetSportOpenState(bool state) { Openstate = state; } +/*获取运动是否开始*/ +bool TraingModel::GetSportOpenState() { return Openstate; } +/*获取运动时长*/ +uint32_t TraingModel::GetSportTime() { return sportdata->duration; } +/*获取训练量是否达标*/ +bool TraingModel::GetMomentum() { #if 0 int caldata = TraingModel::GetInstance()->GetCal(); /*判断是否产生至少1Kcald的运动量*/ @@ -1261,98 +1090,320 @@ namespace OHOS MomentumFlag = false; } #endif - int duration = sportdata->duration; - //判断运动时间是否大于1分钟 - if (duration >= 60) { - MomentumFlag = true; - } else { - MomentumFlag = false; - } - return MomentumFlag; - } - /*发送实时数据*/ - void TraingModel::SendLiveData() - { - msg_get_train_data_info_t data; - memset(&data, 0, sizeof(msg_get_train_data_info_t)); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->starttime %d \r\n", sportdata->starttime); - data.st = sportdata->starttime; - data.hr = sportdata->heart; - data.ca = sportdata->calories; - data.di = sportdata->distance; - data.stp = sportdata->steps; - data.ti = sportdata->intensity; - data.pc = sportdata->pc; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SendLiveData Begin!"); - sendtraningdata(&data); // 发送数据函数 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SendLiveData Stop!"); - } - /* -------------------------------- 运动识别发起处理 -------------------------------- */ - void TraingModel::set_sport_config(UIResourceTextId id) - { - if (id >= MAXSPORTID) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "id is error"); - return; - } - // 开始训练 ->不返回 - NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGCRAD); - // 配置运动项 - SetSportEvent(id); - // 获取运动项目 - ExerciseClass type = GetSportId(); - // 开启对应的运动 - TraingCardPresenter::GetInstance()->OpenSensor(type); - // 设置为手表开启运动 - SetSportOpenWay(false); - } + int duration = sportdata->duration; + //判断运动时间是否大于1分钟 + if (duration >= 60) { + MomentumFlag = true; + } else { + MomentumFlag = false; + } + return MomentumFlag; +} +/*配速表与心率表相关*/ +//清空心率表 +void TraingModel::ClearHeartTable() { + heartRateTable.clear(); // 清空心率数据表 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Heart Rate Table Cleared.\r\n"); +} +//清空配速表 +void TraingModel::ClearPaceTable() { + paceTable.clear(); // 清空配速数据表 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Pace Table Cleared.\r\n"); +} +// 添加心率数据 +bool TraingModel::AddHeartRateData(uint32_t timestamp, uint16_t heartRate) { + // 检查重复时间戳 + for (const auto &entry : heartRateTable) { + if (entry.timestamp == timestamp) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "时间戳重复无法添加数据 AddHeartRateData is error!"); + return false; // 返回重复 + } + } + + if (heartRateTable.size() >= MAX_ENTRIES) { + WEARABLE_LOGE( + WEARABLE_LOG_MODULE_APP, + "达到最大心率数据条目限制 无法添加新的数据 AddHeartRateData is error!"); + return false; // 返回条目满了 + } + + HeartRateEntry newEntry = {timestamp, heartRate}; + heartRateTable.push_back(newEntry); + return true; // 返回成功 +} + +// 添加配速数据 +bool TraingModel::AddPaceData(uint32_t timestamp, uint16_t pace) { + // 检查重复时间戳 + for (const auto &entry : paceTable) { + if (entry.timestamp == timestamp) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "时间戳重复无法添加数据 AddPaceData is error!"); // 修正这里 + return false; // 返回重复 + } + } + + if (paceTable.size() >= MAX_ENTRIES) { + WEARABLE_LOGE( + WEARABLE_LOG_MODULE_APP, + "达到配速数据条目限制 无法添加新的数据 AddPaceData is error!"); + return false; // 返回条目满了 + } + + PaceEntry newEntry = {timestamp, pace}; + paceTable.push_back(newEntry); + return true; // 返回成功 +} + +// 保存心率表 +bool TraingModel::SaveHeartTable() { + CreateDirectoryIfNotExists(TRAINING_HEART_FILE); + + size_t heartRateCount = heartRateTable.size(); + if (heartRateCount == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "心率表为空,无法保存。"); + return false; + } + + std::string filePath = + TRAINING_HEART_FILE + std::to_string(sportdata->starttime) + ".bin"; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveHeartTable filePath: %s", + filePath.c_str()); + std::ofstream heartRateFile(filePath, std::ios::binary); + if (!heartRateFile) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s", + filePath.c_str()); + return false; // 返回失败 + } + + // 存储表数据 + heartRateFile.write(reinterpret_cast(&heartRateCount), + sizeof(heartRateCount)); + if (!heartRateFile.write( + reinterpret_cast(heartRateTable.data()), + heartRateCount * sizeof(HeartRateEntry))) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入心率数据失败。"); + return false; // 返回失败 + } + + heartRateFile.close(); + + return true; // 返回成功 +} + +// 保存配速表 +bool TraingModel::SavePaceTable() { + CreateDirectoryIfNotExists(TRAINING_PACE_FILE); + + size_t paceCount = paceTable.size(); + if (paceCount == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配速表为空,无法保存。"); + return false; + } + + std::string filePath = + TRAINING_PACE_FILE + std::to_string(sportdata->starttime) + ".bin"; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SavePaceTable filePath: %s", + filePath.c_str()); + std::ofstream paceFile(filePath, std::ios::binary); + if (!paceFile) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s", + filePath.c_str()); + return false; // 返回失败 + } + + paceFile.write(reinterpret_cast(&paceCount), sizeof(paceCount)); + if (!paceFile.write(reinterpret_cast(paceTable.data()), + paceCount * sizeof(PaceEntry))) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入配速数据失败。"); + return false; // 返回失败 + } + + paceFile.close(); + + return true; // 返回成功 +} +// 返回心率表路径 +std::string TraingModel::GetHeartTablePath(uint32_t timestamp) { + // 首先检查完全匹配的时间戳 + std::string exactFilePath = + TRAINING_HEART_FILE + std::to_string(timestamp) + ".bin"; + if (IsFileAccessibleAndNotEmpty(exactFilePath)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到心率表: %s", + exactFilePath.c_str()); + return exactFilePath; // 返回完全匹配的文件路径 + } + + // 如果未找到,检查时间戳相差1到2秒的文件 + for (int i = -2; i <= 2; ++i) { + uint32_t checkTimestamp = timestamp + i; + std::string filePath = + TRAINING_HEART_FILE + std::to_string(checkTimestamp) + ".bin"; + if (IsFileAccessibleAndNotEmpty(filePath)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到心率表: %s", + filePath.c_str()); + return filePath; // 返回找到的文件路径 + } + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的心率表。"); + return ""; // 未找到文件 +} + +// 返回配速表路径 +std::string TraingModel::GetPaceTablePath(uint32_t timestamp) { + // 首先检查完全匹配的时间戳 + std::string exactFilePath = + TRAINING_PACE_FILE + std::to_string(timestamp) + ".bin"; + if (IsFileAccessibleAndNotEmpty(exactFilePath)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到配速表: %s", + exactFilePath.c_str()); + return exactFilePath; // 返回完全匹配的文件路径 + } + + // 如果未找到,检查时间戳相差1到2秒的文件 + for (int i = -2; i <= 2; ++i) { + uint32_t checkTimestamp = timestamp + i; + std::string filePath = + TRAINING_PACE_FILE + std::to_string(checkTimestamp) + ".bin"; + if (IsFileAccessibleAndNotEmpty(filePath)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到配速表: %s", + filePath.c_str()); + return filePath; // 返回找到的文件路径 + } + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的配速表。"); + return ""; // 未找到文件 +} +/*发送实时数据*/ +void TraingModel::SendLiveData() { + msg_get_train_data_info_t data; + memset(&data, 0, sizeof(msg_get_train_data_info_t)); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->starttime %d \r\n", + sportdata->starttime); + data.st = sportdata->starttime; + data.hr = sportdata->heart; + data.ca = sportdata->calories; + data.di = sportdata->distance; + data.stp = sportdata->steps; + data.ti = sportdata->intensity; + data.pc = sportdata->pc; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SendLiveData Begin!"); + sendtraningdata(&data); // 发送数据函数 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SendLiveData Stop!"); +} +/* -------------------------------- 运动识别发起处理 + * -------------------------------- */ +void TraingModel::set_sport_config(UIResourceTextId id) { + if (id >= MAXSPORTID) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "id is error"); + return; + } + // 开始训练 ->不返回 + NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGCRAD); + // 配置运动项 + SetSportEvent(id); + // 获取运动项目 + ExerciseClass type = GetSportId(); + // 开启对应的运动 + TraingCardPresenter::GetInstance()->OpenSensor(type); + // 设置为手表开启运动 + SetSportOpenWay(false); +} /* -------------------------------------------------------------------------- */ #if TIMER - /* 时间显示 */ - std::string TraingModel::DisplayMotionDuration() - { - motionDuration.clear(); +#include +#include +#include +#include - if (g_motionTimes >= NUM_TIME_DAY) - { - g_motionTimes = 0; - } - if (g_motionTimes != 0) - { - sportdata->duration = g_motionTimes; // 训练时长 - /*判断是否开启自动获取*/ - if (ConfigModel::GetInstance()->get_configData_int(ConfigModel::CONFIGMODEL_ITEM_TRANING_AUTO)) - { - freq = ConfigModel::GetInstance()->get_configData_int(ConfigModel::CONFIGMODEL_ITEM_TRANING_FREQ); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "freq is %d\r\n", freq); // 获取实时数据频率 - if (sportdata->duration % freq == 0) - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SendLiveData is OK\r\n"); - SendLiveData(); // 发送实时数据 - } - } - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "duration:[%d] g_motionTimes[%d]\r\n", sportdata->duration, g_motionTimes); - } +std::string TraingModel::DisplayMotionDuration() { + // 清空 motionDuration + motionDuration.clear(); + + // 重置运动次数 + if (g_motionTimes >= NUM_TIME_DAY) { + g_motionTimes = 0; + } + + // 计算和格式化运动时长 + int hours = g_motionTimes / NUM_TIME_HOUR; + int minutes = (g_motionTimes % NUM_TIME_HOUR) / NUM_TIME_MIN; + int seconds = g_motionTimes % NUM_TIME_MIN; + + std::ostringstream oss; + oss << std::setfill('0') << std::setw(2) << hours << ":" << std::setw(2) + << minutes << ":" << std::setw(2) << seconds; + + motionDuration = oss.str(); + + // 获取当前时间(以微秒为单位) + uint32_t currentTime = static_cast( + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count()); + + // 记录和检查上一次调用的时间 + static uint32_t lastCallTime = 0; + if (currentTime - lastCallTime < 1000000) { // 小于1秒 + return motionDuration; + } + lastCallTime = currentTime; // 更新最后调用时间 + + // 如果 g_motionTimes 不为零,进行计算和数据存储 + if (g_motionTimes > 0) { + sportdata->duration = g_motionTimes; // 设置训练时长 + + // 检查并发送实时数据 + SendLiveDataIfNecessary(); + + // 每分钟进行配速和心率数据存储 + StoreDataIfMinutePassed(); + } + + return motionDuration; // 返回格式化的运动时长 +} - int hour = g_motionTimes / NUM_TIME_HOUR; - int min = (g_motionTimes % NUM_TIME_HOUR) / NUM_TIME_MIN; - int sec = (g_motionTimes % NUM_TIME_HOUR) % NUM_TIME_MIN; +// 检查并发送实时数据 +void TraingModel::SendLiveDataIfNecessary() { + // 检查自动获取的配置 + if (ConfigModel::GetInstance()->get_configData_int( + ConfigModel::CONFIGMODEL_ITEM_TRANING_AUTO)) { - std::ostringstream oss; - oss << std::setfill('0') << std::setw(2) << hour << ":" << std::setw(2) << min << ":" << std::setw(2) << sec; + freq = ConfigModel::GetInstance()->get_configData_int( + ConfigModel::CONFIGMODEL_ITEM_TRANING_FREQ); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "freq is %d\r\n", freq); + + // 发送实时数据 + if (sportdata->duration % freq == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SendLiveData is OK\r\n"); + SendLiveData(); // 发送实时数据 + } + } +} - motionDuration = oss.str(); - return motionDuration; +// 每分钟进行配速和心率数据存储 +void TraingModel::StoreDataIfMinutePassed() { + if (sportdata->duration % 60 == 0) { + uint32_t timestamp; + if (uapi_get_timestampe_ss(×tamp) == ERRCODE_SUCC) { + AddHeartRateData(timestamp, sportdata->heart); + AddPaceData(timestamp, sportdata->apc); } + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "duration:[%d] g_motionTimes[%d]\r\n", + sportdata->duration, g_motionTimes); +} #ifdef __cplusplus - extern "C" - { +extern "C" { #endif - /* 定时器回调函数 */ - void TraingTimerCallback() - { - g_motionTimes++; +/* 定时器回调函数 */ +void TraingTimerCallback() { + g_motionTimes++; #if 0 TraingCardPresenter *gTraingCardPresenter = TraingCardPresenter::GetInstance(); if (gTraingCardPresenter == nullptr) @@ -1362,382 +1413,359 @@ namespace OHOS } gTraingCardPresenter->ModifiesTime(); #endif - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingTimerCallback\r\n"); - } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingTimerCallback\r\n"); +} - /* 开启定时器 */ - void InitTimer(void) - { - if (g_startCounting != NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::TraingTimer already exists!!"); - return; - } - g_startCounting = osTimerNew((osTimerFunc_t)TraingTimerCallback, osTimerPeriodic, NULL, NULL); - if (g_startCounting == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::TraingTimer osTimerNew failed!!"); - return; - } - int tick = osMs2Tick(MS_ONE_SECONDS); - osStatus_t retTimer = osTimerStart(g_startCounting, tick); - if (retTimer != osOK) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::TraingTimer osTimerStart failed, ret = %lx!!", retTimer); - if (g_startCounting != NULL) - { - retTimer = osTimerDelete(g_startCounting); - if (retTimer != osOK) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::osTimerDelete failed, ret = %lx!!", retTimer); - return; - } - g_startCounting = NULL; - } - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitTimer!"); - return; - } - } - /* 关闭定时器 */ - void DisableTimer(void) - { - if (g_startCounting != NULL) - { - osTimerStop(g_startCounting); - osStatus_t ret = osTimerDelete(g_startCounting); - if (ret != osOK) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret); - return; - } - g_startCounting = NULL; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "g_motionTimes:%d\r\n", sportdata->duration); - g_motionTimes = 0; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DisableTimer!"); - } - } - /* 暂停定时器 */ - void PauseTimer(void) - { - // 检查定时器是否存在 - if (g_startCounting != NULL) - { - // 暂停定时器,但不删除它 - osStatus_t ret = osTimerStop(g_startCounting); - if (ret != osOK) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopWatch_PauseTimer osTimerStop failed, ret = %lx!!", ret); - } - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PauseTimer!"); - } - } +/* 开启定时器 */ +void InitTimer(void) { + if (g_startCounting != NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "TraingModel::TraingTimer already exists!!"); + return; + } + g_startCounting = osTimerNew((osTimerFunc_t)TraingTimerCallback, + osTimerPeriodic, NULL, NULL); + if (g_startCounting == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "TraingModel::TraingTimer osTimerNew failed!!"); + return; + } + int tick = osMs2Tick(MS_ONE_SECONDS); + osStatus_t retTimer = osTimerStart(g_startCounting, tick); + if (retTimer != osOK) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "TraingModel::TraingTimer osTimerStart failed, ret = %lx!!", + retTimer); + if (g_startCounting != NULL) { + retTimer = osTimerDelete(g_startCounting); + if (retTimer != osOK) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "TraingModel::osTimerDelete failed, ret = %lx!!", + retTimer); + return; + } + g_startCounting = NULL; + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitTimer!"); + return; + } +} +/* 关闭定时器 */ +void DisableTimer(void) { + if (g_startCounting != NULL) { + osTimerStop(g_startCounting); + osStatus_t ret = osTimerDelete(g_startCounting); + if (ret != osOK) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret); + return; + } + g_startCounting = NULL; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "g_motionTimes:%d\r\n", + sportdata->duration); + g_motionTimes = 0; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DisableTimer!"); + } +} +/* 暂停定时器 */ +void PauseTimer(void) { + // 检查定时器是否存在 + if (g_startCounting != NULL) { + // 暂停定时器,但不删除它 + osStatus_t ret = osTimerStop(g_startCounting); + if (ret != osOK) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "StopWatch_PauseTimer osTimerStop failed, ret = %lx!!", + ret); + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PauseTimer!"); + } +} - /*恢复定时器*/ - void ResumeTimer(void) - { - // 检查定时器是否存在 - if (g_startCounting != NULL) - { - int tick = osMs2Tick(MS_ONE_SECONDS); - // 恢复定时器 - osStatus_t ret = osTimerStart(g_startCounting, tick); - if (ret != osOK) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer osTimerStart failed, ret = %lx!!", ret); - } - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer!"); - } - } +/*恢复定时器*/ +void ResumeTimer(void) { + // 检查定时器是否存在 + if (g_startCounting != NULL) { + int tick = osMs2Tick(MS_ONE_SECONDS); + // 恢复定时器 + osStatus_t ret = osTimerStart(g_startCounting, tick); + if (ret != osOK) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "ResumeTimer osTimerStart failed, ret = %lx!!", ret); + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer!"); + } +} #ifdef __cplusplus - } +} #endif #endif - /* ---------------------------------- 数据存储 ---------------------------------- */ - static int32 SaveTraingDataToFile(void) - { - time_t now = time(nullptr); - struct tm *timeinfo = localtime(&now); - char filename[20]; - strftime(filename, sizeof(filename), "%Y%m%d.bin", timeinfo); - - uint32 size = sizeof(Trainingdata); +/* ---------------------------------- 数据存储 + * ---------------------------------- */ +static int32 SaveTraingDataToFile(void) { + time_t now = time(nullptr); + struct tm *timeinfo = localtime(&now); + char filename[20]; + strftime(filename, sizeof(filename), "%Y%m%d.bin", timeinfo); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SaveTraingDataToFile !!"); - - char filePath[20]; - sprintf(filePath, "%s%s", TRAINING_DATA_DIRECTORY, filename); - - std::ofstream fd(filePath, std::ios::binary); - if (!fd.is_open()) - { - if (mkdir(TRAINING_DATA_DIRECTORY, S_IRWXU) != 0) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create directory"); - return 0; - } + uint32 size = sizeof(Trainingdata); - fd.open(filePath, std::ios::binary); - if (!fd.is_open()) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for write"); - return 0; - } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SaveTraingDataToFile !!"); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory created successfully!!"); - } + char filePath[20]; + sprintf(filePath, "%s%s", TRAINING_DATA_DIRECTORY, filename); - fd.write(reinterpret_cast(&sportdata), size); - fd.close(); - return 1; + std::ofstream fd(filePath, std::ios::binary); + if (!fd.is_open()) { + if (mkdir(TRAINING_DATA_DIRECTORY, S_IRWXU) != 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create directory"); + return 0; } - static std::vector LoadTrainingDataFromTodayFile() - { - std::vector trainingRecords; - - time_t now = time(nullptr); - struct tm *timeinfo = localtime(&now); - char filename[20]; - strftime(filename, sizeof(filename), "%Y%m%d.bin", timeinfo); - // 找到训练文件夹里面的当天文件 - char filePath[20]; - sprintf(filePath, "%s%s", TRAINING_DATA_DIRECTORY, filename); - - std::ifstream fd(filePath, std::ios::binary); - if (!fd.is_open()) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open today's file"); - return trainingRecords; // Return an empty vector if file open fails - } - // 读取训练信息 - while (!fd.eof()) - { - Trainingdata record; - fd.read(reinterpret_cast(&record), sizeof(Trainingdata)); - if (fd.gcount() == sizeof(Trainingdata)) - { - trainingRecords.push_back(record); - } - } + fd.open(filePath, std::ios::binary); + if (!fd.is_open()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for write"); + return 0; + } - fd.close(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory created successfully!!"); + } - return trainingRecords; - } + fd.write(reinterpret_cast(&sportdata), size); + fd.close(); + return 1; +} +static std::vector LoadTrainingDataFromTodayFile() { + std::vector trainingRecords; + + time_t now = time(nullptr); + struct tm *timeinfo = localtime(&now); + char filename[20]; + strftime(filename, sizeof(filename), "%Y%m%d.bin", timeinfo); + // 找到训练文件夹里面的当天文件 + char filePath[20]; + sprintf(filePath, "%s%s", TRAINING_DATA_DIRECTORY, filename); + + std::ifstream fd(filePath, std::ios::binary); + if (!fd.is_open()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open today's file"); + return trainingRecords; // Return an empty vector if file open fails + } + + // 读取训练信息 + while (!fd.eof()) { + Trainingdata record; + fd.read(reinterpret_cast(&record), sizeof(Trainingdata)); + if (fd.gcount() == sizeof(Trainingdata)) { + trainingRecords.push_back(record); + } + } + + fd.close(); + + return trainingRecords; +} #ifdef __cplusplus - extern "C" - { +extern "C" { #endif - // 获得数据个数 - static int get_Trainingdata_data_num(FILE *fp) - { - long size = 0; - if (fp != NULL) - { - fseek(fp, 0, SEEK_END); // 将文件指针移动到文件末尾 - size = ftell(fp); // 获取当前文件指针位置,即文件大小 - fseek(fp, 0, SEEK_SET); // 将文件指针移回文件开头 - } - int num = size / sizeof(Trainingdata); - return num; - } - int write_Trainingdata_data(Trainingdata data) - { - char file_path[MAX_FILE_PATH_LENGTH] = {0}; - char timeday[12] = {0}; - uapi_get_YYMMDD_Time(timeday, '_'); - sprintf_s(file_path, sizeof(file_path), "%s%s.bin", TRAINING_PATH, timeday); // 防止越界 - - // Check if the directory exists, if not, create it - struct stat st = {0}; - if (stat(TRAINING_PATH, &st) == -1) - { - mkdir(TRAINING_PATH, 0700); - } - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", file_path); - FILE *fp = fopen(file_path, "ab+"); - if (fp == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for append"); - fp = fopen(file_path, "wb+"); - if (fp == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for write"); - return -1; // Return an error code to indicate file open failure - } - } - - int ret = fwrite((void *)&data, sizeof(Trainingdata), 1, fp); - if (ret != 1) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "fwrite_data error! %d", ret); - fclose(fp); - return -1; // Return an error code on write failure - } - - fclose(fp); // Close the file after writing data - return 1; // Return success code - } - // 读数据 - Trainingdata *read_Trainingdata_data(char *timedata, uint16_t offset) - { - char file_path[128] = {0}; - sprintf_s(file_path, sizeof(file_path), "%s%s.bin", TRAINING_PATH, timedata); // 防止越界 - - FILE *fp = fopen(file_path, "rb+"); - if (fp == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "file is NULL"); - return NULL; - } - Trainingdata *data = (Trainingdata *)malloc(sizeof(Trainingdata)); - if (data == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Trainingdata malloc is error"); - fclose(fp); - return NULL; - } - if (get_Trainingdata_data_num(fp) <= offset) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "file is NULL %d", get_Trainingdata_data_num(fp)); - free(data); // 修复内存泄漏 - fclose(fp); - return NULL; - } - fseek(fp, sizeof(Trainingdata) * offset, SEEK_SET); - fread((void *)data, sizeof(Trainingdata), 1, fp); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%d", data->src); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%d %d ", offset, sizeof(Trainingdata)); - fseek(fp, 0, SEEK_SET); - - fclose(fp); - return data; - } +// 获得数据个数 +static int get_Trainingdata_data_num(FILE *fp) { + long size = 0; + if (fp != NULL) { + fseek(fp, 0, SEEK_END); // 将文件指针移动到文件末尾 + size = ftell(fp); // 获取当前文件指针位置,即文件大小 + fseek(fp, 0, SEEK_SET); // 将文件指针移回文件开头 + } + int num = size / sizeof(Trainingdata); + return num; +} +int write_Trainingdata_data(Trainingdata data) { + char file_path[MAX_FILE_PATH_LENGTH] = {0}; + char timeday[12] = {0}; + uapi_get_YYMMDD_Time(timeday, '_'); + sprintf_s(file_path, sizeof(file_path), "%s%s.bin", TRAINING_PATH, + timeday); // 防止越界 + + // Check if the directory exists, if not, create it + struct stat st = {0}; + if (stat(TRAINING_PATH, &st) == -1) { + mkdir(TRAINING_PATH, 0700); + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", file_path); + FILE *fp = fopen(file_path, "ab+"); + if (fp == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for append"); + fp = fopen(file_path, "wb+"); + if (fp == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for write"); + return -1; // Return an error code to indicate file open failure + } + } + + int ret = fwrite((void *)&data, sizeof(Trainingdata), 1, fp); + if (ret != 1) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "fwrite_data error! %d", ret); + fclose(fp); + return -1; // Return an error code on write failure + } + + fclose(fp); // Close the file after writing data + return 1; // Return success code +} +// 读数据 +Trainingdata *read_Trainingdata_data(char *timedata, uint16_t offset) { + char file_path[128] = {0}; + sprintf_s(file_path, sizeof(file_path), "%s%s.bin", TRAINING_PATH, + timedata); // 防止越界 + + FILE *fp = fopen(file_path, "rb+"); + if (fp == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "file is NULL"); + return NULL; + } + Trainingdata *data = (Trainingdata *)malloc(sizeof(Trainingdata)); + if (data == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Trainingdata malloc is error"); + fclose(fp); + return NULL; + } + if (get_Trainingdata_data_num(fp) <= offset) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "file is NULL %d", + get_Trainingdata_data_num(fp)); + free(data); // 修复内存泄漏 + fclose(fp); + return NULL; + } + fseek(fp, sizeof(Trainingdata) * offset, SEEK_SET); + fread((void *)data, sizeof(Trainingdata), 1, fp); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%d", data->src); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%d %d ", offset, + sizeof(Trainingdata)); + fseek(fp, 0, SEEK_SET); + + fclose(fp); + return data; +} #ifdef __cplusplus - } +} #endif - /* -------------------------------------------------------------------------- */ - /*检查是否存在数据*/ - bool TraingModel::CheckDataJson() - { - // 读取record.json文件 - std::ifstream file(TRAINING_RECORD_FILE); - - // 检查文件是否打开成功 - if (!file.is_open()) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unable to open file"); - return false; - } - - // 检查文件是否为空 - file.seekg(0, std::ios::end); - if (file.tellg() == 0) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File is empty"); - file.close(); - return false; - } - - // 解析json - std::vector sportDataVector; - if(!LoadDataFormJson(sportDataVector)) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDataFormJson is error"); - file.close(); - return false; - } - - // 关闭文件 - file.close(); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckDataJson is ok"); - return true; - } +/* -------------------------------------------------------------------------- */ +/*检查是否存在数据*/ +bool TraingModel::CheckDataJson() { + // 读取record.json文件 + std::ifstream file(TRAINING_RECORD_FILE); + + // 检查文件是否打开成功 + if (!file.is_open()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unable to open file"); + return false; + } + + // 检查文件是否为空 + file.seekg(0, std::ios::end); + if (file.tellg() == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File is empty"); + file.close(); + return false; + } + + // 解析json + std::vector sportDataVector; + if (!LoadDataFormJson(sportDataVector)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDataFormJson is error"); + file.close(); + return false; + } + + // 关闭文件 + file.close(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckDataJson is ok"); + return true; +} #if 1 - bool TraingModel::SaveDataToJson(SportData *data) - { - FILE *fp; - char *jsonStr = NULL; - // 创建sport文件夹 - CreateDirectoryIfNotExists(TRAINING_DATA_DIRECTORY); - - // 读取现有的 JSON 数据 - fp = fopen(TRAINING_RECORD_FILE, "r"); - cJSON *data_root = NULL; - cJSON *dataArray = NULL; - - if (fp != NULL) - { - fseek(fp, 0, SEEK_END); - long fileSize = ftell(fp); - fseek(fp, 0, SEEK_SET); - - jsonStr = (char *)malloc(fileSize + 1); - if (jsonStr != nullptr) - { - if (fread(jsonStr, fileSize, 1, fp) == 1) - { - data_root = cJSON_Parse(jsonStr); - if (data_root != NULL) - { - dataArray = cJSON_GetObjectItem(data_root, "data"); - } - } - } - fclose(fp); - } - - if (dataArray == NULL) - { - data_root = cJSON_CreateObject(); - cJSON_AddItemToObject(data_root, "data", cJSON_CreateArray()); - dataArray = cJSON_GetObjectItem(data_root, "data"); - } - - // 创建或更新数据节点 - cJSON *sportData = cJSON_CreateObject(); - cJSON_AddNumberToObject(sportData, "sportTypeId", int(data->sportType)); // 训练项目类 Id - cJSON_AddNumberToObject(sportData, "sportId", data->sportId); // 训练项目 Id - cJSON_AddStringToObject(sportData, "startDate", (data->start_date).c_str()); // 训练开始日期字符串 - cJSON_AddStringToObject(sportData, "startTime", (data->start_time).c_str()); // 训练开始时间 - cJSON_AddStringToObject(sportData, "endTime", (data->end_time).c_str()); // 训练结束时间 - cJSON_AddNumberToObject(sportData, "goalDegree", data->goaldegree); // 训练目标完成度 - cJSON_AddNumberToObject(sportData, "duration", data->duration); // 训练时长(秒) - cJSON_AddNumberToObject(sportData, "distance", data->distance); // 训练距离 - cJSON_AddNumberToObject(sportData, "avgHeartRate", data->avgheart); // 训练平均心率 - cJSON_AddNumberToObject(sportData, "steps", data->steps); // 训练步数 - cJSON_AddNumberToObject(sportData, "intensity", data->intensity); // 训练强度 - cJSON_AddNumberToObject(sportData, "apc", data->apc); // 训练平均配速 - cJSON_AddNumberToObject(sportData, "cdc", data->cdc); // 训练步频 - cJSON_AddNumberToObject(sportData, "std", data->std); // 训练步幅 - - // 添加运动数据节点到数组并限制数量 - cJSON_AddItemToArray(dataArray, sportData); - while (cJSON_GetArraySize(dataArray) > MAX_DATA_COUNT) - { - cJSON_DeleteItemFromArray(dataArray, 0); - } - - // 将更新后的 JSON 数据写入文件 - char *jsonStrNew = cJSON_Print(data_root); - fp = fopen(TRAINING_RECORD_FILE, "w"); - if (fp != NULL) - { - fwrite(jsonStrNew, strlen(jsonStrNew), 1, fp); - fclose(fp); +bool TraingModel::SaveDataToJson(SportData *data) { + FILE *fp; + char *jsonStr = NULL; + // 创建sport文件夹 + CreateDirectoryIfNotExists(TRAINING_DATA_DIRECTORY); + + // 读取现有的 JSON 数据 + fp = fopen(TRAINING_RECORD_FILE, "r"); + cJSON *data_root = NULL; + cJSON *dataArray = NULL; + + if (fp != NULL) { + fseek(fp, 0, SEEK_END); + long fileSize = ftell(fp); + fseek(fp, 0, SEEK_SET); + + jsonStr = (char *)malloc(fileSize + 1); + if (jsonStr != nullptr) { + if (fread(jsonStr, fileSize, 1, fp) == 1) { + data_root = cJSON_Parse(jsonStr); + if (data_root != NULL) { + dataArray = cJSON_GetObjectItem(data_root, "data"); } - - // 释放资源 - cJSON_Delete(data_root); - free(jsonStr); - cJSON_free(jsonStrNew); - - return true; + } } + fclose(fp); + } + + if (dataArray == NULL) { + data_root = cJSON_CreateObject(); + cJSON_AddItemToObject(data_root, "data", cJSON_CreateArray()); + dataArray = cJSON_GetObjectItem(data_root, "data"); + } + + // 创建或更新数据节点 + cJSON *sportData = cJSON_CreateObject(); + cJSON_AddNumberToObject(sportData, "sportTypeId", + int(data->sportType)); // 训练项目类 Id + cJSON_AddNumberToObject(sportData, "sportId", data->sportId); // 训练项目 Id + cJSON_AddStringToObject(sportData, "startDate", + (data->start_date).c_str()); // 训练开始日期字符串 + cJSON_AddStringToObject(sportData, "startTime", + (data->start_time).c_str()); // 训练开始时间 + cJSON_AddStringToObject(sportData, "endTime", + (data->end_time).c_str()); // 训练结束时间 + cJSON_AddNumberToObject(sportData, "goalDegree", + data->goaldegree); // 训练目标完成度 + cJSON_AddNumberToObject(sportData, "duration", + data->duration); // 训练时长(秒) + cJSON_AddNumberToObject(sportData, "distance", data->distance); // 训练距离 + cJSON_AddNumberToObject(sportData, "avgHeartRate", + data->avgheart); // 训练平均心率 + cJSON_AddNumberToObject(sportData, "steps", data->steps); // 训练步数 + cJSON_AddNumberToObject(sportData, "intensity", data->intensity); // 训练强度 + cJSON_AddNumberToObject(sportData, "apc", data->apc); // 训练平均配速 + cJSON_AddNumberToObject(sportData, "cdc", data->cdc); // 训练步频 + cJSON_AddNumberToObject(sportData, "std", data->std); // 训练步幅 + + // 添加运动数据节点到数组并限制数量 + cJSON_AddItemToArray(dataArray, sportData); + while (cJSON_GetArraySize(dataArray) > MAX_DATA_COUNT) { + cJSON_DeleteItemFromArray(dataArray, 0); + } + + // 将更新后的 JSON 数据写入文件 + char *jsonStrNew = cJSON_Print(data_root); + fp = fopen(TRAINING_RECORD_FILE, "w"); + if (fp != NULL) { + fwrite(jsonStrNew, strlen(jsonStrNew), 1, fp); + fclose(fp); + } + + // 释放资源 + cJSON_Delete(data_root); + free(jsonStr); + cJSON_free(jsonStrNew); + + return true; +} #endif #if 0 bool TraingModel::SaveDataToJson(SportData *data) @@ -1806,141 +1834,148 @@ namespace OHOS return true; } #endif - /* 加载训练数据函数 */ - bool TraingModel::LoadDataFormJson(std::vector& sportDataVector) - { - std::ifstream file(TRAINING_RECORD_FILE); - if (!file.is_open()) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file"); - return false; - } - - std::string jsonData((std::istreambuf_iterator(file)), std::istreambuf_iterator()); - file.close(); - - cJSON *root = cJSON_Parse(jsonData.c_str()); - if (root == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse JSON: %s", cJSON_GetErrorPtr()); - return false; - } - - cJSON *dataArray = cJSON_GetObjectItem(root, "data"); - if (dataArray == NULL ||!cJSON_IsArray(dataArray)) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid or missing 'data' array in JSON"); - cJSON_Delete(root); - return false; - } - - int dataCount = cJSON_GetArraySize(dataArray); - if (dataCount == 0) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "error dataCount is 0"); - cJSON_Delete(root); - return false; - } - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "dataCount is %d", dataCount); - - for (int i = 0; i < dataCount; i++) - { - cJSON *item = cJSON_GetArrayItem(dataArray, i); - if (item == NULL) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid item at index %d", i); - continue; // 跳过无效项目 - } - - SportData sportData; - bool isValid = true; // 用于标记 sportData 是否有效 - - // 检查并获取每个字段,确保其存在且类型正确 - if (cJSON *sportTypeIdItem = cJSON_GetObjectItem(item, "sportTypeId"); sportTypeIdItem && cJSON_IsNumber(sportTypeIdItem)) - sportData.sportType = (Exercisetype)sportTypeIdItem->valueint; - else - isValid = false; - - if (cJSON *sportIdItem = cJSON_GetObjectItem(item, "sportId"); sportIdItem && cJSON_IsNumber(sportIdItem)) - sportData.sportId = (UIResourceTextId)sportIdItem->valueint; - else - isValid = false; - - if (cJSON *startDateItem = cJSON_GetObjectItem(item, "startDate"); startDateItem && cJSON_IsString(startDateItem)) - sportData.start_date = startDateItem->valuestring; - else - isValid = false; - - if (cJSON *startTimeItem = cJSON_GetObjectItem(item, "startTime"); startTimeItem && cJSON_IsString(startTimeItem)) - sportData.start_time = startTimeItem->valuestring; - else - isValid = false; - - if (cJSON *endTimeItem = cJSON_GetObjectItem(item, "endTime"); endTimeItem && cJSON_IsString(endTimeItem)) - sportData.end_time = endTimeItem->valuestring; - else - isValid = false; - - if (cJSON *goalDegreeItem = cJSON_GetObjectItem(item, "goalDegree"); goalDegreeItem && cJSON_IsNumber(goalDegreeItem)) - sportData.goaldegree = goalDegreeItem->valueint; - else - isValid = false; - - if (cJSON *durationItem = cJSON_GetObjectItem(item, "duration"); durationItem && cJSON_IsNumber(durationItem)) - sportData.duration = durationItem->valueint; - else - isValid = false; - - if (cJSON *distanceItem = cJSON_GetObjectItem(item, "distance"); distanceItem && cJSON_IsNumber(distanceItem)) - sportData.distance = distanceItem->valueint; - else - isValid = false; - - if (cJSON *avgHeartRateItem = cJSON_GetObjectItem(item, "avgHeartRate"); avgHeartRateItem && cJSON_IsNumber(avgHeartRateItem)) - sportData.avgheart = avgHeartRateItem->valueint; - else - isValid = false; - - if (cJSON *stepsItem = cJSON_GetObjectItem(item, "steps"); stepsItem && cJSON_IsNumber(stepsItem)) - sportData.steps = stepsItem->valueint; - else - isValid = false; - - if (cJSON *intensityItem = cJSON_GetObjectItem(item, "intensity"); intensityItem && cJSON_IsNumber(intensityItem)) - sportData.intensity = intensityItem->valueint; - else - isValid = false; - - if (cJSON *apcItem = cJSON_GetObjectItem(item, "apc"); apcItem && cJSON_IsNumber(apcItem)) - sportData.apc = apcItem->valueint; - else - isValid = false; - - if (cJSON *cdcItem = cJSON_GetObjectItem(item, "cdc"); cdcItem && cJSON_IsNumber(cdcItem)) - sportData.cdc = cdcItem->valueint; - else - isValid = false; - - if (cJSON *stdItem = cJSON_GetObjectItem(item, "std"); stdItem && cJSON_IsNumber(stdItem)) - sportData.std = stdItem->valueint; - else - isValid = false; - - // 只有在所有字段都有效的情况下才添加 sportData 到向量中 - if (isValid) - { - sportDataVector.push_back(sportData); - } - else - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid data in item %d", i); - } - } - - cJSON_Delete(root); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDataFormJson is ok"); - return true; - } +/* 加载训练数据函数 */ +bool TraingModel::LoadDataFormJson(std::vector &sportDataVector) { + std::ifstream file(TRAINING_RECORD_FILE); + if (!file.is_open()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file"); + return false; + } + + std::string jsonData((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + file.close(); + + cJSON *root = cJSON_Parse(jsonData.c_str()); + if (root == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse JSON: %s", + cJSON_GetErrorPtr()); + return false; + } + + cJSON *dataArray = cJSON_GetObjectItem(root, "data"); + if (dataArray == NULL || !cJSON_IsArray(dataArray)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "Invalid or missing 'data' array in JSON"); + cJSON_Delete(root); + return false; + } + + int dataCount = cJSON_GetArraySize(dataArray); + if (dataCount == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "error dataCount is 0"); + cJSON_Delete(root); + return false; + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "dataCount is %d", dataCount); + + for (int i = 0; i < dataCount; i++) { + cJSON *item = cJSON_GetArrayItem(dataArray, i); + if (item == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid item at index %d", i); + continue; // 跳过无效项目 + } + + SportData sportData; + bool isValid = true; // 用于标记 sportData 是否有效 + + // 检查并获取每个字段,确保其存在且类型正确 + if (cJSON *sportTypeIdItem = cJSON_GetObjectItem(item, "sportTypeId"); + sportTypeIdItem && cJSON_IsNumber(sportTypeIdItem)) + sportData.sportType = (Exercisetype)sportTypeIdItem->valueint; + else + isValid = false; + + if (cJSON *sportIdItem = cJSON_GetObjectItem(item, "sportId"); + sportIdItem && cJSON_IsNumber(sportIdItem)) + sportData.sportId = (UIResourceTextId)sportIdItem->valueint; + else + isValid = false; + + if (cJSON *startDateItem = cJSON_GetObjectItem(item, "startDate"); + startDateItem && cJSON_IsString(startDateItem)) + sportData.start_date = startDateItem->valuestring; + else + isValid = false; + + if (cJSON *startTimeItem = cJSON_GetObjectItem(item, "startTime"); + startTimeItem && cJSON_IsString(startTimeItem)) + sportData.start_time = startTimeItem->valuestring; + else + isValid = false; + + if (cJSON *endTimeItem = cJSON_GetObjectItem(item, "endTime"); + endTimeItem && cJSON_IsString(endTimeItem)) + sportData.end_time = endTimeItem->valuestring; + else + isValid = false; + + if (cJSON *goalDegreeItem = cJSON_GetObjectItem(item, "goalDegree"); + goalDegreeItem && cJSON_IsNumber(goalDegreeItem)) + sportData.goaldegree = goalDegreeItem->valueint; + else + isValid = false; + + if (cJSON *durationItem = cJSON_GetObjectItem(item, "duration"); + durationItem && cJSON_IsNumber(durationItem)) + sportData.duration = durationItem->valueint; + else + isValid = false; + + if (cJSON *distanceItem = cJSON_GetObjectItem(item, "distance"); + distanceItem && cJSON_IsNumber(distanceItem)) + sportData.distance = distanceItem->valueint; + else + isValid = false; + + if (cJSON *avgHeartRateItem = cJSON_GetObjectItem(item, "avgHeartRate"); + avgHeartRateItem && cJSON_IsNumber(avgHeartRateItem)) + sportData.avgheart = avgHeartRateItem->valueint; + else + isValid = false; + + if (cJSON *stepsItem = cJSON_GetObjectItem(item, "steps"); + stepsItem && cJSON_IsNumber(stepsItem)) + sportData.steps = stepsItem->valueint; + else + isValid = false; + + if (cJSON *intensityItem = cJSON_GetObjectItem(item, "intensity"); + intensityItem && cJSON_IsNumber(intensityItem)) + sportData.intensity = intensityItem->valueint; + else + isValid = false; + + if (cJSON *apcItem = cJSON_GetObjectItem(item, "apc"); + apcItem && cJSON_IsNumber(apcItem)) + sportData.apc = apcItem->valueint; + else + isValid = false; + + if (cJSON *cdcItem = cJSON_GetObjectItem(item, "cdc"); + cdcItem && cJSON_IsNumber(cdcItem)) + sportData.cdc = cdcItem->valueint; + else + isValid = false; + + if (cJSON *stdItem = cJSON_GetObjectItem(item, "std"); + stdItem && cJSON_IsNumber(stdItem)) + sportData.std = stdItem->valueint; + else + isValid = false; + + // 只有在所有字段都有效的情况下才添加 sportData 到向量中 + if (isValid) { + sportDataVector.push_back(sportData); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid data in item %d", i); + } + } + + cJSON_Delete(root); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDataFormJson is ok"); + return true; +} -} \ No newline at end of file +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/utilscpp/custom_utilscpp.cpp b/code/sdk/drivers/peripheral/utilscpp/custom_utilscpp.cpp index d69ebce6c..60ef7b4a4 100644 --- a/code/sdk/drivers/peripheral/utilscpp/custom_utilscpp.cpp +++ b/code/sdk/drivers/peripheral/utilscpp/custom_utilscpp.cpp @@ -254,52 +254,56 @@ void uapi_dump_meminfo(void) } -void CustomEventPublish(uint16_t topic, uint8_t *data , uint32_t size) -{ - int32_t ret; - - BroadcastApi *broadcastApi = NULL; - IUnknown *api = NULL; - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish topic=%u!!", topic); +void CustomEventPublish(uint16_t topic, uint8_t *data, uint32_t size) { + int32_t ret; + + BroadcastApi *broadcastApi = NULL; + IUnknown *api = NULL; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish topic=%u!!", topic); + + void *publishData = nullptr; + if (size > 0) { + publishData = malloc(size); + if (publishData == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish malloc failed! size = %u", size); + return; + } + ret = memcpy_s(publishData, size, (const void *)data, size); + if (ret != EOK) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish memcpy_s failed! ret = %d", ret); + free(publishData); + return; + } + } + Request request = {.msgId = topic, .len = size, .msgValue = 0, .data = publishData}; - void *publishData = nullptr; - if (size > 0) - { - publishData = malloc(size); - if (publishData == nullptr) { - return; - } - ret = memcpy_s(publishData, size, (const void *)data, size); - if (ret != EOK) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish memcpy_s rateDataTmp fail! ret = %d", ret); - free(publishData); - return; - } - } + /* public request */ + api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME); + if (api == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetFeatureApi failed for service: %s, feature: %s", BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME); + free(publishData); + return; + } - Request request = {.msgId = topic, .len = size, .msgValue = 0,.data = publishData}; - + ret = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); + if (ret != 0 || broadcastApi == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "QueryInterface failed! ret = %d, api = %p", ret, api); + free(publishData); + return; + } - /* public request */ - api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME); - if (api == NULL) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetFeatureApi failed"); - free(publishData); - return; - } - ret = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); - if (ret != 0 || broadcastApi == NULL) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QueryInterface failed"); - free(publishData); - return; - } - broadcastApi->PublishTopic((IUnknown *)broadcastApi, &request); - broadcastApi->Release((IUnknown *)broadcastApi); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish end!!"); + ret = broadcastApi->PublishTopic((IUnknown *)broadcastApi, &request); + if (ret != 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PublishTopic failed! ret = %d", ret); + } + + broadcastApi->Release((IUnknown *)broadcastApi); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish end!!"); - return; + // 释放内存 + free(publishData); + return; } void custom_set_volume(uint8_t channel,int32_t sounding) -- 2.17.1