增加血压Slice;UI待更新 1805/1 1805/head 1817/target/1
authorCaisking <Casiking@zhihuishixun.com>
Tue, 3 Jun 2025 10:55:03 +0000 (18:55 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Tue, 3 Jun 2025 10:55:03 +0000 (18:55 +0800)
15 files changed:
code/sdk/application/wearable/fd230/nativeapp/CMakeLists.txt
code/sdk/application/wearable/fd230/nativeapp/nativelauncher/include/AppViewIDs.h
code/sdk/application/wearable/fd230/nativeapp/nativelauncher/include/NativeLauncher.h
code/sdk/application/wearable/fd230/nativeapp/nativelauncher/src/NativeLauncher.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPDetectionPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPDetectionView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPMainView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPModel.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPDetectionPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPDetectionView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPMainView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPModel.cpp [new file with mode: 0644]
tools/image_converter_tool/test/w9/BP/bg.png [new file with mode: 0644]

index 5d37a82..3b4273e 100644 (file)
@@ -26,6 +26,7 @@ set(PRIVATE_HEADER
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/main/include
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/clock/include
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodoxygen/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodpressure/include
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bluetooth/include
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/indoorwalk/include
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/activity/include
@@ -228,6 +229,13 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodoxygen/src/BloodDetectionView.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodoxygen/src/BloodDetectionPresenter.cpp
 
+    #BloodPressure
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodpressure/src/BPMainView.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodpressure/src/BPMainPresenter.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodpressure/src/BPModel.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodpressure/src/BPDetectionView.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodpressure/src/BPDetectionPresenter.cpp
+
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bluetooth/src/BluetoothDeviceCaseListAdapter.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bluetooth/src/BluetoothDeviceListView.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bluetooth/src/BluetoothPresenter.cpp
index 586dc5a..4d12f5b 100644 (file)
@@ -91,6 +91,7 @@ typedef enum : uint16_t
     VIEW_SET_DIAL,       // 切换表盘
     VIEW_SET_HEART,      // 设置心率周期检测
     VIEW_CODED_LOCK,     // 密码锁
+    VIEW_BLOOD_PRESSURE, // 血压监测
     /* ----------------------------------- 训练 ----------------------------------- */
     VIEW_TRAINING,        // 训练
     VIEW_TRAININGNOMAL,   // 正常训练开始界面(除骑行,健走,跑步外)
index c6eb0cc..92e808e 100644 (file)
@@ -74,6 +74,7 @@ namespace OHOS
         /* --------------------------------界面------------------------------------ */
         void InitRotateSlice(void);
         void InitBloodSlice(void);
+        void InitBloodPressureSlice(void);
         void InitCheckAbnormalSlice(void);
         void InitCheckInvalidSlice(void);
         void InitHeartResultSlice(void);
index 1c8729d..9459599 100644 (file)
 #include "bloodoxygen/include/BloodDetectionPresenter.h"
 #include "bloodoxygen/include/BloodResultView.h"
 #include "bloodoxygen/include/BloodResultPresenter.h"
+/*血压检测*/
+#include "bloodpressure/include/BPMainView.h"
+#include "bloodpressure/include/BPMainPresenter.h"
 /*心率监测*/
 #include "heartrate/include/HeartDetectionView.h"
 #include "heartrate/include/HeartDetectionPresenter.h"
@@ -445,6 +448,8 @@ namespace OHOS
         /*血氧检测*/
         {VIEW_BLOOD_CHECK, &NativeLauncher::InitBloodCheckSlice},
         {VIEW_BLOOD_RESULT, &NativeLauncher::InitBloodResultSlice},
+        /*血压检测*/
+        {VIEW_BLOOD_PRESSURE, &NativeLauncher::InitBloodPressureSlice},
         /*心率检测*/
         {VIEW_HEART_CHECK, &NativeLauncher::InitHeartCheckSlice},
         {VIEW_HEART_RESULT, &NativeLauncher::InitHeartResultSlice},
@@ -1322,6 +1327,18 @@ namespace OHOS
         }
         NativeAbility::GetInstance().AddSliceProxy(VIEW_BLOOD_RESULT, bloodResultView);
     }
