From 2a9ffe4675bd3d828342fd131d275109b93e138a Mon Sep 17 00:00:00 2001 From: Caisking <3449750381@qq.com> Date: Wed, 6 Mar 2024 18:24:06 +0800 Subject: [PATCH] =?utf8?q?1.=E4=BC=98=E5=8C=96=E5=BF=83=E7=8E=87=E8=A1=80?= =?utf8?q?=E6=B0=A7=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=98=BE=E7=A4=BA?= =?utf8?q?=EF=BC=9B2.=E6=90=AD=E5=BB=BA=E5=BF=83=E7=8E=87=E6=A3=80?= =?utf8?q?=E6=B5=8B=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../wearable/fd230app/CMakeLists.txt | 1 + .../bloodoxygen/src/BloodOxygenModel.cpp | 90 +++------- .../bloodoxygen/src/BloodOxygenView.cpp | 39 +++-- .../heart_blood/src/BloodCardView.cpp | 36 ++-- .../heartrate/include/HeartBandoffView.h | 38 +++++ .../heartrate/include/HeartCheckView.h | 2 +- .../nativeui/heartrate/include/HeartModel.h | 3 + .../heartrate/include/HeartPresenter.h | 10 +- .../nativeui/heartrate/include/HeartView.h | 28 ++-- .../heartrate/src/HeartBandoffView.cpp | 156 ++++++++++++++++++ .../nativeui/heartrate/src/HeartCheckView.cpp | 2 +- .../nativeui/heartrate/src/HeartModel.cpp | 37 +++-- .../nativeui/heartrate/src/HeartPresenter.cpp | 76 ++++----- .../nativeui/heartrate/src/HeartView.cpp | 30 +++- .../main/include/dial/DialModelSPO2.h | 2 +- .../fd230/fs/user/res/dialupdate/KUMI.bin | Bin 45784 -> 45784 bytes 16 files changed, 376 insertions(+), 174 deletions(-) diff --git a/code/sdk/application/wearable/fd230app/CMakeLists.txt b/code/sdk/application/wearable/fd230app/CMakeLists.txt index 6de55db57..761d9657d 100644 --- a/code/sdk/application/wearable/fd230app/CMakeLists.txt +++ b/code/sdk/application/wearable/fd230app/CMakeLists.txt @@ -199,6 +199,7 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/activity/src/ActivityModel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartRateView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartModel.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartBandoffView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartCheckView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartResultView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartView.cpp diff --git a/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenModel.cpp index 148a07a12..198257f03 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenModel.cpp @@ -1,89 +1,45 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: bloodOxygen view - * Author: - * Create: 2021-08-01 - */ - #include "BloodOxygenModel.h" #include "DialModelSPO2.h" #include "wearable_log.h" #include "BloodOxygenPresenter.h" + namespace OHOS { - BloodOxygenModel::BloodOxygenModel() + BloodOxygenModel::BloodOxygenModel() : OxygenView(false), BandoffView(false), CheckView(false), ResultView(false), CheckStatus(false), SPO2_(DialModelSPO2::GetInstance()->GetSPO2Data()) { - OxygenView = false; - BandoffView = false; - CheckView = false; - ResultView = false; - CheckStatus = false; - // 初始化血氧值 - SPO2_ = DialModelSPO2::GetInstance()->GetSPO2Data(); } - bool BloodOxygenModel::GetBloodOxygenViewStatus(void) - { - return OxygenView; - } + bool BloodOxygenModel::GetBloodOxygenViewStatus() { return OxygenView; } - bool BloodOxygenModel::GetBloodBandoffViewStatus(void) - { - return BandoffView; - } + bool BloodOxygenModel::GetBloodBandoffViewStatus() { return BandoffView; } - bool BloodOxygenModel::GetBloodCheckViewStatus(void) - { - return CheckView; - } + bool BloodOxygenModel::GetBloodCheckViewStatus() { return CheckView; } - void BloodOxygenModel::SetBloodBandoffViewStatus(bool bandoffViewStatus) - { - BandoffView = bandoffViewStatus; - } + void BloodOxygenModel::SetBloodBandoffViewStatus(bool bandoffViewStatus) { BandoffView = bandoffViewStatus; } - void BloodOxygenModel::SetBloodOxygenViewStatus(bool oxygenViewStatus) - { - OxygenView = oxygenViewStatus; - } + void BloodOxygenModel::SetBloodOxygenViewStatus(bool oxygenViewStatus) { OxygenView = oxygenViewStatus; } - void BloodOxygenModel::SetBloodCheckViewStatus(bool checkViewStatus) - { - CheckView = checkViewStatus; - } + void BloodOxygenModel::SetBloodCheckViewStatus(bool checkViewStatus) { CheckView = checkViewStatus; } + + bool BloodOxygenModel::GetCheckStatus() { return CheckStatus; } + + void BloodOxygenModel::SetCheckStatus(bool checkstatus) { CheckStatus = checkstatus; } + + uint16_t BloodOxygenModel::GetSPO2data() { return SPO2_; } + + uint16_t BloodOxygenModel::GetShowSPO2data() { return Show_SPO2_; } - /* -------------------------------------------------------------------------- */ - // 获取检测状态 - bool BloodOxygenModel::GetCheckStatus() - { - return CheckStatus; - } - // 设置检测状态 - void BloodOxygenModel::SetCheckStatus(bool checkstatus) - { - CheckStatus = checkstatus; - } - uint16_t BloodOxygenModel::GetSPO2data() - { - return SPO2_; - } - uint16_t BloodOxygenModel::GetShowSPO2data() - { - return Show_SPO2_; - } void BloodOxygenModel::UpSPO2data(uint16_t spo2) { - // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpSPO2data SPO2:%d->%d", SPO2_, spo2); Show_SPO2_ = spo2; - // 筛选有效信息 if (Show_SPO2_ != 0) { SPO2_ = spo2; } } + uint16_t BloodOxygenModel::GetCheckTime() { - // 第一次进入,默认刚刚测试 if (initstatus) { TIME_ = BloodOxygenPresenter::GetInstance()->GetCurrentTime(); @@ -91,14 +47,12 @@ namespace OHOS } return TIME_; } - void BloodOxygenModel::SetCheckTime(uint16_t time) - { - TIME_ = time; - } - /* -------------------------------------------------------------------------- */ - BloodOxygenModel *BloodOxygenModel::GetInstance(void) + + void BloodOxygenModel::SetCheckTime(uint16_t time) { TIME_ = time; } + + BloodOxygenModel *BloodOxygenModel::GetInstance() { static BloodOxygenModel instance; return &instance; } -} \ No newline at end of file +} diff --git a/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenView.cpp b/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenView.cpp index 22f8c9576..0ec393d28 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenView.cpp @@ -76,16 +76,22 @@ namespace OHOS { // 更新血氧数据 uint16_t spo2_ = BloodOxygenModel::GetInstance()->GetSPO2data(); - if (spo2_ != 97) // 判断是否为默认数据 + if (spo2_ != 0) // 判断是否为默认数据 { + // 更新数据 std::string bloodoxygenStr = std::to_string(spo2_); percent->SetText(bloodoxygenStr.c_str()); + // 更新时间 + uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime(); + uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime(); + std::string TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time) + "检测"; + timeLabel->SetText(TimeStr.c_str()); + } + else + { + percent->SetText("--"); + timeLabel->SetText("暂无检测结果"); } - // 更新时间 - uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime(); - uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime(); - std::string TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time) + "检测"; - timeLabel->SetText(TimeStr.c_str()); } // 初始化标签 @@ -103,8 +109,21 @@ namespace OHOS percent->SetViewId("label2"); // Set style percent->SetStyle(STYLE_TEXT_FONT, PERCENT_FONT_SIZE); uint16_t spo2_ = BloodOxygenModel::GetInstance()->GetSPO2data(); - std::string bloodoxygenStr = std::to_string(spo2_); - percent->SetText(bloodoxygenStr.c_str()); + std::string TimeStr; + if (spo2_ != 0) + { + std::string bloodoxygenStr = std::to_string(spo2_); + percent->SetText(bloodoxygenStr.c_str()); + // 更新时间 + uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime(); + uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime(); + TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time); + } + else + { + percent->SetText("--"); + TimeStr = "暂无测量数据"; + } percent->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); percent->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); percent->SetRollSpeed(0); @@ -121,10 +140,6 @@ namespace OHOS timeLabel->SetViewId("label1"); // Set style timeLabel->SetStyle(STYLE_TEXT_FONT, TIMELABEL_FONT_SIZE); /* -------------------------------------------------------------------------- */ - // 更新时间 - uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime(); - uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime(); - std::string TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time); timeLabel->SetText(TimeStr.c_str()); /* -------------------------------------------------------------------------- */ timeLabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); diff --git a/code/sdk/application/wearable/fd230app/nativeui/heart_blood/src/BloodCardView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heart_blood/src/BloodCardView.cpp index f2d6d526a..c2be257cd 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heart_blood/src/BloodCardView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heart_blood/src/BloodCardView.cpp @@ -62,9 +62,15 @@ namespace OHOS // Set additional property bloodoxygen = BloodOxygenModel::GetInstance()->GetSPO2data(); - // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetSPO2Data %d", bloodoxygen); - std::string bloodoxygenStr = std::to_string(bloodoxygen); - bloodLabel->SetText(bloodoxygenStr.c_str()); + if (bloodoxygen != 0) + { + std::string bloodoxygenStr = std::to_string(bloodoxygen); + bloodLabel->SetText(bloodoxygenStr.c_str()); + } + else + { + bloodLabel->SetText("--"); + } bloodLabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); bloodLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); bloodLabel->SetRollSpeed(0); @@ -73,7 +79,7 @@ namespace OHOS // Add to rootView Add(bloodLabel); - /* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ timeLabel = new UILabel(); if (timeLabel == nullptr) { @@ -81,15 +87,21 @@ namespace OHOS return false; } timeLabel->SetPosition(90, 300); // widget's left position and top position - timeLabel->Resize(280, 100); // widget's width and height - timeLabel->SetViewId("label1"); // Set style + timeLabel->Resize(280, 100); // widget's width and height + timeLabel->SetViewId("label1"); // Set style timeLabel->SetStyle(STYLE_TEXT_FONT, 30); - /* -------------------------------------------------------------------------- */ - // 更新时间 - uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime(); - uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime(); - std::string TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time) +"检测"; - timeLabel->SetText(TimeStr.c_str()); + if (bloodoxygen != 0) + { + // 更新时间 + uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime(); + uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime(); + std::string TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time) + "检测"; + timeLabel->SetText(TimeStr.c_str()); + } + else + { + timeLabel->SetText("暂无测量记录"); + } /* -------------------------------------------------------------------------- */ timeLabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); timeLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartBandoffView.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartBandoffView.h index e69de29bb..060059ee4 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartBandoffView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartBandoffView.h @@ -0,0 +1,38 @@ + + +#ifndef Heart_BANDOFF_VIEW_H +#define Heart_BANDOFF_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_animator.h" +#include "components/ui_button.h" +#include "components/ui_label_button.h" +#include "BaseView.h" +#include "View.h" +#include "ohos_types.h" +#include "components/ui_scroll_view.h" +namespace OHOS +{ + class HeartBandoffView + { + public: + HeartBandoffView(); + virtual ~HeartBandoffView(); + + UIViewGroup *CreateUIViewGroup(); + static HeartBandoffView *GetInstance(void); + UIScrollView *HeartBondoffViewInit(); + UIImageAnimatorView *GetImageAnimator(); + + private: + UILabel *label; + UILabelButton *testButton; + UIScrollView *HeartBandoffScrollView; + UIViewGroup *group; + UIImageView *imageView; + UIImageAnimatorView *imageAnimator; + }; +} + +#endif // 血氧跳转界面 \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartCheckView.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartCheckView.h index 26c62b0fd..3a7379f0b 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartCheckView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartCheckView.h @@ -34,7 +34,7 @@ namespace OHOS UIScrollView *HeartCheckViewInit(); UIImageAnimatorView *GetImageAnimator(); UILabelButton *CreateAndSetUIButton(const char *title); - void UpHeartText(); + void UpShowHeartText(); private: UIImageAnimatorView *imageAnimator; diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h index 59aa389ed..246d0476b 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h @@ -112,9 +112,12 @@ extern "C" bool GetHeartViewStatus(void); bool GetHeartBandoffViewStatus(void); bool GetHeartCheckViewStatus(void); + bool GetHeartResultViewStaus(void); + void SetHeartViewStatus(bool HeartViewStatus); void SetHeartBandoffViewStatus(bool bandoffViewStatus); void SetHeartCheckViewStatus(bool checkViewStatus); + void SetHeartResultViewStatus(bool resultViewStatus); bool GetCheckStatus(); void SetCheckStatus(bool checkstatus); diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartPresenter.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartPresenter.h index 213e4e879..0de763603 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartPresenter.h +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartPresenter.h @@ -21,7 +21,7 @@ namespace OHOS typedef enum { HEARTVIEW = 0, // 血氧视图(slice) - HEARTBANDVIEW, + HEARTBANDVIEW, // 佩戴提醒 HEARTCHECKVIEW, // 检测视图(subView) HEARTRESULT, // 测试失败(subView) MAX_HEARTVIEW, @@ -29,10 +29,10 @@ namespace OHOS class HeartView; class HeartPresenter : public Presenter, - public UIView::OnClickListener, - public RootView::OnKeyActListener, - public ModelListenerSample, - public UIView::OnDragListener + public UIView::OnClickListener, + public RootView::OnKeyActListener, + public ModelListenerSample, + public UIView::OnDragListener { public: HeartPresenter(); diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartView.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartView.h index 0869abbbc..59bf6e80e 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartView.h @@ -26,7 +26,7 @@ namespace OHOS { class HeartPresenter; - //class HeartBandoffView; + class HeartBandoffView; class HeartCheckView; class HeartResultView; class HeartView : public View @@ -40,26 +40,23 @@ namespace OHOS void OnTearDownView() override; void OnStart() override; static HeartView *GetInstance(void); - bool ChangeHeartView(int16_t thisview); // 主视图 - bool ChangeCheckView(int16_t thisview); - bool ChangeResultView(int16_t thisview); + bool ChangeHeartView(int16_t thisview); // 主视图 + bool ChangeBandoffView(int16_t thisview); // 佩戴手表 + bool ChangeCheckView(int16_t thisview); // 检测心率 + bool ChangeResultView(int16_t thisview); // 异常检测(佩戴,心率过高或过低) bool ClickFunc(int16_t interface); void ChangeView(int16_t hideView, int16_t showView); UIScrollView *GetHeartScrollView(int ViewId); - void Upheartdata(); - + void UpHeartText(); // 更新心率结果文本 private: - // 增加图片 - bool InitImageDisplay(void); - // 初始化标签 - bool InitLabel(void); - // 添加label按键 - UILabelButton *CreateAndSetUIButton(const char *title); - // 初始化界面 - bool InitHeartView(void); + bool InitImageDisplay(void); // 初始化背景图片 + bool InitLabel(void); // 初始化标签 + UILabelButton *CreateAndSetUIButton(const char *title); // 添加label按键 + bool InitHeartView(void); // 初始化界面 bool SetOnDragListener(void); + HeartBandoffView *heartbandoff{nullptr}; HeartCheckView *heartcheck{nullptr}; HeartResultView *heartresult{nullptr}; UIScrollView *HeartScrollView[4]{nullptr}; @@ -72,8 +69,7 @@ namespace OHOS UILabelButton *testButton; // 检测按键 const power_display_svr_api_t *display_api = power_display_svr_get_api(); - uint32_t display_time; - uint32_t heart_; + uint32_t display_time; // 获取系统亮屏时间暂存 }; } diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartBandoffView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartBandoffView.cpp index e69de29bb..59af17ed0 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartBandoffView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartBandoffView.cpp @@ -0,0 +1,156 @@ + +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: HeartBandoff view + * Author: + * Create: 2021-08-01 + */ +#include "UiConfig.h" +#include "wearable_log.h" +#include "HeartBandoffView.h" +#include "HeartModel.h" + +namespace OHOS +{ + // 动态显示图片设置 + static constexpr uint16_t IMAGE_SIZE = 96; + static constexpr uint16_t IMAGE_POSITION_Y = 276; + static constexpr uint16_t IMAGE_POSITION_X = 179; + static constexpr uint16_t IMAGEANIMATOERVIEW_SIZE = 24; + static constexpr uint16_t IMAGEANIMATOERVIEW_SPEED = 40; + + // 标签设置 + static constexpr uint16_t LABEL_POSITION_X = 87; + static constexpr uint16_t LABEL_POSITION_Y = 200; + static constexpr uint16_t LABEL_POSITION_WIDTH = 288; + static constexpr uint16_t LABEL_POSITION_HEIGHT = 50; + + // 图片设置 + static constexpr uint16_t IMAGE_ENTER_POSITION_X = 131; + static constexpr uint16_t IMAGE_ENTER_POSITION_Y = 70; + + static constexpr uint16_t TITLE_LABEL_DEFAULT_HEIGHT = 30; + static constexpr uint16_t FONT_DEFAULT_SIZE = 25; + static constexpr uint16_t VIEW_DISTANCE_TO_LEFT_SIDE = 48; + static constexpr uint16_t TEXT_DISTANCE_TO_LEFT_SIDE = 50; + static constexpr uint16_t TEXT_DISTANCE_TO_TOP_SIDE = 11; + + static ImageAnimatorInfo g_imageAnimatorInfo_Time[IMAGEANIMATOERVIEW_SIZE] = { + {PNG_COUNTDOWN_TIME_IMAGE_0, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_1, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_2, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_3, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_4, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_5, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_6, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_7, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_8, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_9, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_10, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_11, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_12, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_13, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_14, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_15, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_16, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_17, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_18, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_19, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_20, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_21, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_22, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + {PNG_COUNTDOWN_TIME_IMAGE_23, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH}, + }; + static HeartBandoffView *g_pMainView = nullptr; + HeartBandoffView::HeartBandoffView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::HeartBandoffView"); + label = nullptr; + imageView = nullptr; + HeartBandoffScrollView = nullptr; + imageAnimator = nullptr; + g_pMainView = this; + } + + HeartBandoffView::~HeartBandoffView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::~HeartBandoffView"); + HeartBandoffScrollView->RemoveAll(); + delete label; + delete imageView; + delete imageAnimator; + label = nullptr; + imageView = nullptr; + delete HeartBandoffScrollView; + HeartBandoffScrollView = nullptr; + imageAnimator = nullptr; + g_pMainView = nullptr; + } + + HeartBandoffView *HeartBandoffView::GetInstance(void) + { + return g_pMainView; + } + + // 返回动画状态 + UIImageAnimatorView *HeartBandoffView::GetImageAnimator() + { + return imageAnimator; + } + + UIScrollView *HeartBandoffView::HeartBondoffViewInit() + { + // 初始化界面 + HeartBandoffScrollView = new UIScrollView(); + if (HeartBandoffScrollView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartBondoffViewInit::HeartBandoffView new fail!"); + // return nullptr; + } + HeartBandoffScrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + HeartBandoffScrollView->SetStyle(STYLE_BACKGROUND_OPA, 0xff); + HeartBandoffScrollView->SetStyle(STYLE_BORDER_RADIUS, 1294); + HeartBandoffScrollView->SetScrollBlankSize(35); + HeartBandoffScrollView->SetReboundSize(50); + HeartBandoffScrollView->SetDirection(1); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::CreateUIViewGroup"); + + // 佩戴title + label = new UILabel(); + if (label == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::new Label fail"); + // return nullptr; + } + label->SetPosition(LABEL_POSITION_X, LABEL_POSITION_Y, LABEL_POSITION_WIDTH, LABEL_POSITION_HEIGHT); + label->SetText("偏紧佩戴,保持静止"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + HeartBandoffScrollView->Add(label); + + // 播放动画 + imageAnimator = new UIImageAnimatorView(); + if (imageAnimator == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::new UIImageAnimatorView fail"); + // return nullptr; + } + imageAnimator->SetImageAnimatorSrc(g_imageAnimatorInfo_Time, IMAGEANIMATOERVIEW_SIZE, IMAGEANIMATOERVIEW_SPEED); + imageAnimator->Start(); + imageAnimator->SetRepeat(false); + HeartBandoffScrollView->Add(imageAnimator); + + // 提醒图片 + imageView = new UIImageView(); + if (imageView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::new UIImageView fail"); + // return nullptr; + } + imageView->SetPosition(IMAGE_ENTER_POSITION_X, IMAGE_ENTER_POSITION_Y); // 30 : offset + imageView->SetSrc(PNG_BLOOD_ICON_ENTER); + HeartBandoffScrollView->Add(imageView); + + return HeartBandoffScrollView; + } +} diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartCheckView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartCheckView.cpp index ab72cc08c..3f44ae496 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartCheckView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartCheckView.cpp @@ -75,7 +75,7 @@ namespace OHOS HeartText = nullptr; g_pMainView = this; } - void HeartCheckView::UpHeartText() + void HeartCheckView::UpShowHeartText() { uint16_t heart_ = HeartModel::GetInstance()->GetShowHeartdata(); // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetHeartData %d", heart_); diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp index 99f61242b..fe9bc7c7f 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp @@ -472,17 +472,17 @@ namespace OHOS } } } - bool HeartModel::GetHeartViewStatus(void) + bool HeartModel::GetHeartViewStatus() { return HeartView; } - bool HeartModel::GetHeartBandoffViewStatus(void) + bool HeartModel::GetHeartBandoffViewStatus() { return BandoffView; } - bool HeartModel::GetHeartCheckViewStatus(void) + bool HeartModel::GetHeartCheckViewStatus() { return CheckView; } @@ -492,9 +492,19 @@ namespace OHOS BandoffView = bandoffViewStatus; } - void HeartModel::SetHeartViewStatus(bool HeartViewStatus) + bool HeartModel::GetHeartResultViewStaus() { - HeartView = HeartViewStatus; + return ResultView; + } + + void HeartModel::SetHeartResultViewStatus(bool resultViewStatus) + { + ResultView = resultViewStatus; + } + + void HeartModel::SetHeartViewStatus(bool heartViewStatus) + { + HeartView = heartViewStatus; } void HeartModel::SetHeartCheckViewStatus(bool checkViewStatus) @@ -502,38 +512,37 @@ namespace OHOS CheckView = checkViewStatus; } - /* -------------------------------------------------------------------------- */ - // 获取检测状态 bool HeartModel::GetCheckStatus() { return CheckStatus; } - // 设置检测状态 - void HeartModel::SetCheckStatus(bool checkstatus) + + void HeartModel::SetCheckStatus(bool checkStatus) { - CheckStatus = checkstatus; + CheckStatus = checkStatus; } + uint16_t HeartModel::GetHeartdata() { return Heart_; } + uint16_t HeartModel::GetShowHeartdata() { return Show_Heart_; } + void HeartModel::UpHeartdata(uint16_t heart) { - // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpHeartdata Heart:%d->%d", Heart_, heart); Show_Heart_ = heart; - // 筛选有效信息 if (Show_Heart_ != 0) { Heart_ = heart; } } + uint16_t HeartModel::GetCheckTime() { - // 第一次进入,默认刚刚测试 if (initstatus) { TIME_ = HeartPresenter::GetInstance()->GetCurrentTime(); @@ -541,9 +550,9 @@ namespace OHOS } return TIME_; } + void HeartModel::SetCheckTime(uint16_t time) { TIME_ = time; } - /* -------------------------------------------------------------------------- */ } diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartPresenter.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartPresenter.cpp index 801111ff5..faa4d4bf3 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartPresenter.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartPresenter.cpp @@ -1,20 +1,10 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: heartOxygen view - * Author: - * Create: 2021-08-01 - */ - #include "HeartPresenter.h" #include "common/task_manager.h" -#include "HeartView.h" -#include "HeartModel.h" -#include "HeartCheckView.h" #include "components/ui_label.h" #include "ChangeSliceListener.h" #include "broadcast_service.h" #include -#include "iostream" +#include #include #include #include @@ -22,17 +12,20 @@ #include "wearable_log.h" #include "cmsis_os.h" #include "securec.h" -#include "broadcast_service.h" #include "graphic_service.h" #include #include #include "ppg_service.h" #include "displaybrightness/include/DisplayBrightnessModel.h" #include "power_display_service.h" -#include "heartrate/include/HeartPresenter.h" + #include "heartrate/include/HeartView.h" +#include "HeartModel.h" +#include "HeartCheckView.h" +#include "HeartBandoffView.h" #define HEARTKEYABLE 0 + namespace OHOS { static HeartPresenter *g_pMainView = nullptr; @@ -40,8 +33,7 @@ namespace OHOS static constexpr uint16_t PROGRESS_VALUE_MIN = 0; static constexpr uint16_t PROGRESS_VALUE_MAX = 10; - /* -------------------------------------------------------------------------- */ - // 获取当前的"时间分" + uint16_t HeartPresenter::GetCurrentTime() { time_t now = time(0); @@ -50,7 +42,7 @@ namespace OHOS uint16_t current_time = tblock->tm_hour * 60 + tblock->tm_min; return current_time; } - // 获取时间差 + std::string HeartPresenter::GetTDOA(uint16_t new_time, uint16_t old_time) { if (new_time == old_time) @@ -78,7 +70,7 @@ namespace OHOS return ss.str(); } } - /* -------------------------------------------------------------------------- */ + HeartPresenter::HeartPresenter() { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartPresenter::new HeartPresenter"); @@ -96,6 +88,7 @@ namespace OHOS #endif g_pMainView = nullptr; } + HeartPresenter *HeartPresenter::GetInstance() { return g_pMainView; @@ -129,27 +122,18 @@ namespace OHOS bool HeartPresenter::CheckPointersValue() { - if (HeartView::GetInstance() == nullptr) - { - return false; - } - -#if 0 - if (HeartBandoffView::GetInstance() == nullptr) - { - return false; - } -#endif - if (HeartModel::GetInstance() == nullptr) + if (HeartView::GetInstance() == nullptr || HeartBandoffView::GetInstance() == nullptr || HeartModel::GetInstance() == nullptr) { return false; } return true; } + bool HeartPresenter::OnDrag(UIView &view, const DragEvent &event) { return true; } + bool HeartPresenter::OnDragEnd(UIView &view, const DragEvent &event) { if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) @@ -167,14 +151,16 @@ namespace OHOS // 主界面点击开始检测 if (strcmp(view.GetViewId(), "checkbegin") == 0) { - //HeartView::GetInstance()->ChangeView(HEARTVIEW, HEARTBANDVIEW); - //HeartModel::GetInstance()->SetHeartBandoffViewStatus(true); - // HeartBandoffView::GetInstance()->GetImageAnimator()->Start(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HEARTVIEW->HEARTBANDVIEW"); + HeartView::GetInstance()->ChangeView(HEARTVIEW, HEARTBANDVIEW); + HeartModel::GetInstance()->SetHeartBandoffViewStatus(true); + HeartBandoffView::GetInstance()->GetImageAnimator()->Start(); return true; } // 从检测界面回到主界面 if (strcmp(view.GetViewId(), "checkstop") == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HEARTCHECKVIEW->HEARTVIEW"); HeartView::GetInstance()->ChangeView(HEARTCHECKVIEW, HEARTVIEW); HeartModel::GetInstance()->SetHeartCheckViewStatus(false); HeartModel::GetInstance()->SetCheckStatus(false); // 关闭检测 @@ -183,6 +169,7 @@ namespace OHOS // 从检测失败界面回到检测界面 if (strcmp(view.GetViewId(), "ReCheck") == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HEARTRESULT->HEARTCHECKVIEW"); HeartView::GetInstance()->ChangeView(HEARTRESULT, HEARTCHECKVIEW); HeartCheckView::GetInstance()->GetImageAnimator()->Start(); // 播放检测界面动画 HeartModel::GetInstance()->SetCheckStatus(true); // 开始检测 @@ -191,6 +178,7 @@ namespace OHOS // 从检测失败界面回到主界面 if (strcmp(view.GetViewId(), "StCheck") == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HEARTRESULT->HEARTVIEW"); HeartView::GetInstance()->ChangeView(HEARTRESULT, HEARTVIEW); HeartModel::GetInstance()->SetCheckStatus(false); // 关闭检测 return true; @@ -220,11 +208,11 @@ namespace OHOS // 当检测状态为开始检测,开始检测 if (HeartModel::GetInstance()->GetCheckStatus() == true) { - HeartCheckView::GetInstance()->UpHeartText(); // 更新 + HeartCheckView::GetInstance()->UpShowHeartText(); // 更新 if (startheart == true) { - // uint8_t md = PPG_SERVICE_CMD_TYPE_DO_Heart_TEST; - // send_ppg_cmd_msg(md); + uint8_t md = PPG_SERVICE_CMD_TYPE_DO_PPG_TEST; + send_ppg_cmd_msg(md); startheart = false; } } @@ -232,11 +220,11 @@ namespace OHOS // 当检测状态为结束检测,结束检测 if (HeartModel::GetInstance()->GetCheckStatus() == false) { - HeartView::GetInstance()->Upheartdata(); // 更新主界面 + HeartView::GetInstance()->UpHeartText(); // 更新主界面 if (startheart == false) { - // uint8_t md = PPG_SERVICE_CMD_TYPE_STOP_Heart_TEST; - // send_ppg_cmd_msg(md); + uint8_t md = PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST; + send_ppg_cmd_msg(md); startheart = true; } } @@ -244,7 +232,7 @@ namespace OHOS void HeartPresenter::ReturnInterface() { -#if 0 + // 佩戴动画播放完毕,前往检测界面 if (HeartModel::GetInstance()->GetHeartBandoffViewStatus() == true) { @@ -259,7 +247,7 @@ namespace OHOS HeartModel::GetInstance()->SetCheckStatus(true); // 开始检测 } } -#endif + // 检测动画播放完毕 if (HeartModel::GetInstance()->GetHeartCheckViewStatus() == true) { @@ -268,19 +256,25 @@ namespace OHOS // 测试失败 if (HeartModel::GetInstance()->GetShowHeartdata() == 0) { + HeartView::GetInstance()->ChangeView(HEARTCHECKVIEW, HEARTRESULT); + HeartModel::GetInstance()->SetHeartResultViewStatus(true); } // 测试成功 else { HeartView::GetInstance()->ChangeView(HEARTCHECKVIEW, HEARTVIEW); } - HeartModel::GetInstance()->SetCheckStatus(false); // 关闭检测 HeartModel::GetInstance()->SetHeartCheckViewStatus(false); + HeartModel::GetInstance()->SetCheckStatus(false); // 关闭检测 } uint16_t time = GetCurrentTime(); HeartModel::GetInstance()->SetCheckTime(time); // 更新时间 } + if (HeartModel::GetInstance()->GetHeartResultViewStaus() == true) + { + HeartModel::GetInstance()->SetCheckStatus(false); // 关闭检测 + } } void HeartPresenter::Notify(void) { diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartView.cpp index 8dcd0e558..d4197111c 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartView.cpp @@ -8,9 +8,11 @@ #include "heartrate/include/HeartView.h" #include "heartrate/include/HeartPresenter.h" #include "HeartModel.h" -#include "HeartPresenter.h" #include "displaybrightness/include/DisplayBrightnessModel.h" #include "power_display_service.h" +#include "HeartBandoffView.h" +#include "HeartCheckView.h" +#include "HeartRateView.h" namespace OHOS { @@ -57,6 +59,8 @@ namespace OHOS delete testButton; delete percent; delete heartcheck; + delete heartbandoff; + delete heartresult; imageViewMain = nullptr; titleLabel = nullptr; @@ -65,6 +69,8 @@ namespace OHOS testButton = nullptr; g_pMainView = nullptr; heartcheck = nullptr; + heartbandoff = nullptr; + heartresult = nullptr; delete HeartScrollView[HEARTVIEW]; HeartScrollView[HEARTVIEW] = nullptr; } @@ -72,11 +78,11 @@ namespace OHOS { return g_pMainView; } - void HeartView::Upheartdata() + void HeartView::UpHeartText() { // 更新血氧数据 uint16_t heart_ = HeartModel::GetInstance()->GetHeartdata(); - if (heart_ != 97) // 判断是否为默认数据 + if (heart_ != 0) // 判断是否为默认数据 { std::string heartStr = std::to_string(heart_); percent->SetText(heartStr.c_str()); @@ -249,6 +255,23 @@ namespace OHOS } return true; } + // 2.跳转到佩戴界面 + bool HeartView::ChangeBandoffView(int16_t thisView) + { + if (HeartScrollView[thisView] == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartOxygenView::ChangeBandoffView"); + heartbandoff = new HeartBandoffView(); + if (heartbandoff == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartOxygenView:: new scrollView[%d] fail", thisView); + return false; + } + HeartScrollView[thisView] = heartbandoff->HeartBondoffViewInit(); + RootView::GetInstance()->Add(HeartScrollView[thisView]); + } + return true; + } // 3.跳转到检测界面 bool HeartView::ChangeCheckView(int16_t thisView) { @@ -302,6 +325,7 @@ namespace OHOS // 2.ViewMapper[] 是一个静态的视图映射数组,将视图ID与MainStopWatchView类中的特定成员函数指针进行了绑定。 static const HeartViewMapper ViewMapper[] = { {HEARTVIEW, &HeartView::ChangeHeartView}, + {HEARTBANDVIEW, &HeartView::ChangeBandoffView}, {HEARTCHECKVIEW, &HeartView::ChangeCheckView}, {HEARTRESULT, &HeartView::ChangeResultView}, }; diff --git a/code/sdk/application/wearable/fd230app/nativeui/main/include/dial/DialModelSPO2.h b/code/sdk/application/wearable/fd230app/nativeui/main/include/dial/DialModelSPO2.h index da9662f2a..54f3cc2b7 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/main/include/dial/DialModelSPO2.h +++ b/code/sdk/application/wearable/fd230app/nativeui/main/include/dial/DialModelSPO2.h @@ -27,7 +27,7 @@ namespace OHOS int GetSPO2Data(); private: - float SPO2_ = 97.0; // 97.0: default SPO2 value as reference + float SPO2_ = 0; // 97.0: default SPO2 value as reference }; } #endif diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/dialupdate/KUMI.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/dialupdate/KUMI.bin index df8ecd7b4b530118f0e7115caf98eb20c8c7f705..5532379ee708a027631b9a3f21aed7ef355b86df 100644 GIT binary patch literal 45784 zcmeHw4O~=Z_W!vrGt9ss!<(X_Tn5m=mz)vbDwBI>P{FjAL08v&8I3J5QzF|eUFQO$ zF=_^6sk!B7nBZzbx~s0W4v?m43fgY=TU|!8@~y-)LEi5F+!-$h{riZe0_7#yeYnqk zo^#Igz2`a4Ip=vUZ~!zx69T26{l`Xubk)@h?kmE50sP*|gik~Y%~Wb~{X#z=W@zlj zjJVOzK*VL~Dm0>u4lm87^9?3e;e6qcwu*-T9k7#~3qAlX!Jc_<)3{z@Svk2Il}|v1 z`RmdBOzONi+efy@hHgNBW6NgKv2(PyDeozOASGn)o3Q-9=WLcZ(_9L)LC}vcI_#g< zBjI3d0GhWm*?Ah!de9 zUVK)KU6PmQFE{XVr^=-y^!K!lzrXJYNhFxvWdb71slpahuLCrj6vP-F=U?nUJA8{F zdVF+%WpD!D^^)ISP&DG37azKZ?>4WGP0BPy=K`A5%pYl(Z?#&D1%(+sydgfZ?>Alx zUt679s@+bri{c*h!r@e`5&{sPq2kb9zcTJNK5ut_-2JE6h$v_Hmy`?jGc)OE)>=&h zgiR=eV^7Vr5>J~lbLnd0y*S8IP$JJ#|G(Gywzc^;6$B`hc6!9R$>jT=G+3<$<-cf` zE%|g1fc)y!%SREPLnUzHcrKUd_5AJ5>(AEik0U^SgMXlt@|V-DMaj0gL7;}-IiHql zKaY#E$5FP*zS#pDG%ML7BgBX9>FeA6euwvcP%*K~g!i&HE04d|5Asdt7Sp2~vl+Di z)Qgh~uC+E^+FSny3dVZyy#>G;1?K2aXotb%ga&@2*C}eBY5z3u087~-$c{}*#raI) z@1DLEC2;fk3-xPwK)O6+wRLT3TFh>1iQ-?hB{}j>bzvxVdgw4oo}MxI?d#J!&95=x z7&y|uq(ynskO#%RKB0pQ&X?vL%<{^b0n50A`JB!6DxVyQ74GThpXlfQoxe5bg~!=| zRKNb}U&j!poYRU~x*(k;fJcFa_P^8PcdvcHeW9@N5(H!Pr~FBpahCv2d-OAF>ZvH? zzkBkV?|Vx22F$`LSWS}O??pdra<+7#crH3)p?{?>iokewG0o@~90wM%;NSZmkmTVJ z;644?+VU_IS-|Nmm5HlEptFgjltuIi8)58SH>-Z?31Oo|-)|MaqJKb{;Kgb#k>(fC zo-*Tl%V8)-2eh|q>38#oNc`W!t0;lC|Gt`|KlOfO;!FqtCpf&Ev^ixxxrj`C$2(i= zA}s_fjpuI#&!$T&#PtE+aRX_YKHWg#`dH_|s{1!D@$329?H@mG4+*5V*!nhw_`6sm z8)}IKKB}WwLVxi7Y5oiY_@66`A97S#ORQpwrF9aCv9JD^s?(G_=1(?J| zfB(t}brL~9HZdJOBhdMe7ve)i2gWk8@Hx6spWH2ao6Cnwp#6by@SGFhF9K*&&YQi0 z1-g3Ag@CR5kyPYoWx(Z67sn?{=3_AE7WCFWPK> zRn%7?e-mou{~{a5yRG84(Vp*u!o>fQ&aR>3J|f@>RVS+(`sWL`TV6M7&y>?w6+*KO z-OsH3;uyLj!| zo?6h*hk(e0T>9E5lRdC^&1(9{N7Zm3k+>F*^NXHgcvl90GK^=Om+m;dXkSq0y|pw1 zK_rxcCw@{E2fPwk5*Vrfwt{EcIN|9FL*2ED%~5c>H$`x4&~veJ?gj-bf2XX^!gwa~n*`bwgQAa?E)7v4s^ zKl=qiC^b)<@Yqv5`WW^{s9vP~vLXqmp8$TJN%ij({mt9wOhsQ;+&@f-(*kH84v#dQ zmG|zj3brqvfqzkiOpxje!k|GJ88_r9mBT4PNXe=jM&!g%2_L1$8ST4hKI2*tu&*22=WNJ+ZB3yl0<)N;TQF7+z9*u76sfO2PeKQa_qoSs zN%Y+<`9vtZ_1G7~o_}dwj zm;a~q;Fr0e>mH(@p9rKVGPOt$h;aG=qawYR)PGCyOGXC-yW%L4KmLO-as{iDo=4vB zx}ooGSDCvMgwS%T7~Xm+Z}Z=S!Y|0r3)=}O+5K_##&N-mr2Zv*-mGj8@#|8DTycAK z>jZsHOds9UM`)71>I)@@yGYO9F8Xh^Ju~WKw2ucvxAa-A-Ct~%p1)i8H79@~FJ z;-ky_{$rXa_1{|Z2vjVgfpI=niSap}P(w5P9+K#5DSk7x0l~1DB>B)QLZ?uklAga^ z{Bb#7y`v6+hHeo-Xdgt=l6~;QoJ^=UzET3q_Ae+!@|_S2CiW9mT;eR z8XBIoDOejg70w+}{oBRQt+vPQyb^DtN9)30$W*F1U5FuJewLv-vE&>f)Kv(VZ+kwd z+y2fWVGyc&2*G$mbUG6!V@L!GYFpTRtMuRQ`fVM*TtOfG+~jk_G#9>Km;ol)2d|xz z>;vJJ>;p-DKZkEFr|)H95Z{-Br~kU{pq@5p=js_2;7Z;nnV{9Wq~}`=zXZ7bexCk; zHtv6$b|{ER>isYf2EeNleYZ;=n^Tt34%Wm5uj=;X;=oFf+HWoXoA=+=@XHmuowFYC zpwZW8AJ|?wowrOMbVT$Q%&kLjO`f@6tR_n0=jZTvv-{{@Lwh5d{?EW3RWBK_zntVg zomDPte9iMEVT{czJ>OQwt2sU9=#?1%*u;B3#)rB5o$^M1)of8ljJJgHUY}()uHVJmcfuZQ&fm?-Z4SRVTU1Q7bwzz_{LZ{l1eBkV_YSS>uYEdq zCJ#KDD6YrmNb9kRs>b=UrT8@vi2u}v4g{=QvI#GIKQ?3$4RfdoPfuE{+Z$SrjuRZ1 z5FC34{%@PpH_gWr@yp`+j(`{do$MeO5{Rrvz9yECWvrhQ{2J+RF@7_dsB~fgut7jW zstU?=djK2}QRz7M@xUfF@4vOnt&Lw!nO20MRM*zLPY9m#*atPM6|XP9?mxiwlrZt4 zTH#(!eJYHRw7s2UQQ+si@&`^8PV;``heK2X=aXroDoK``;ItT`isM@F| zOQiNi?6w8{a;x-2LoY`MfwOYz#gzA1r5e;VCs zL>D4Li;*=$bl*M}tLowP1Ylkb{ex7$t&GR7rRS)^MbF5kcjWlHR4$pzUuv(V_%#&m zQ)x^7YvTi5qC%)j;m%7SM z9{yND;L$fra2dP%6M@38R-7fjHwf6KcY)MYk zxX|CtFwSg#$fHZWl>q>88e$YE<|=+-PvH7EJ=w-&x$~2EUyn!Rdhr;K0Iz)Vowmkb zb9(MHeo;O}bMt1NVqn^j{0H>wlK;RRFM!Ihs{!txQi;Bn;*~>twlO||>kYSk(8Ec? zfOJtM=?OkB#Hg8YeZu|yd{9^N2VEC0@B<jQwRz&bWtn{x<=^6H~dq&FX7i< zUr@l+#U}g#F3hR_Ay(ih=;M(M{#LdZm@AX z27(V1rtVb(_ifjKXSy=A%RspHCj_rxtP{Wi-iTe7p(cOuEdfT0$9k)VwpTT8}VH9+dGrT8_A z@rAjh7cus$gw9$urlj3%gwEd+jI?B=c&$Q2vjncFm0$U#yp5zR`2_ z!n8H)nmK>3_+IKy%GX%Fr9*Ehj25iUYr@7&4{S2n16A2{Li|ZWI4o59jW*%_5=;PL zaj_!WdlRMSTZ)giUO(a)%5v(h>SZroG(u2%?B9GJX{{FZRBD327fLy;gCVOL?1{@|O7^;do4#$|wx(eB|e@ z+b_7zmim+Mdb6^aublR_P%rjJgFm2s@tk7`LGG?t(JwB@JH7Zq8O<<=W%O1M3Y}AG z5C4Ey`?D{M$|Yb~C+_br0bdA$@MS*JJ~~}vjl--7-Dkx>M z_-&5g@IGC7!x>JnLY1&`+N?QfAM~cD$96HD%C6B={qKI%kM)l&yb?rg!1RM&D;x6( zTZ&gnK2rUXcrm^JpC2ep_fs(dW~EZ)l6R;{LbRw{2j?Nadc(eP^(-4L=e-xX@jF|x zzbkIwsipXBnvXAhV~QRV?CcDdp0ac@BwPM5H>Nf~JB#�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 d(#J4(SEu&-=jVH{{S7v=d}O; literal 45784 zcmeHw3tSZC`u{Vtv&*n7?1CsL=ng9>nC7mec`IfXE3iy^dNnf7C=kef@~O%*=av z-tYU&_kEt{eFr!Iil7KVMpM3n9|0*2j;mWvvB((5dmz+qF`FeoEN&VjN<65rU`^IrkhF5?MuC6y9>hc^B zU!`@>9nW?QOqM}z*f4r?faRJz45-RdLEsWWa5Ypcu0RkTwDEe-`pdl=W+1m)=5|zk zHaZN4+%&ikmlGX0@lD?nzv-v#!1XGmc;^mo*Jwh6mop^!i0}ZY!AE1|i9ugt)eOi~ z_>ZL}Vd_;lVa%4xRj;lFpxJ>vOkMs%{Wm}7Z_uGtiC;gz5^mpU!l@-0jb5dK%QfwH zE2#%hKS|@+RQu1h{;3CL4|u%I7c1Hj|C$t>e_$%D^^ZSOvaICv=g%lgxJlb7AiSK~ zcA!86tdaWDSa`hK^>YMR+T5x?+Wth2Rwk?LXVdE?;g_{{qvya zxtJ3aD14mSKv4o3|0Bta=8H~qU)kK7{&ng*++>lDB)Wz3kdFv=|NX>u=|fk_yEx7i z96z#g!NQEF@XsmzcR_7jB2R(25AiB#Dp4Z!&)2&8+L(Q`8@V9(D^J2pLv$uOyZHx& z{39^%A^*62JabDXMLP<$m9m4!%^MfJpTQwsfxPfbWIGpPlOE#r_V9YU@^aysIeAdy z!ZS%d#Isx8lGG)6N_nnj5dD}|tJLNlKUs}enTN<%#qp*|qaa~zJG3>S}LDyY%-(s)Ys->-R7>z`-Mg>Syp0iV}b!zv8f=_C-E z;Q%sElt`G=f0uk3VZ0vJFCkAH0kqd``WrAzdzpJYGz_<-Mc9RCZDrz~5o1R!+;~xv zm-N*AmghVZ(4M0LZ>QEDb_hc5jDMd$k}?h$_yP5e>o&Px1Qz@$&``38*dca%1E!k&)VIV(DqLZ&~c@3TCx>NMQc3S0Q1tZ1|ySRRq zR9{oYFUt42zo%6z*eM9+^s|fi1T985=y^H?R!i;2F~C$a9~&xfj`2~25sFx-Otd;= zp^#7I5Jd}2e2E|aSyqy3*yLkiN(C*8f2TxRt)^X2>XDYxPv>_sIy85AiaDmj aZ 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 -- 2.17.1