+    // 血压监测界面
+    void NativeLauncher::InitBloodPressureSlice(void)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NativeLauncher::InitBloodPressureSlice");
+        SliceProxy *bloodPressureView = new AbilitySliceProxy<BPMainView, BPMainPresenter>;
+        if (bloodPressureView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "bloodPressureView is nullptr");
+            return;
+        }
+        NativeAbility::GetInstance().AddSliceProxy(VIEW_BLOOD_PRESSURE, bloodPressureView);
+    }
     // 心率监测界面
     void NativeLauncher::InitHeartCheckSlice(void)
     {
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPDetectionPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPDetectionPresenter.h
new file mode 100644 (file)
index 0000000..79281ef
--- /dev/null
@@ -0,0 +1,59 @@
+/***
+ * @Date: 2024-07-29 15:33:59
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-29 16:28:08
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPDetectionPresenter.h
+ */
+
+#ifndef BP_DETECTION_PRESENTER_H
+#define BP_DETECTION_PRESENTER_H
+
+#include "Presenter.h"
+#include "components/ui_list.h"
+#include "components/ui_view.h"
+#include "KeyInputListener.h"
+#include "ModelListenerSample.h"
+#include "bloodpressure/include/BPDetectionView.h"
+#include "power_display_service.h"
+
+#define BP_KEEP_TIME 60000 // 60s
+
+namespace OHOS
+{
+
+    class BPDetectionView;
+    class BPDetectionPresenter : public Presenter<BPDetectionView>,
+                                    public ModelListenerSample,
+                                    public UIView::OnClickListener,
+                                    public UIView::OnDragListener,
+                                    public RootView::OnKeyActListener,
+                                    public ListScrollListener
+    {
+    public:
+        BPDetectionPresenter();
+        ~BPDetectionPresenter() override;
+        static BPDetectionPresenter *GetInstance(void);
+
+        void OnStart() override;
+        void OnResume() override;
+        void OnStop() override;
+        void OnTickEvent() override;
+        void Notify() override {}
+        bool OnClick(UIView &view, const ClickEvent &event) override;
+        bool OnDrag(UIView &view, const DragEvent &event) override;
+        bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
+
+        void NavigateBack(void);
+
+    private:
+        void ResetTickTimer(void);
+        uint64_t startTime{0};
+        bool BPCountEvent{false};
+        bool BPCheckState{false};
+
+        const power_display_svr_api_t *display_api = power_display_svr_get_api();
+        uint32_t display_time;
+    };
+}
+
+#endif // BP_DETECTION_PRESENTER_H
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPDetectionView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPDetectionView.h
new file mode 100644 (file)
index 0000000..5003f28
--- /dev/null
@@ -0,0 +1,65 @@
+/***
+ * @Date: 2024-07-29 15:38:56
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-29 15:42:12
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPDetectionView.cpp
+ */
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: bloodDetection view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#ifndef BP_Detection_VIEW_H
+#define BP_Detection_VIEW_H
+
+#include "View.h"
+#include "BaseView.h"
+#include "wearable_log.h"
+#include "UiConfig.h"
+#include "components/ui_label.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_label_button.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_circle_progress.h"
+#include "components/ui_view_group.h"
+
+
+#include "bloodpressure/include/BPDetectionPresenter.h"
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_button_ext.h"
+
+#include "power_display_service.h"
+
+#define STOPCHECK "stop_check"
+namespace OHOS
+{
+    class BPDetectionView : public View<BPDetectionPresenter>
+    {
+    public:
+        BPDetectionView();
+        virtual ~BPDetectionView();
+        void OnStop() override;
+        void OnSetUpView() override;
+        void OnTearDownView() override;
+        void OnStart() override;
+        static BPDetectionView *GetInstance(void);
+
+        bool BPDetectionViewInit();
+        UIImageAnimatorView *GetImageAnimator(void);
+        void UpShowBPText(void);
+
+    private:
+        UIImageAnimatorView *imageAnimator{nullptr};
+        UILabelExt *titleLabel{nullptr};
+        UILabel *Spo2Text{nullptr};
+        UILabelButtonExt *testButton{nullptr};
+
+        uint32_t spo2_;
+    };
+}
+
+#endif // 血氧主界面
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h
new file mode 100644 (file)
index 0000000..90e5a44
--- /dev/null
@@ -0,0 +1,44 @@
+
+
+#ifndef BP_RESULT_PRESENTER_H
+#define BP_RESULT_PRESENTER_H
+
+#include "Presenter.h"
+#include "ModelListenerSample.h"
+#include "components/ui_circle_progress.h"
+#include "ohos_types.h"
+#include "KeyInputListener.h"
+#include "common/key_code.h"
+#include "bloodpressure/include/BPMainView.h"
+
+namespace OHOS
+{
+    static constexpr const char *CLICK_BP = "clickblood"; // 血氧检测
+
+    class BPMainView;
+    class BPMainPresenter : public Presenter<BPMainView>,
+                                 public UIView::OnClickListener,
+                                 public RootView::OnKeyActListener,
+                                 public UIView::OnDragListener
+    {
+    public:
+        BPMainPresenter();
+        virtual ~BPMainPresenter();
+        static BPMainPresenter *GetInstance(void);
+
+        void OnStart() override;
+        void OnPause() override;
+        void OnResume() override;
+        void OnStop() override;
+
+        bool OnDrag(UIView &view, const DragEvent &event) override;
+        bool OnDragEnd(UIView &view, const DragEvent &event) override;
+        bool OnClick(UIView &view, const ClickEvent &event) override;
+        bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
+
+        uint32_t GetCurrentTime();
+        int GetTDOA(uint32_t new_time, uint32_t old_time);
+    };
+}
+
+#endif
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPMainView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPMainView.h
new file mode 100644 (file)
index 0000000..e6b3667
--- /dev/null
@@ -0,0 +1,53 @@
+
+
+#ifndef BP_MAIN_VIEW_H
+#define BP_MAIN_VIEW_H
+
+#include "View.h"
+#include "BaseView.h"
+#include "wearable_log.h"
+#include "UiConfig.h"
+#include "components/ui_label.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_label_button.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_circle_progress.h"
+#include "components/ui_view_group.h"
+#include "bloodpressure/include/BPMainPresenter.h"
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_button_ext.h"
+namespace OHOS
+{
+    class BPMainPresenter;
+    class BPMainView : public View<BPMainPresenter>
+    {
+    public:
+        BPMainView();
+        virtual ~BPMainView();
+        static BPMainView *GetInstance(void);
+
+        void OnStop() override;
+        void OnSetUpView() override;
+        void OnTearDownView() override;
+        void OnStart() override;
+
+        bool BPMainViewInit();
+        void UpSPO2Text(void);
+
+        void DeInit();
+        bool AddButton();
+        bool InitLable();
+        bool Initbackground();
+
+    private:
+        UIImageView *background = nullptr;
+        UILabelExt *titleLabel = nullptr;
+        UILabelExt *timeLabel = nullptr;
+        UILabel *bloodLabel = nullptr;
+        UILabelButtonExt *checkButton{nullptr};
+    };
+}
+
+#endif // 血氧主界面
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPModel.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPModel.h
new file mode 100644 (file)
index 0000000..5f0f910
--- /dev/null
@@ -0,0 +1,81 @@
+/*** 
+ * @Date: 2024-04-15 10:55:58
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-09-05 14:58:21
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPModel.h
+ */
+/***
+ * @Date: 2024-04-15 10:55:58
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-31 10:38:26
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/include/BPModel.h
+ */
+
+#ifndef BP_MODEL_H
+#define BP_MODEL_H
+
+#include <stdint.h>
+#include <string>
+
+namespace OHOS
+{
+    // 血氧检测状态
+    enum class BPState
+    {
+        End = 0,
+        Start,
+    };
+    enum class BPMain
+    {
+        NOT_TESTED = 0, // 未检测
+        SUCCESS,        // 检测成功
+        NOT_WORN,       // 未佩戴检测
+        TIMEOUT,        // 检测超时
+        HIGH_RESULT,    // 检测结果过高
+        LOW_RESULT,     // 检测结果过低
+        INVALID_DATA    // 无效数据
+    };
+    class BPModel
+    {
+    public:
+        BPModel();
+        ~BPModel();
+        static BPModel *GetInstance();
+
+        void UpSPO2data(uint8_t spo2);
+        uint16_t GetSPO2data();
+        uint16_t GetShowSPO2data();
+
+        uint32_t GetCheckTime();
+        void SetCheckTime(uint32_t time);
+        void SetWearStatus(int32_t wear);
+        void SetMain(BPMain result);
+        BPMain GetMain();
+
+        void BP_Stop(void);
+        void BP_Start(void);
+        void BP_Save(void);
+        void BP_Main(void);
+
+        void BP_Control(BPState state);
+        void ClearDisplayData();
+        void CleanAllData();
+
+    private:
+        uint16_t displayspo2;
+        uint16_t currentspo2;
+        uint32_t timestamp_ms;
+        int32_t wear_;
+
+        bool sensorstate{false};
+        bool startspo2{false};
+
+        uint16_t unwear_counter_;                           // 无效佩戴计数器
+        uint16_t valid_counter_;                            // 有效数计数器
+        uint16_t disvalid_counter_;                         // 无效数计数器
+        BPMain bloodresult_ = BPMain::NOT_TESTED; // 检测结果
+        bool initstatus;
+    };
+}
+
+#endif
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPDetectionPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPDetectionPresenter.cpp
new file mode 100644 (file)
index 0000000..1dcca00
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: BPDetectionPresenter.cpp
+ * Author:
+ * Create: 2021-11-23
+ */
+
+#include "bloodpressure/include/BPDetectionView.h"
+#include "bloodpressure/include/BPDetectionPresenter.h"
+
+#include "AppViewIDs.h"
+#include "NativeAbility.h"
+#include "common/key_code.h"
+#include "KeyInputListener.h"
+#include "custom_utils.h"
+#include "displaybrightness/include/DisplayBrightnessModel.h"
+#include "bloodpressure/include/BPModel.h"
+#include "MainModel.h"
+
+namespace OHOS
+{
+
+    // 当前Presenter属性实例化的内存指针
+    static BPDetectionPresenter *g_pBPDetectionPresenter = nullptr;
+
+    BPDetectionPresenter::BPDetectionPresenter()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPDetectionPresenter::BPDetectionPresenter");
+        g_pBPDetectionPresenter = this;
+
+        // display_api->set_screen_set_keepon_timeout(-1); // 设置常亮
+        ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+        ResetTickTimer();
+    }
+
+    BPDetectionPresenter::~BPDetectionPresenter()
+    {
+        // display_api->set_screen_set_keepon_timeout(0); // 恢复
+        ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
+        g_pBPDetectionPresenter = nullptr;
+    }
+    BPDetectionPresenter *BPDetectionPresenter::GetInstance()
+    {
+        return g_pBPDetectionPresenter;
+    }
+    void BPDetectionPresenter::NavigateBack()
+    {
+        NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+    }
+    void BPDetectionPresenter::OnStart()
+    {
+        Presenter<BPDetectionView>::OnStart();
+        if (!BPCheckState)
+        {
+            BPModel::GetInstance()->BP_Start();
+            BPCheckState = true;
+        }
+    }
+    void BPDetectionPresenter::OnResume(void)
+    {
+    }
+
+    void BPDetectionPresenter::OnStop(void)
+    {
+        if (BPCheckState)
+        {
+            BPModel::GetInstance()->BP_Stop();
+            BPCheckState = false;
+        }
+    }
+
+    bool BPDetectionPresenter::OnDrag(UIView &view, const DragEvent &event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPDetectionPresenter::OnDrag");
+        UNUSED(view);
+        if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) &&
+            (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY()))))
+        {
+            NavigateBack();
+        }
+        return true;
+    }
+
+    bool BPDetectionPresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        if (strcmp(view.GetViewId(), STOPCHECK) == 0)
+        {
+            NavigateBack();
+        }
+        return true;
+    }
+
+    void BPDetectionPresenter::OnTickEvent()
+    {
+        // 更新显示血氧数据
+        // BPDetectionView::GetInstance()->UpShowBPText(); 屏蔽动态显示实时数据
+        uint64_t current_time = osKernelGetTick2ms();
+        if ((startTime != 0) && (current_time - startTime >= BP_KEEP_TIME))
+        {
+            // 超时处理
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 超时处理 BP_KEEP_TIME: %lld", current_time - startTime);
+            BPModel::GetInstance()->SetMain(BPMain::TIMEOUT);
+            BPModel::GetInstance()->BP_Stop();
+        }
+    }
+    void BPDetectionPresenter::ResetTickTimer(void)
+    {
+        startTime = osKernelGetTick2ms();
+    }
+    // 增加按键事件
+    bool BPDetectionPresenter::OnKeyAct(UIView &view, const KeyEvent &event)
+    {
+        unsigned short keyID = event.GetKeyId();
+        unsigned short keyState = event.GetState();
+        // 如果是power键,且是亮屏状态,按键释放就返回上一级
+        if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 1 && uapi_get_screen_state() == 0)
+        {
+            NavigateBack();
+        }
+        return true;
+    }
+}
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPDetectionView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPDetectionView.cpp
new file mode 100644 (file)
index 0000000..8696302
--- /dev/null
@@ -0,0 +1,201 @@
+/***
+ * @Date: 2024-04-15 10:55:58
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-29 15:35:06
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPDetectionView.cpp
+ */
+#include "UiConfig.h"
+#include "wearable_log.h"
+#include "BPDetectionView.h"
+#include "BPModel.h"
+#include "ui_image_animator.h"
+#include "BPDetectionView.h"
+#include "ui_resource_string.h"
+#include "power_display_service.h"
+#include "uicomponents/UIComponents.h"
+namespace OHOS
+{
+    // 动态刷新设置
+    static constexpr uint16_t IMAGE_SIZE = 180;
+    static constexpr uint16_t IMAGE_POSITION_Y = 143;
+    static constexpr uint16_t IMAGE_POSITION_X = 143;
+    static constexpr uint16_t DETECTION_IMAGE_ANIMATORVIEW_SIZE = 30;
+    static constexpr uint16_t DETECTION_IMAGE_ANIMATORVIEW_SPEED = 40;
+
+    static ImageAnimatorInfo g_imageAnimatorInfo_blood[30] = {
+    {PNG_CHECK_TIME_IMAGE_0, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_1, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_2, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_3, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_4, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_5, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_6, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_7, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_8, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_9, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_10, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_11, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_12, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_13, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_14, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_15, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_16, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_17, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_18, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_19, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_20, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_21, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_22, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_23, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_24, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_25, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_26, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_27, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_28, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    {PNG_CHECK_TIME_IMAGE_29, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    };
+
+    static BPDetectionView *g_pBPCheckView = nullptr;
+    BPDetectionView::BPDetectionView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPBandoffView::BPBandoffView");
+        g_pBPCheckView = this;
+    }
+    BPDetectionView::~BPDetectionView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPDetectionView::~BPDetectionView");
+        if(container_)
+            container_->RemoveAll();
+        if(titleLabel)
+        {
+            delete titleLabel;
+            titleLabel = nullptr;
+        }
+        if(testButton)
+        {
+            delete testButton;
+            testButton = nullptr;
+        }
+        if(imageAnimator)
+        {
+            imageAnimator->Stop();
+            delete imageAnimator;
+            imageAnimator = nullptr;   
+        }
+        if(Spo2Text)
+        {
+            delete Spo2Text;
+            Spo2Text = nullptr;  
+        }
+        g_pBPCheckView = nullptr;
+    }
+    BPDetectionView *BPDetectionView::GetInstance(void)
+    {
+        return g_pBPCheckView;
+    }
+    UIImageAnimatorView *BPDetectionView::GetImageAnimator()
+    {
+        return imageAnimator;
+    }
+
+    /*更新显示数据*/
+    void BPDetectionView::UpShowBPText()
+    {
+        uint16_t spo2_ = BPModel::GetInstance()->GetShowSPO2data();
+        std::string bloodpressureStr = std::to_string(spo2_);
+        if (Spo2Text != nullptr)
+            Spo2Text->SetText(bloodpressureStr.c_str());
+    }
+    /*初始化检测界面*/
+    bool BPDetectionView::BPDetectionViewInit()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPDetectionViewInit is begin");
+        /*初始化title*/
+        InitLabelExt(titleLabel, 83, 50, 300, 35, "title", STR_CHECKON, DEFAULT_VECTOR_FONT_FILENAME, 30);
+        container_->Add(titleLabel);
+
+        /* -------------------------------------------------------------------------- */
+        imageAnimator = new UIImageAnimatorView();
+        if (imageAnimator == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPBandoffView::new UIImageAnimatorView fail");
+            return false;
+        }
+        imageAnimator->SetImageAnimatorSrc(g_imageAnimatorInfo_blood, DETECTION_IMAGE_ANIMATORVIEW_SIZE, DETECTION_IMAGE_ANIMATORVIEW_SPEED);
+        imageAnimator->SetRepeat(true);
+        container_->Add(imageAnimator);
+
+        /* -------------------------------------------------------------------------- */
+        /*初始化血氧值label*/
+        // InitUILabel(Spo2Text, 83, 83, 300, 300, "bloodtext", "--", GILROY_BOLD_FONT, 140);
+        // container_->Add(Spo2Text);
+
+        /* -------------------------------------------------------------------------- */
+        InitButtonExt(testButton, 93, 330, 280, 90, STOPCHECK, STR_CHECKSTOP, 30);
+        container_->Add(testButton);
+
+        /* -------------------------------------------------------------------------- */
+        UIView::OnClickListener *clickLeftListener = (UIView::OnClickListener *)OHOS::BPDetectionPresenter::GetInstance();
+        if (clickLeftListener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPDetectionView::new clickLeftListener fail");
+            return false;
+        }
+        testButton->SetOnClickListener(clickLeftListener);
+        /* -------------------------------------------------------------------------- */
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPDetectionViewInit is ok");
+        return true;
+    }
+    void BPDetectionView::OnStart()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPDetectionView::OnStart");
+        View<BPDetectionPresenter>::OnStart();
+
+        SetContainerView(new UIViewGroup());
+        container_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+
+        if (!BPDetectionViewInit())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPDetectionView::InitBPView fail");
+        }
+
+        SetContainerView(container_);
+
+        container_->SetDraggable(true);
+        container_->SetTouchable(true);
+        container_->SetOnDragListener(presenter_);
+
+        // 增加按键监听
+        RootView::OnKeyActListener *keyactListener = (RootView::OnKeyActListener *)OHOS::BPDetectionPresenter::GetInstance();
+        RootView::GetInstance()->SetOnKeyActListener(keyactListener);
+    }
+    void BPDetectionView::OnSetUpView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPDetectionView::OnSetUpView");
+        View<BPDetectionPresenter>::OnSetUpView();
+        if (imageAnimator != nullptr)
+        {
+            imageAnimator->Start();
+        }
+        Draw();
+    }
+    void BPDetectionView::OnTearDownView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPDetectionView::OnTearDownView");
+        View<BPDetectionPresenter>::OnTearDownView();
+        return;
+    }
+
+    void BPDetectionView::OnStop()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPDetectionView::OnStop");
+        View<BPDetectionPresenter>::OnStop();
+        if (container_ != nullptr)
+        {
+            container_->RemoveAll();
+            delete container_;
+            container_ = nullptr;
+        }
+        return;
+    }
+}
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp
new file mode 100644 (file)
index 0000000..2a11fca
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: bloodOxygen view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#include "bloodpressure/include/BPMainPresenter.h"
+#include "common/task_manager.h"
+#include "BPModel.h"
+
+#include "bloodpressure/include/BPDetectionView.h"
+#include "bloodpressure/include/BPMainView.h"
+
+#include "components/ui_label.h"
+#include "components/ui_label_ext.h"
+
+#include "ChangeSliceListener.h"
+#include "broadcast_service.h"
+#include <fstream>
+#include "iostream"
+#include <sstream>
+#include <string>
+#include <cstdlib>
+#include <ctime>
+#include "wearable_log.h"
+#include "cmsis_os.h"
+#include "securec.h"
+#include "broadcast_service.h"
+#include "graphic_service.h"
+#include <chrono>
+#include <thread>
+#include <sys/time.h>
+
+#include "ppg_service.h"
+#include "displaybrightness/include/DisplayBrightnessModel.h"
+#include "power_display_service.h"
+#include "custom_utils.h"
+#include "cywee_service.h"
+#include "battery_hal.h"
+
+#include "heart_blood/health_service/health_service.h"
+#include "gfx_utils/mem_check.h"
+
+#define BPKEYABLE 1
+namespace OHOS
+{
+    static constexpr uint16_t PROGRESS_VALUE_MIN = 0;
+    static constexpr uint16_t PROGRESS_VALUE_MAX = 10;
+
+    static BPMainPresenter *g_pBPMainPresenter;
+    /* -------------------------------------------------------------------------- */
+    // 获取当前的时间戳
+    uint32_t BPMainPresenter::GetCurrentTime()
+    {
+        uint32_t time;
+        if (uapi_get_timestampe_ss(&time) != ERRCODE_SUCC)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp");
+            return 0;
+        }
+        return time;
+    }
+
+    // 获取时间差,现在传进来的是两个时间戳
+    int BPMainPresenter::GetTDOA(uint32_t new_time, uint32_t old_time)
+    {
+        if (new_time == old_time || old_time > new_time)
+        {
+            return 0;
+        }
+        int time_diff_seconds = new_time - old_time;
+        // 转换为分钟的差值
+        int time_diff_minutes = time_diff_seconds / 60;
+        return time_diff_minutes;
+    }
+    /* -------------------------------------------------------------------------- */
+    BPMainPresenter::BPMainPresenter()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPMainPresenter::new BPMainPresenter");
+        g_pBPMainPresenter = this;
+#ifdef MEM_CHECK
+        MemCheck::GetInstance()->EnableLeakCheck(true);
+#endif
+    }
+    BPMainPresenter::~BPMainPresenter()
+    {
+        g_pBPMainPresenter = nullptr;
+#ifdef MEM_CHECK
+        MemCheck::GetInstance()->EnableLeakCheck(false);
+#endif
+    }
+    BPMainPresenter *BPMainPresenter::GetInstance()
+    {
+        return g_pBPMainPresenter;
+    }
+    void BPMainPresenter::OnStart()
+    {
+        Presenter<BPMainView>::OnStart();
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPMainPresenter::On Start ");
+    }
+    void BPMainPresenter::OnPause(void) {}
+
+    void BPMainPresenter::OnResume(void) {}
+
+    void BPMainPresenter::OnStop(void) {}
+
+    bool BPMainPresenter::OnDrag(UIView &view, const DragEvent &event)
+    {
+        return true;
+    }
+    bool BPMainPresenter::OnDragEnd(UIView &view, const DragEvent &event)
+    {
+        if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT)
+        {
+            // NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST);
+            NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+            return true;
+        }
+        return false;
+    }
+    bool BPMainPresenter::OnKeyAct(UIView &view, const KeyEvent &event)
+    {
+        unsigned short keyID = event.GetKeyId();
+        unsigned short keyState = event.GetState();
+        // 如果是power键,且是亮屏状态,按键释放就返回上一级
+        if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) &&
+            keyState == 1 && uapi_get_screen_state() == 0)
+        {
+            // NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST);
+            NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+        }
+        return true;
+    }
+
+    bool BPMainPresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        if (strcmp(view.GetViewId(), CLICK_BP) == 0)
+        {
+            // 如果正在充电进入提醒界面
+            if (get_charge_stat())
+            {
+                HealthState highHealthState;
+                highHealthState.checkType = CHARGE;
+                HealthService::GetInstance()->SetHealthCurrent(highHealthState);
+                NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_INVALID, TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+            }
+            else
+            {
+                // NativeAbility::GetInstance().EnterSlice(VIEW_BP_CHECK, TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+            }
+        }
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPPresenter::OnClick");
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPMainView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPMainView.cpp
new file mode 100644 (file)
index 0000000..dcebfe5
--- /dev/null
@@ -0,0 +1,247 @@
+/***
+ * @Date: 2024-04-15 10:55:58
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-31 14:36:25
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPMainView.cpp
+ */
+
+#include "common/image_cache_manager.h"
+#include "ui_resource_image.h"
+#include <ui_scroll_view.h>
+#include "components/ui_button.h"
+#include "MainViewSample.h"
+#include "components/ui_view_group.h"
+#include "DialModelSPO2.h"
+#include "DialModelHeartRate.h"
+#include "BPModel.h"
+
+#include "UiConfig.h"
+#include "uicomponents/UIComponents.h"
+#include "MainPresenterSample.h"
+
+#include "bloodpressure/include/BPMainPresenter.h"
+#include "bloodpressure/include/BPMainView.h"
+namespace OHOS
+{
+    static BPMainView *g_pBPMainView{nullptr};
+    static const char *BPBACKPATH = "/user/res/BP/beijing.bin";
+
+    BPMainView::BPMainView()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPMainView::BPMainView");
+        g_pBPMainView = this;
+    }
+
+    BPMainView::~BPMainView()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPMainView::~BPMainView");
+        DeInit();
+        g_pBPMainView = nullptr;
+    }
+
+    BPMainView *BPMainView::GetInstance()
+    {
+        return g_pBPMainView;
+    }
+
+    /* -------------------------------------------------------------------------- */
+    void BPMainView::UpSPO2Text()
+    {
+        if (bloodLabel == nullptr || timeLabel == nullptr)
+            return;
+            
+        // 更新血氧数据
+        uint16_t spo2 = BPModel::GetInstance()->GetSPO2data();
+        if (spo2 != 0) // 判断是否为默认数据
+        {
+            // 更新数据
+            std::string bloodpressureStr = std::to_string(spo2) + "%";
+            bloodLabel->SetText(bloodpressureStr.c_str());
+
+            // 获取时间差
+            uint32_t time = BPMainPresenter::GetInstance()->GetCurrentTime();
+            uint32_t check_time = BPModel::GetInstance()->GetCheckTime();
+            int time_diff = BPMainPresenter::GetInstance()->GetTDOA(time, check_time);
+
+            if (time_diff == 0)
+            {
+                timeLabel->SetTextId(STR_CHECKNEW);
+            }
+            else if (time_diff <= 60)
+            {
+                UpdateLabel(timeLabel, time_diff, STR_CHECKTIME);
+            }
+            else
+            {
+                timeLabel->SetTextId(STR_CHECKLONG);
+            }
+        }
+        else
+        {
+            bloodLabel->SetText("--");
+            timeLabel->SetTextId(STR_CHECKNO);
+        }
+    }
+
+    /* -------------------------------------------------------------------------- */
+    /***
+     * @description:
+     * @return 添加按键是否成功
+     */
+    bool BPMainView::AddButton()
+    {
+        InitButtonExt(checkButton, 118, 336, 230, 80, CLICK_BP, STR_CHECK, 30);
+        checkButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xffFF5A36); // 设置按键颜色
+        // 设置按键监听
+        UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::BPMainPresenter::GetInstance();
+        checkButton->SetOnClickListener(clickListener);
+
+        container_->Add(checkButton);
+        return true;
+    }
+    /***
+     * @description:
+     * @return 初始化标签是否成功
+     */
+    bool BPMainView::InitLable()
+    {
+        /*初始化title*/
+        // InitLabelExt(titleLabel, 83, 50, 300, 35, "title", STR_BP, DEFAULT_VECTOR_FONT_FILENAME, 30);
+        /*初始化血氧值label*/
+        InitUILabel(bloodLabel, 83, 32, 300, 300, "bloodtext", "--", DEFAULT_VECTOR_FONT_FILENAME, 140);
+        /*初始化检测时间*/
+        InitLabelExt(timeLabel, 53, 270, 360, 35, "time", STR_CHECKNO, DEFAULT_VECTOR_FONT_FILENAME, 30);
+        // 设置来回滚动属性
+        timeLabel->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION);
+        timeLabel->SetRollSpeed(23);
+
+        UpSPO2Text();
+
+        // container_->Add(titleLabel);
+        container_->Add(bloodLabel);
+        container_->Add(timeLabel);
+
+        return true;
+    }
+    /***
+     * @description:
+     * @return 初始化背景是否成功
+     */
+    bool BPMainView::Initbackground()
+    {
+
+        background = new UIImageView();
+        background->SetPosition(0, 0, 466, 466);
+        background->SetSrc(BPBACKPATH);
+
+        container_->Add(background);
+        return true;
+    }
+    /***
+     * @description:
+     * @return 是否初始化成功
+     */
+    bool BPMainView::BPMainViewInit()
+    {
+
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "bool BPMainView::InitView()");
+        if (!Initbackground())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Initbackground error!");
+        };
+        if (!InitLable())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitLable error!");
+        };
+        if (!AddButton())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddButton error!");
+        };
+        return true;
+    }
+    /***
+     * @description:
+     * @return 删除组件
+     */
+    void BPMainView::DeInit()
+    {
+        if(container_)
+        {
+            container_->RemoveAll();
+        }
+        if (background != nullptr)
+        {
+            delete background;
+            background = nullptr;
+        }
+        if (bloodLabel != nullptr)
+        {
+            delete bloodLabel;
+            bloodLabel = nullptr;
+        }
+        if (timeLabel != nullptr)
+        {
+            delete timeLabel;
+            timeLabel = nullptr;
+        }
+        if (titleLabel != nullptr)
+        {
+            delete titleLabel;
+            titleLabel = nullptr;
+        }
+        if(checkButton!=nullptr)
+        {
+            delete checkButton;
+            checkButton = nullptr;
+        }
+    }
+
+    void BPMainView::OnStart()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPMainView::OnStart");
+        View<BPMainPresenter>::OnStart();
+
+        SetContainerView(new UIViewGroup());
+        container_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+
+        if (!BPMainViewInit())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPMainView::InitBPView fail");
+        }
+
+        SetContainerView(container_);
+
+        container_->SetDraggable(true);
+        container_->SetTouchable(true);
+        container_->SetOnDragListener(presenter_);
+
+        // 增加按键监听
+        RootView::OnKeyActListener *keyactListener = (RootView::OnKeyActListener *)OHOS::BPMainPresenter::GetInstance();
+        RootView::GetInstance()->SetOnKeyActListener(keyactListener);
+    }
+    void BPMainView::OnSetUpView()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPMainView::OnSetUpView");
+        View<BPMainPresenter>::OnSetUpView();
+        Draw();
+    }
+    void BPMainView::OnTearDownView()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPMainView::OnTearDownView");
+        View<BPMainPresenter>::OnTearDownView();
+        return;
+    }
+
+    void BPMainView::OnStop()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPMainView::OnStop");
+        View<BPMainPresenter>::OnStop();
+        if (container_ != nullptr)
+        {
+            container_->RemoveAll();
+            delete container_;
+            container_ = nullptr;
+        }
+        return;
+    }
+}
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPModel.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/BPModel.cpp
new file mode 100644 (file)
index 0000000..dc03b98
--- /dev/null
@@ -0,0 +1,304 @@
+#include "bloodpressure/include/BPModel.h"
+#include "bloodpressure/include/BPMainPresenter.h"
+
+#include "DialModelSPO2.h"
+#include "wearable_log.h"
+#include "heart_blood/health_service/health_service.h"
+#include "custom_utils.h"
+
+extern "C" errcode_t uapi_get_timestamp_ms(uint32_t *tm);
+
+#include "custom_utils.h"
+#include "ppg_service.h"
+#include "ConfigModel.h"
+#include "AppViewIDs.h"
+#include "NativeAbility.h"
+#include "battery_hal.h"
+// #include "heart_blood/BloodCardView.h"
+#include "MainViewSample.h"
+
+#include <custom_save_runtime.h>
+
+#define MAX_UNWARE_COUNT 10
+#define MAX_VALID_SPO2_COUNT 30
+#define MAX_DISVALID_SPO2_COUNT 100
+namespace OHOS
+{
+    /**
+     * @brief Constructor for the BPModel class.
+     */
+    BPModel::BPModel()
+    {
+        // BPData *data = HealthService::GetInstance()->ReadBPData();
+        // if (data)
+        // {
+        //     currentspo2 = data->SPO2;
+        //     timestamp_ms = data->timestamp;
+        //     // 更新表盘血氧数据
+        //     DialModelSPO2::GetInstance()->UpdateSPO2(currentspo2);
+        //     delete data;
+        // }
+        // else
+        // {
+            currentspo2 = 0;
+            timestamp_ms = 0;
+        // }
+    }
+    BPModel::~BPModel() {}
+    BPModel *BPModel::GetInstance(void)
+    {
+        static BPModel instance;
+        return &instance;
+    }
+    /* ---------------------------------- 状态检测 ---------------------------------- */
+
+    void BPModel::ClearDisplayData()
+    {
+      // currentspo2 = 0;
+      // timestamp_ms = 0;
+      // 不需要清空
+    }
+
+    // 血氧监控
+    void BPModel::BP_Control(BPState state)
+    {
+        // if (state == BPState::End && startspo2 == true)
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "startspo2 End");
+        //     uint16_t md = PPG_SERVICE_CMD_TYPE_STOP_SPO2_TEST;
+        //     send_ppg_cmd_msg(md);
+        //     startspo2 = false;
+
+        //     uapi_save_runtime_log(RUNTIME_LOG_OXYGEN_MEASURE_END);
+        // }
+        // else if (state == BPState::Start && startspo2 == false)
+        // {
+        //     /*充电状态下不进行检测*/
+        //     bool isCharging = get_charge_stat(); // 获取充电状态
+        //     if (isCharging)
+        //     {
+        //         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "充电不能检测");
+        //         return;
+        //     }
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "startspo2 Start");
+        //     uint16_t md = PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST;
+        //     send_ppg_cmd_msg(md);
+        //     startspo2 = true;
+
+        //     uapi_save_runtime_log(RUNTIME_LOG_OXYGEN_MEASURE);
+        // }
+    }
+
+    uint16_t BPModel::GetSPO2data()
+    {
+        return currentspo2;
+    }
+
+    uint16_t BPModel::GetShowSPO2data()
+    {
+        return displayspo2;
+    }
+
+    uint32_t BPModel::GetCheckTime()
+    {
+        return timestamp_ms;
+    }
+
+    void BPModel::SetCheckTime(uint32_t time)
+    {
+        timestamp_ms = time;
+    }
+    void BPModel::SetMain(BPMain result)
+    {
+        bloodresult_ = result;
+    }
+    BPMain BPModel::GetMain()
+    {
+        return bloodresult_;
+    }
+
+    // 开始检测
+    void BPModel::BP_Start()
+    {
+        // displayspo2 = 0;
+        // SetMain(BPMain::NOT_TESTED); // 成功检测
+        // // 进行初始化操作
+        // if (!sensorstate)
+        // {
+        //     BP_Control(BPState::Start);
+        //     sensorstate = true;
+        // }
+    }
+
+    // 结束检测
+    void BPModel::BP_Stop()
+    {
+        // valid_counter_ = 0;
+        // disvalid_counter_ = 0;
+        // unwear_counter_ = 0;
+
+        // if (sensorstate)
+        // {
+        //     BP_Control(BPState::End);
+        //     sensorstate = false;
+        //     BP_Main(); // 处理结果
+        // }
+    }
+
+    // 保存检测数据
+    void BPModel::BP_Save()
+    {
+//         uint32_t timestamp = BPMainPresenter::GetInstance()->GetCurrentTime();
+//         SetCheckTime(timestamp);
+// #if MSG_SAVE_TEST
+//         BPData data;
+//         data.SPO2 = currentspo2;
+//         data.timestamp = timestamp_ms;
+//         HealthService::GetInstance()->UpdateHealthData(data);
+// #else
+//         HealthService::GetInstance()->send_blood_save();
+//     #endif
+    }
+
+    // 显示检测结果// 显示检测结果
+    void BPModel::BP_Main()
+    {
+        // uint16_t MiniBP = ConfigModel::GetInstance()->get_configData_int(ConfigModel::CONFIGMODEL_ITEM_OXYGEN_THRESHOLD_VALUE);
+
+        // // 检查当前血氧值并设置结果 需要检测成功
+        // if(bloodresult_ == BPMain::SUCCESS){
+        //     if (currentspo2 < MiniBP && currentspo2 != 0)
+        //     {
+        //         // 测量结果小于最小血氧值
+        //         bloodresult_ = BPMain::LOW_RESULT;
+        //         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 低结果情况, currentspo2 = %d, MiniBP = %d", currentspo2, MiniBP);
+        //     }
+        // }
+
+        // // 根据结果进行处理
+        // switch (bloodresult_)
+        // {
+        // case BPMain::SUCCESS:
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 成功");
+        //     BP_Save();
+        //     NativeAbility::GetInstance().Back(); // 成功
+        //     break;
+        // }
+        // case BPMain::NOT_WORN: // 未佩戴状态
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 未佩戴状态");
+        //     NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_ABNORMAL);
+        //     break;
+        // }
+        // case BPMain::TIMEOUT: // 超时情况
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 超时情况");
+        //     NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_ABNORMAL);
+        //     break;
+        // }
+        // case BPMain::LOW_RESULT: // 低结果情况
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 低结果情况");
+        //     HealthState healthState;
+        //     healthState.checkType = BP_CHECK;
+        //     healthState.resultStatus = LOW;
+        //     healthState.checkMain = MiniBP;
+        //     HealthService::GetInstance()->SetHealthCurrent(healthState);
+        //     //保存异常数据
+        //     BP_Save();
+        //     NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_INVALID);
+        //     break;
+        // }
+        // case BPMain::INVALID_DATA: // 无效数据情况
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 无效数据情况");
+        //     NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_ABNORMAL);
+        //     break;
+        // }
+        // default:
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 未知状态");
+        //     break;
+        // }
+        // }
+    }
+    // 更新佩戴状态
+    void BPModel::SetWearStatus(int32_t wear)
+    {
+        // // 设置佩戴状态
+        // WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BPModel Weartest::%d", wear);
+        // //开启检测才对佩戴进行监听
+        // if (sensorstate)
+        // {
+        //     // 计数更新
+        //     if (wear_ != 1 && wear != 1)
+        //     {
+        //         unwear_counter_++; // 佩戴错误计时器计数
+        //     }
+        //     else
+        //     {
+        //         unwear_counter_ = 0; // 佩戴正常情况下清零计数器
+        //     }
+        //     wear_ = wear;
+        //     // 检查是否达到了最大未佩戴计数限制
+        //     if (unwear_counter_ >= MAX_UNWARE_COUNT)
+        //     {
+        //         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 未佩戴计数最大 unwear_counter: %d", unwear_counter_);
+        //         SetMain(BPMain::NOT_WORN);
+        //         BP_Stop();
+        //     }
+        // }
+    }
+
+    // 更新SPO2数据
+    void BPModel::UpSPO2data(uint8_t spo2)
+    {
+        // displayspo2 = spo2;
+
+        // // 处理有效与无效计数
+        // if (displayspo2 != 0)
+        // {
+        //     currentspo2 = displayspo2; // 更新 currentspo2
+        //     valid_counter_++;          // 增加有效计数器
+        //     disvalid_counter_ = 0;     // 清空无效计数器
+        // }
+        // else
+        // {
+        //     disvalid_counter_++; // 增加无效计数器
+        //     valid_counter_ = 0;  // 清零有效计数器
+        // }
+
+        // // 检查无效计数器是否达标
+        // if (disvalid_counter_ >= MAX_DISVALID_SPO2_COUNT)
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 无效数达标 disvalid_counter: %d", disvalid_counter_);
+        //     SetMain(BPMain::INVALID_DATA); // 无效数达标
+        //     BP_Stop();
+        // }
+
+        // // 检查有效计数器是否达标
+        // if (valid_counter_ >= MAX_VALID_SPO2_COUNT)
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 成功 valid_counter: %d currentspo2: %d", valid_counter_, currentspo2);
+        //     SetMain(BPMain::SUCCESS); // 成功检测
+        //     BP_Stop();
+        // }
+    }
+
+    // 更新血氧数据
+    void BPModel::CleanAllData(void)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Nextday!");
+        // if (MainViewSample::GetInstance() != nullptr && BPCardView::GetInstance() != nullptr)
+        // {
+        //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "更新主界面血氧卡片");
+        //     BPCardView::GetInstance()->UpSPO2Text();
+        // }
+        if (BPMainView::GetInstance() != nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "更新测量血氧卡片");
+            BPMainView::GetInstance()->UpSPO2Text();
+        }
+    }
+}
diff --git a/tools/image_converter_tool/test/w9/BP/bg.png b/tools/image_converter_tool/test/w9/BP/bg.png
new file mode 100644 (file)
index 0000000..b5eeb5f
Binary files /dev/null and b/tools/image_converter_tool/test/w9/BP/bg.png differ