【心率】UI
authorCaisking <Casiking@zhihuishixun.com>
Fri, 18 Apr 2025 03:54:56 +0000 (11:54 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Fri, 18 Apr 2025 03:54:56 +0000 (11:54 +0800)
20 files changed:
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartChartPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartChartView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartDetectionPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartDetectionView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartModel.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartNoteView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartRateCardView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartRateView.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartResultPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartResultView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartChartPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartChartView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartDetectionPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartDetectionView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartModel.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartNoteView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartRateCardView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartRateView.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartResultPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartResultView.cpp [new file with mode: 0644]

diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartChartPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartChartPresenter.h
new file mode 100644 (file)
index 0000000..876166b
--- /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/fd230app/nativeui/heartrate/include/HeartChartPresenter.h
+ */
+
+#ifndef HEART_Chart_PRESENTER_H
+#define HEART_Chart_PRESENTER_H
+
+#include "Presenter.h"
+#include "components/ui_list.h"
+#include "components/ui_view.h"
+#include "KeyInputListener.h"
+#include "ModelListenerSample.h"
+#include "heartrate/include/HeartChartView.h"
+#include "power_display_service.h"
+
+#define HEART_KEEP_TIME 40000 // 40s
+
+namespace OHOS
+{
+
+    class HeartChartView;
+    class HeartChartPresenter : public Presenter<HeartChartView>,
+                                    public ModelListenerSample,
+                                    public UIView::OnClickListener,
+                                    public UIView::OnDragListener,
+                                    public RootView::OnKeyActListener,
+                                    public ListScrollListener
+    {
+    public:
+        HeartChartPresenter();
+        ~HeartChartPresenter() override;
+        static HeartChartPresenter *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 HeartCountEvent{false};
+        bool HeartCheckState{false};
+
+        const power_display_svr_api_t *display_api = power_display_svr_get_api();
+        uint32_t display_time;
+    };
+}
+
+#endif // HEART_Chart_PRESENTER_H
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartChartView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartChartView.h
new file mode 100644 (file)
index 0000000..06db4bd
--- /dev/null
@@ -0,0 +1,96 @@
+/***
+ * @Date: 2024-08-15 18:38:49
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-08-26 15:17:07
+ * @FilePath:
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartChartView.h
+ */
+/***
+ * @Date: 2024-08-15 18:38:49
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-08-15 20:25:38
+ * @FilePath:
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartChartView.h
+ */
+
+#ifndef HEART_Chart_VIEW_H
+#define HEART_Chart_VIEW_H
+
+
+#include "UiConfig.h"
+#include "View.h"
+#include "components/ui_button.h"
+#include "components/ui_circle_progress.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_label.h"
+#include "components/ui_label_button.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_view_group.h"
+#include "wearable_log.h"
+
+#include "heartrate/include/HeartChartPresenter.h"
+
+#include "components/ui_label_button_ext.h"
+#include "components/ui_scroll_view.h"
+
+#include "components/ui_chart.h"
+#include "components/ui_image_animator.h"
+#include "power_display_service.h"
+
+#define STOPCHECK "stop_check"
+namespace OHOS {
+class HeartChartPresenter;
+class HeartChartView : public View<HeartChartPresenter> {
+public:
+  HeartChartView();
+  virtual ~HeartChartView();
+
+  void OnStart() override;
+  static HeartChartView *GetInstance(void);
+  UIImageAnimatorView *GetImageAnimator(void);
+  void HeartbeatImageAnimatorStart();
+  void HeartbeatImageAnimatorStop();
+
+  bool HeartViewInit();
+  void InitChartView(void);
+  void InitChartLabel(void);
+  void InitChartImageView(void);
+
+  void SetDataChart();
+  void SetDataTopAndBottom();
+  void HeartImageAnimator();
+
+  void UpdateShowHeart(void);
+  void Update_data_Chart(int serialIndex);
+  void CleanAllDataView();
+  void UpdateChartConfig();
+  void SetLastHeart();
+  UIViewGroup *GetchartGroup();
+
+private:
+  UIImageView *maxRateIconView_{nullptr};
+  UIImageView *minRateIconView_{nullptr};
+  UIImageView *chartBackgroundView_{nullptr};
+  UIImageView *heartIconView_{nullptr};
+
+  UIImageAnimatorView *imageAnimator{nullptr};
+
+  Point heartdata[24];
+  UIChartDataSerial *heartSerial{nullptr};
+  UIChartPolyline *heartchart = nullptr;
+
+  UILabelExt *displayheart_{nullptr};
+  UILabelExt *uheart_{nullptr};
+  UILabelExt *lastheart_{nullptr};
+  UILabelExt *minheart_{nullptr};
+  UILabelExt *maxheart_{nullptr};
+
+  UILabelExt *maxheart_dynamic_{nullptr};
+  UILabelExt *maxheart_dynamic_3_{nullptr};
+  UILabelExt *maxheart_dynamic_2_{nullptr};
+  UILabelExt *maxheart_dynamic_1_{nullptr};
+  UILabelExt *minheart_dynamic_{nullptr};
+};
+} // namespace OHOS
+
+#endif // 心率主界面
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartDetectionPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartDetectionPresenter.h
new file mode 100644 (file)
index 0000000..8c7ec93
--- /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/fd230app/nativeui/heartrate/include/HeartDetectionPresenter.h
+ */
+
+#ifndef HEART_DETECTION_PRESENTER_H
+#define HEART_DETECTION_PRESENTER_H
+
+#include "Presenter.h"
+#include "components/ui_list.h"
+#include "components/ui_view.h"
+#include "KeyInputListener.h"
+#include "ModelListenerSample.h"
+#include "heartrate/include/HeartDetectionView.h"
+#include "power_display_service.h"
+
+#define HEART_KEEP_TIME 40000 // 40s
+
+namespace OHOS
+{
+
+    class HeartDetectionView;
+    class HeartDetectionPresenter : public Presenter<HeartDetectionView>,
+                                    public ModelListenerSample,
+                                    public UIView::OnClickListener,
+                                    public UIView::OnDragListener,
+                                    public RootView::OnKeyActListener,
+                                    public ListScrollListener
+    {
+    public:
+        HeartDetectionPresenter();
+        ~HeartDetectionPresenter() override;
+        static HeartDetectionPresenter *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 HeartCountEvent{false};
+        bool HeartCheckState{false};
+
+        const power_display_svr_api_t *display_api = power_display_svr_get_api();
+        uint32_t display_time;
+    };
+}
+
+#endif // HEART_DETECTION_PRESENTER_H
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartDetectionView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartDetectionView.h
new file mode 100644 (file)
index 0000000..2cc2921
--- /dev/null
@@ -0,0 +1,53 @@
+
+
+#ifndef HEART_Detection_VIEW_H
+#define HEART_Detection_VIEW_H
+
+#include "View.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 "heartrate/include/HeartDetectionPresenter.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 HeartDetectionPresenter;
+    class HeartDetectionView : public View<HeartDetectionPresenter>
+    {
+    public:
+        HeartDetectionView();
+        virtual ~HeartDetectionView();
+     
+        void OnStart() override;
+        static HeartDetectionView *GetInstance(void);
+
+        bool HeartDetectionViewInit();
+        UIImageAnimatorView *GetImageAnimator(void);
+        void UpShowHeartText(void);
+
+    private:
+        UIImageAnimatorView *imageAnimator{nullptr};
+        UILabelExt *titleLabel{nullptr};
+        UILabel *HeartText{nullptr};
+        UIScrollView *HeartDetectionScrollView{nullptr};
+        UILabelButtonExt *testButton{nullptr};
+
+        uint32_t heart_;
+    };
+}
+
+#endif // 心率主界面
\ No newline at end of file
index 3891ec7..00809cf 100644 (file)
@@ -1,11 +1,11 @@
 #ifndef HEART_MODEL_H\r
 #define HEART_MODEL_H\r
 \r
-#include <ctime>\r
+#include "MainClockView.h"\r
 #include "broadcast_feature.h"\r
 #include "broadcast_service.h"\r
 #include "samgr_lite.h"\r
-#include "MainClockView.h"\r
+#include <ctime>\r
 \r
 #ifdef __cplusplus\r
 extern "C" {\r
@@ -18,39 +18,39 @@ void HearDatatUnsubscribeTopic(Topic topic);
 #define HEART_ALL_POINTS 360\r
 \r
 typedef struct {\r
-    uint16_t x;\r
-    uint16_t y;\r
-    bool flag;\r
+  uint16_t x;\r
+  uint16_t y;\r
+  bool flag;\r
 } Point;\r
 \r
 typedef struct {\r
-    /** X coordinate */\r
-    uint16_t x;\r
-    /** Y coordinate */\r
-    uint16_t y;\r
+  /** X coordinate */\r
+  uint16_t x;\r
+  /** Y coordinate */\r
+  uint16_t y;\r
 } HeartPoint;\r
 \r
 typedef struct {\r
-    uint16_t perSec;\r
-    uint16_t rest;\r
-    uint16_t minX;\r
-    uint16_t minValue;\r
-    uint16_t maxX;\r
-    uint16_t maxValue;\r
-    uint16_t index;\r
-    Point value[HEART_ALL_POINTS];\r
+  uint16_t perSec;\r
+  uint16_t rest;\r
+  uint16_t minX;\r
+  uint16_t minValue;\r
+  uint16_t maxX;\r
+  uint16_t maxValue;\r
+  uint16_t index;\r
+  Point value[HEART_ALL_POINTS];\r
 } HeartInfo;\r
 \r
 #pragma pack(4)\r
 typedef struct {\r
-    uint16_t perSec;\r
-    uint16_t rest;\r
-    uint16_t minX;\r
-    uint16_t minValue;\r
-    uint16_t maxX;\r
-    uint16_t maxValue;\r
-    uint16_t index;\r
-    HeartPoint value[HEART_ALL_POINTS];\r
+  uint16_t perSec;\r
+  uint16_t rest;\r
+  uint16_t minX;\r
+  uint16_t minValue;\r
+  uint16_t maxX;\r
+  uint16_t maxValue;\r
+  uint16_t index;\r
+  HeartPoint value[HEART_ALL_POINTS];\r
 } HeartDatas;\r
 \r
 #pragma pack()\r
@@ -69,52 +69,137 @@ namespace OHOS {
 #define NUM_7 7\r
 #define NUM_16 16\r
 #define NUM_99 99\r
-\r
+// 心率检测状态\r
+enum class HeartState {\r
+  End = 0,\r
+  Start,\r
+};\r
+enum class HeartCheck {\r
+  RESTSTSTE = 0, // 未检测状态\r
+  PASSIVITY,     // 被动检测心率\r
+  CARDCHECK,     // 卡片检测\r
+  INITIATIVE,    // 主动检测心率\r
+  EXERCISE,      // 运动心率\r
+};\r
+enum class HeartResult {\r
+  NOT_TESTED = 0, // 未检测\r
+  SUCCESS,        // 检测成功\r
+  NOT_WORN,       // 未佩戴检测\r
+  TIMEOUT,        // 检测超时\r
+  HIGH_RESULT,    // 检测结果过高\r
+  LOW_RESULT,     // 检测结果过低\r
+  INVALID_DATA    // 无效数据\r
+};\r
+// 控制心率检测\r
 typedef struct {\r
-    uint32_t heartRatePerSec;\r
-    Point heartRateAvg[HEART_AVE_NUM];\r
-    uint32_t heartRateRest;\r
-    Point heartRateMax;\r
-    Point heartRateMin;\r
+  uint32_t heartRatePerSec;\r
+  Point heartRateAvg[HEART_AVE_NUM];\r
+  uint32_t heartRateRest;\r
+  Point heartRateMax;\r
+  Point heartRateMin;\r
 } HealthAllDatas;\r
 \r
 class HeartModel {\r
 public:\r
-    HeartModel();\r
-    ~HeartModel();\r
-    static HeartModel *GetInstance(void);\r
-    void ObtainingHeartRateData(void);\r
-    void PushHealthDatas(HealthMsg healthMsg);\r
-    Point* GetAveHeartRate(void);\r
-    uint16_t GetAveHeartRateCount(void);\r
-    void SetAveHeartRateCount(uint16_t value);\r
-    Point* GetMaximumHeartRate(void);\r
-    void Init(void);\r
-    void HeartRatePros(HeartDatas *heartInfo);\r
-    void RefreshHeartRateScreen(uint16_t perSec, uint16_t rest, uint16_t maxRate, uint16_t minRate);\r
-    void ClearHeartData(void);\r
-    void HandleMaxHeart(uint16_t coord, uint16_t value);\r
-    void HandleMinHeart(uint16_t coord, uint16_t value);\r
-    void SetHeartRatePerSec(uint32_t sec);\r
-    void SetWearStatus(bool status);\r
-    bool GetWearStatus(void);\r
-    uint16_t GetHeartRateMax(void);\r
-    uint16_t GetHeartRateMin(void);\r
+  HeartModel();\r
+  ~HeartModel();\r
+  static HeartModel *GetInstance(void);\r
+  void ObtainingHeartRateData(void);\r
+  void PushHealthDatas(HealthMsg healthMsg);\r
+  Point *GetAveHeartRate(void);\r
+  uint16_t GetAveHeartRateCount(void);\r
+  void SetAveHeartRateCount(uint16_t value);\r
+  Point *GetMaximumHeartRate(void);\r
+  void Init(void);\r
+  void HeartRatePros(HeartDatas *heartInfo);\r
+  void RefreshHeartRateScreen();\r
+  void ClearHeartData(void);\r
+  void HandleMaxHeart(uint16_t coord, uint16_t value);\r
+  void HandleMinHeart(uint16_t coord, uint16_t value);\r
+  void SetHeartRatePerSec(uint32_t sec);\r
+  uint16_t GetHeartRateMax(void);\r
+  uint16_t GetHeartRateMin(void);\r
+  /* --------------------------------------------------------------------------\r
+   */\r
+  void UpHeartdata(uint16_t heart);\r
+  uint16_t GetHeartdata();\r
+  uint16_t GetShowHeartdata();\r
+  uint16_t GetShowMaxHeartdata();\r
+  uint16_t GetShowMinHeartdata();\r
+\r
+  uint16_t GetIndex();\r
+  void SetIndex(uint16_t index);\r
+\r
+  uint32_t GetCheckTime(void);\r
+  void SetCheckTime(uint32_t time);\r
+  void SetWearStatus();\r
+  void SetResult(HeartResult result);\r
+  HeartResult GetResult();\r
+\r
+  void Heart_Start(HeartCheck check);\r
+  void Heart_Stop(void);\r
+  void Heart_Save(void);\r
+  void Heart_Result(void);\r
+\r
+  void Heart_Control(HeartState state, HeartCheck check);\r
+  void ClearDisplayData();\r
+  void Heart_Update_View(void);\r
+  void CleanAllData(void);\r
+\r
+  std::string GetCheckString();\r
+  uint16_t *GetArrayData();\r
+  void SetArrayData();\r
+\r
+  void handleHeartResult();\r
+  void logAndChangeSlice(HeartResult result);\r
+  void handleLowHeartRate();\r
+  void handleHighHeartRate();\r
+\r
+  void heart_start_screen60s_timer(uint32_t interval = 30 * 1000);\r
+  void heart_stop_screen60s_timer();\r
+  void reset_heart_screen60s_timer_time();\r
 \r
 private:\r
-    HealthAllDatas healthDatas;\r
-    uint16_t pretime{0};\r
-    uint16_t entryTimes{0};\r
-    uint16_t aveCount{0};\r
-    uint16_t preMaxValue{0};\r
-    uint16_t preMaxX{NUM_1};\r
-    uint16_t preMinValue{HEART_RATE_LIMIT_UPPER};\r
-    uint16_t preMinX{NUM_1};\r
-    uint16_t countMax{0};\r
-    uint16_t countMin{0};\r
-    bool wearStatus{false};\r
+  HealthAllDatas healthDatas;\r
+  uint16_t pretime{0};\r
+  uint16_t entryTimes{0};\r
+  uint16_t aveCount{0};\r
+  uint16_t preMaxValue{0};\r
+  uint16_t preMaxX{NUM_1};\r
+  uint16_t preMinValue{HEART_RATE_LIMIT_UPPER};\r
+  uint16_t preMinX{NUM_1};\r
+  uint16_t countMax{0};\r
+  uint16_t countMin{0};\r
+  bool wearStatus{true};\r
+  uint16_t index_ = 0;\r
+\r
+  uint16_t displayheart = 0;     // 显示心率\r
+  uint16_t currentheart = 0;     // 保存心率\r
+  uint16_t displayheart_max = 0; // 显示最大心率\r
+  uint16_t displayheart_min = 0; // 显示最小心率\r
+\r
+  uint32 timestamp_ms; // 检测时间(存(时、分),大于24小时,改为1天前,小于1分钟为刚刚)\r
+\r
+  bool initstatus = true;\r
+  bool heartstate = false;\r
+  bool sensorstate{false};\r
+\r
+  uint16_t wear_;\r
+  uint16_t valid_counter_ = 0;    // 有效数计数器\r
+  uint16_t disvalid_counter_ = 0; // 无效数计数器\r
+  uint16_t unwear_counter_ = 0;   // 佩戴错误计数器\r
+  uint16_t display_counter_ = 0;  //显示计数器\r
+\r
+  HeartResult heartresult_ = HeartResult::NOT_TESTED; // 检测结果\r
+  HeartCheck checkstate = HeartCheck::RESTSTSTE;      // 目前检测状态\r
+\r
+  uint16_t dynamic_heartrate[5]; //动态心率配置项\r
+\r
+  uint8_t heartRemindState{0};\r
+  uint16_t thresholdValue{160};\r
+  uint16_t thresholdState{1};\r
 };\r
-}\r
+} // namespace OHOS\r
 \r
 #ifdef __cplusplus\r
 }\r
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartNoteView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartNoteView.h
new file mode 100644 (file)
index 0000000..2138339
--- /dev/null
@@ -0,0 +1,63 @@
+/***
+ * @Date: 2024-04-15 10:55:58
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-30 11:46:23
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/include/HeartNoteView.h
+ */
+/***
+ * @Date: 2024-04-15 10:55:58
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-05-07 18:51:13
+ * @FilePath: /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/include/HeartNoteView.h
+ */
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: bloodResult view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#ifndef HEART_NOTE_VIEW_H
+#define HEART_NOTE_VIEW_H
+
+#include "View.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 "components/ui_scroll_view.h"
+#include "components/ui_label_button_ext.h"
+namespace OHOS {
+
+#define CLICK_HEART_STOP "click_heart_stop"
+#define CLICK_HEART_RESTART "click_heart_restart"
+
+    class HeartNoteView 
+    {
+    public:
+        HeartNoteView();
+        virtual ~HeartNoteView();
+        UIScrollView *CreateHeartNoteView(void);
+
+      private:
+        bool CrearAllView();
+        // 提醒图标
+        UIImageView *noteimage = nullptr;
+        // 按键
+        UILabelButtonExt *StButton = nullptr;
+        UILabelButtonExt *ReButton = nullptr;
+        // 提醒label
+        UILabelExt *titleLabel = nullptr;
+        UILabelExt *noteLabel = nullptr;
+        UIScrollView *heartNoteView = nullptr;
+    };
+}
+
+#endif // 血氧主界面
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartRateCardView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartRateCardView.h
new file mode 100644 (file)
index 0000000..cdab034
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef HEART_RATECARD_VIEW_H
+#define HEART_RATECARD_VIEW_H
+
+#include "components/root_view.h"
+#include "components/ui_card_page.h"
+#include "heartrate/include/HeartChartView.h"
+#include "wearable_log.h"
+namespace OHOS {
+
+class HeartRateCardView : public UICardPage {
+public:
+  HeartRateCardView();
+  virtual ~HeartRateCardView();
+  static HeartRateCardView *GetInstance(void);
+
+  bool InitView(void);
+  void PreLoad(void) override;
+  void UnLoad(void) override;
+  UIViewGroup *GetHeartRateCardView();
+
+private:
+  HeartChartView *heartRateCardView{nullptr};
+  UIViewGroup *heartRateGroupView{nullptr};
+  void ClearAll(void);
+  bool viewiInitStatus{false};
+};
+
+} // namespace OHOS
+#endif
\ No newline at end of file
index 1d94d89..8117440 100644 (file)
@@ -9,6 +9,7 @@
 #define HEART_RATE_VIEW_H\r
 \r
 #include "View.h"\r
+\r
 #include "components/ui_image_animator.h"\r
 #include "components/ui_chart.h"\r
 #include "wearable_log.h"\r
@@ -16,7 +17,8 @@
 #include "components/ui_card_page.h"\r
 #include "HeartModel.h"\r
 \r
-namespace OHOS {\r
+namespace OHOS\r
+{\r
 #define HEART_AVE_NUM 360\r
 #define HEART_RATE_LIMIT_UPPER 200\r
 #define HEART_RATE_LIMIT_LOWER 0\r
@@ -31,74 +33,88 @@ namespace OHOS {
 #define NUM_16 16\r
 #define NUM_99 99\r
 \r
-class HeartRateView : public UICardPage {\r
-public:\r
-    HeartRateView();\r
-    ~HeartRateView() override;\r
-    static HeartRateView *GetInstance(void);\r
+    class HeartRateView : public UICardPage\r
+    {\r
+    public:\r
+        HeartRateView();\r
+        ~HeartRateView() override;\r
+        static HeartRateView *GetInstance(void);\r
+\r
+        bool InitView(void);\r
+        void PreLoad(void) override;\r
+        void UnLoad(void) override;\r
+        int32_t SetHeartRateData(Point *rateData, uint32 rateDataSize); // 设置心率数据,用于画心率曲线\r
+        void RefreshElectrocardiogram(void);                            // 刷新心率曲线\r
+        void ClearElectrocardiogram(void);                              // 清空心率曲线\r
+        void RefreshHeartRatePerSec(uint16_t value);                    // 刷新每秒心率\r
+        void RefreshHeartRateMax(uint16_t max);                         // 刷新心率最大值\r
+        void RefreshHeartRateMin(uint16_t min);                         // 刷新心率最小值\r
+        void RefreshRestHeartRate(uint16_t value);                      // 刷新静息心率\r
+        void HeartbeatImageAnimatorStart(void);                         // 心形动画启动\r
+        void HeartbeatImageAnimatorStop(void);                          // 心形动画停止\r
+        void InitRefreshInterface(void);\r
+        void InitChartTest(void);\r
+        void Init_data_Chart();\r
+        void Update_data_Chart(int serialIndex);\r
+        void UpdataChart();\r
+        void CleanAllDataView();\r
 \r
-    bool InitView(void);\r
-    void PreLoad(void) override;\r
-    void UnLoad(void) override;\r
-    int32_t SetHeartRateData(Point *rateData, uint32 rateDataSize); // 设置心率数据,用于画心率曲线\r
-    void RefreshElectrocardiogram(void); // 刷新心率曲线\r
-    void ClearElectrocardiogram(void); // 清空心率曲线\r
-    void RefreshHeartRatePerSec(uint16_t value); // 刷新每秒心率\r
-    void RefreshHeartRateMax(uint16_t max); // 刷新心率最大值\r
-    void RefreshHeartRateMin(uint16_t min); // 刷新心率最小值\r
-    void RefreshRestHeartRate(uint16_t value); // 刷新静息心率\r
-    void HeartbeatImageAnimatorStart(void); // 心形动画启动\r
-    void HeartbeatImageAnimatorStop(void); // 心形动画停止\r
-    void InitRefreshInterface(void);\r
+    private:\r
+        typedef struct\r
+        {\r
+            uint8_t fontSize;\r
+            int16 x;\r
+            int16 y;\r
+            int16 width;\r
+            int16 height;\r
+        } LabelInfo;\r
 \r
-private:\r
-    typedef struct {\r
-        uint8_t fontSize;\r
-        int16 x;\r
-        int16 y;\r
-        int16 width;\r
-        int16 height;\r
-    } LabelInfo;\r
+        int32_t InitHeartRateData(void);\r
+        void SetLabel(UILabel *label, LabelInfo labelInfo);\r
+        void HeartRateLabelDisplay(void);\r
+        void HeartRateCoordinate(void);\r
+        void HeartRateElectrocardiogram(void);\r
+        void InsertTopAndBottomRateImage(void);\r
+        void UpdataTopAndBottomRate(void);\r
+        void ElectrocardiogramOnePoint(Point *rateData, uint16_t index);\r
+        void ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume);\r
+        int32_t HeartRateDataProc(void);\r
+        void HeartbeatImageAnimator(void);\r
+        void SetDataTopAndBottom();\r
 \r
-    int32_t InitHeartRateData(void);\r
-    void SetLabel(UILabel *label, LabelInfo labelInfo);\r
-    void HeartRateLabelDisplay(void);\r
-    void HeartRateCoordinate(void);\r
-    void HeartRateElectrocardiogram(void);\r
-    void InsertTopAndBottomRateImage(void);\r
-    void UpdataTopAndBottomRate(void);\r
-    void ElectrocardiogramOnePoint(Point *rateData, uint16_t index);\r
-    void ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume);\r
-    int32_t HeartRateDataProc(void);\r
-    void HeartbeatImageAnimator(void);\r
+    private:\r
+        Point heartRateData[HEART_AVE_NUM];\r
+        Point rateDataTmp[HEART_AVE_NUM];\r
 \r
-private:\r
-    Point heartRateData[HEART_AVE_NUM];\r
-    Point rateDataTmp[HEART_AVE_NUM];\r
+        void PreLoadHeartRateImageRes(void);\r
+        void UnLoadHeartRateImageRes(void);\r
+        bool viewiInitStatus{false};\r
+        bool resLoadStatus{false};\r
+        UIChartPolyline *chart{nullptr};\r
+        uint16_t dataNume;  // 心率曲线记录数据总个数\r
+        uint16_t currIndex; // 当前已显示心率曲线心率个数\r
+        UIChartDataSerial *dataSerial[HEART_AVE_NUM]{nullptr};\r
+        UIChartDataSerial *dataTopAndbottom{nullptr};\r
+        UIImageView *imageViewTop{nullptr};\r
+        UIImageView *imageViewBottom{nullptr};\r
+        uint16_t serialIndex;\r
+        UIImageAnimatorView *imageAnimator{nullptr};\r
+        UIImageView *imageViewCoordinate{nullptr};\r
 \r
-    bool viewiInitStatus{false};\r
-    bool resLoadStatus{false};\r
-    UIChartPolyline *chart{nullptr};\r
-    uint16_t dataNume; // 心率曲线记录数据总个数\r
-    uint16_t currIndex; // 当前已显示心率曲线心率个数\r
-    UIChartDataSerial *dataSerial[HEART_AVE_NUM]{nullptr};\r
-    UIChartDataSerial *dataTopAndbottom{nullptr};\r
-    UIImageView *imageViewTop{nullptr};\r
-    UIImageView *imageViewBottom{nullptr};\r
-    uint16_t serialIndex;\r
-    UIImageAnimatorView *imageAnimator{nullptr};\r
-    UIImageView *imageViewCoordinate{nullptr};\r
+        UILabel *topRate{nullptr};\r
+        UILabel *bottomRate{nullptr};\r
+        UILabel *ratePerSec{nullptr};\r
+        UILabel *ratePerSecText{nullptr};\r
+        UILabel *restRate{nullptr};\r
+        UILabel *restRateText1{nullptr};\r
+        UILabel *restRateText2{nullptr};\r
 \r
-    UILabel *topRate{nullptr};\r
-    UILabel *bottomRate{nullptr};\r
-    UILabel *ratePerSec{nullptr};\r
-    UILabel *ratePerSecText{nullptr};\r
-    UILabel *restRate{nullptr};\r
-    UILabel *restRateText1{nullptr};\r
-    UILabel *restRateText2{nullptr};\r
+        uint16_t maxRate;\r
+        uint16_t minRate;\r
 \r
-    uint16_t maxRate;\r
-    uint16_t minRate;\r
-};\r
+        Point heartdata[24];\r
+        UIChartDataSerial *heartSerial{nullptr};\r
+        UIChartPolyline *heartchart = nullptr;\r
+    };\r
 } // namespace OHOS\r
 #endif // HEART_RATE_VIEW_H\r
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartResultPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartResultPresenter.h
new file mode 100644 (file)
index 0000000..f3cf855
--- /dev/null
@@ -0,0 +1,53 @@
+/*** 
+ * @Date: 2024-07-31 10:27:08
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-31 10:31:42
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartResultPresenter.h
+ */
+
+
+#ifndef HEART_RESULT_PRESENTER_H
+#define HEART_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 "battery_hal.h"
+
+#include "heartrate/include/HeartResultView.h"
+
+namespace OHOS
+{
+    static constexpr const char *CLICK_HEART = "clickheart"; // 心率检测
+
+    class HeartResultView;
+    class HeartResultPresenter : public Presenter<HeartResultView>,
+                                 public UIView::OnClickListener,
+                                 public RootView::OnKeyActListener,
+                                 public UIView::OnDragListener
+    {
+    public:
+        HeartResultPresenter();
+        virtual ~HeartResultPresenter();
+        static HeartResultPresenter *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/heartrate/include/HeartResultView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/include/HeartResultView.h
new file mode 100644 (file)
index 0000000..62b3738
--- /dev/null
@@ -0,0 +1,49 @@
+
+#ifndef HEART_Result_VIEW_H
+#define HEART_Result_VIEW_H
+
+#include "View.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 "heartrate/include/HeartResultPresenter.h"
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_button_ext.h"
+namespace OHOS
+{
+    class HeartResultPresenter;
+    class HeartResultView : public View<HeartResultPresenter>
+    {
+    public:
+        HeartResultView();
+        virtual ~HeartResultView();
+        static HeartResultView *GetInstance(void);
+
+        void OnStart() override;
+
+        bool HeartResultViewInit();
+        void UpHeartText(void);
+
+        void DeInit();
+        bool AddButton();
+        bool InitLable();
+        bool Initbackground();
+
+    private:
+        UIImageView *background = nullptr;
+        UILabelExt *titleLabel = nullptr;
+        UILabelExt *timeLabel = nullptr;
+        UILabel *heartLabel = nullptr;
+        UILabelButtonExt *checkButton{nullptr};
+    };
+}
+
+#endif // 心率主界面
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartChartPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartChartPresenter.cpp
new file mode 100644 (file)
index 0000000..b6346b5
--- /dev/null
@@ -0,0 +1,141 @@
+/*** 
+ * @Date: 2024-08-15 18:39:25
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-09-03 21:04:56
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartChartPresenter.cpp
+ */
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: HeartChartPresenter.cpp
+ * Author:
+ * Create: 2021-11-23
+ */
+
+#include "heartrate/include/HeartChartView.h"
+#include "heartrate/include/HeartChartPresenter.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 "heartrate/include/HeartModel.h"
+#include "MainModel.h"
+#include "gfx_utils/mem_check.h"
+
+#include "NativeRegisterManager.h"
+
+namespace OHOS
+{
+
+    REGIST_MENU_PRO(VIEW_HEART_CHART, HeartChartView, HeartChartPresenter,
+        PNG_APPLIST_HEART_IMAGE_BIG, PNG_APPLIST_HEART_IMAGE,PNG_APPLIST_HEART_IMAGE, "心率", STR_HEART_RATE);
+
+    // 当前Presenter属性实例化的内存指针
+    static HeartChartPresenter *g_pHeartChartPresenter = nullptr;
+    HeartChartPresenter::HeartChartPresenter()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartChartPresenter::HeartChartPresenter");
+        g_pHeartChartPresenter = this;
+#ifdef MEM_CHECK
+        MemCheck::GetInstance()->EnableLeakCheck(true);
+#endif
+    }
+
+    HeartChartPresenter::~HeartChartPresenter()
+    {
+        g_pHeartChartPresenter = nullptr;
+#ifdef MEM_CHECK
+        MemCheck::GetInstance()->EnableLeakCheck(false);
+#endif
+    }
+    HeartChartPresenter *HeartChartPresenter::GetInstance()
+    {
+        return g_pHeartChartPresenter;
+    }
+    void HeartChartPresenter::NavigateBack()
+    {
+        NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+    }
+    void HeartChartPresenter::OnStart()
+    {
+        Presenter<HeartChartView>::OnStart();
+        if (!HeartCheckState)
+        {
+            HeartModel::GetInstance()->Heart_Start(HeartCheck::INITIATIVE);
+            HeartCheckState = true;
+        }
+    }
+    void HeartChartPresenter::OnResume(void)
+    {
+    }
+
+    void HeartChartPresenter::OnStop(void)
+    {
+        if (HeartCheckState)
+        {
+            HeartModel::GetInstance()->Heart_Stop();
+            HeartModel::GetInstance()->Heart_Control(HeartState::End, HeartCheck::INITIATIVE); // 主动检测心率关闭
+            HeartCheckState = false;
+        }
+    }
+
+    bool HeartChartPresenter::OnDrag(UIView &view, const DragEvent &event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartChartPresenter::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 false;
+    }
+
+    bool HeartChartPresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        if (strcmp(view.GetViewId(), STOPCHECK) == 0)
+        {
+            NavigateBack();
+        }
+        return true;
+    }
+
+    void HeartChartPresenter::OnTickEvent()
+    {
+        // 更新显示心率数据
+        if(HeartChartView::GetInstance() == nullptr)
+        {
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartChartView::GetInstance()==nullptr");
+            return;
+        }
+
+        uint64_t current_time = osKernelGetTick2ms();
+        if ((startTime != 0) && (current_time - startTime >= HEART_KEEP_TIME))
+        {
+            // 超时处理
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "检测结果: 超时处理 HEART_KEEP_TIME: %lld", current_time - startTime);
+            HeartModel::GetInstance()->SetResult(HeartResult::TIMEOUT);
+            HeartModel::GetInstance()->Heart_Stop();
+            return;
+        }
+
+        HeartChartView::GetInstance()->UpdateShowHeart(); 
+    }
+
+    // 增加按键事件
+    bool HeartChartPresenter::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/heartrate/src/HeartChartView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartChartView.cpp
new file mode 100644 (file)
index 0000000..aabb4ce
--- /dev/null
@@ -0,0 +1,634 @@
+/***
+ * @Date: 2024-08-15 18:39:02
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-09-05 14:36:17
+ * @FilePath:
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartChartView.cpp
+ */
+/***
+ * @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/fd230app/nativeui/heartrate/src/HeartChartView.cpp
+ */
+#include "HeartChartView.h"
+#include "HeartModel.h"
+#include "UiConfig.h"
+#include "heart_blood/health_service/health_service.h"
+#include "power_display_service.h"
+#include "ui_image_animator.h"
+#include "ui_resource_string.h"
+#include "uicomponents/UIComponents.h"
+#include "wearable_log.h"
+namespace OHOS {
+static HeartChartView *g_pHeartCheckView = nullptr;
+
+// 动态刷新设置
+static constexpr uint16_t IMAGE_SIZE = 180;
+static constexpr uint16_t IMAGE_POSITION_Y = 134;
+static constexpr uint16_t IMAGE_POSITION_X = 150;
+static constexpr uint16_t Chart_IMAGE_ANIMATORVIEW_SIZE = 20;
+static constexpr uint16_t Chart_IMAGE_ANIMATORVIEW_SPEED = 40;
+// 图片路径
+static constexpr const char *BACKGROUND_IMAGE_PATH =
+    "/user/res/heart_chart/background.bin";
+static constexpr const char *BUTTOM_ICON_PATH =
+    "/user/res/heart_chart/buttomicon.bin";
+static constexpr const char *TOP_ICON_PATH =
+    "/user/res/heart_chart/topicon.bin";
+static constexpr const char *HEART_ICON_PATH =
+    "/user/res/heart_chart/hearticon.bin";
+// 心形心跳
+static constexpr int HEARTBEAT_IMAGE_WIDTH = 54;
+static constexpr int HEARTBEAT_IMAGE_HEIGHT = 50;
+static constexpr int HEARTBEAT_IMAGE_X = 111;
+static constexpr int HEARTBEAT_IMAGE_Y = 57;
+static constexpr int HEARTBEAT_IMAGE_NUM = 21;
+static constexpr int HEARTBEAT_DELAY = 50;
+// 心跳image
+static ImageAnimatorInfo g_heartImageInfo[HEARTBEAT_IMAGE_NUM] = {
+    {PNG_A004_070_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_071_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_072_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_073_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_074_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_075_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_076_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_077_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_078_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_079_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_080_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_081_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_082_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_083_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_084_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_085_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_086_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_087_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_088_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_089_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+    {PNG_A004_090_IMAGE_PATH,
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},
+     HEARTBEAT_IMAGE_WIDTH,
+     HEARTBEAT_IMAGE_HEIGHT,
+     IMG_SRC_FILE_PATH},
+};
+
+HeartChartView::HeartChartView() {
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::HeartBandoffView");
+  g_pHeartCheckView = this;
+}
+HeartChartView::~HeartChartView() {
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartChartView::~HeartChartView");
+
+  if (displayheart_) {
+    delete displayheart_;
+    displayheart_ = nullptr;
+  }
+  if (maxheart_) {
+    delete maxheart_;
+    maxheart_ = nullptr;
+  }
+  if (minheart_) {
+    delete minheart_;
+    minheart_ = nullptr;
+  }
+  if (uheart_) {
+    delete uheart_;
+    uheart_ = nullptr;
+  }
+  if (lastheart_) {
+    delete lastheart_;
+    lastheart_ = nullptr;
+  }
+  if (maxheart_dynamic_) {
+    delete maxheart_dynamic_;
+    maxheart_dynamic_ = nullptr;
+  }
+  if (maxheart_dynamic_3_) {
+    delete maxheart_dynamic_3_;
+    maxheart_dynamic_3_ = nullptr;
+  }
+  if (maxheart_dynamic_2_) {
+    delete maxheart_dynamic_2_;
+    maxheart_dynamic_2_ = nullptr;
+  }
+  if (maxheart_dynamic_1_) {
+    delete maxheart_dynamic_1_;
+    maxheart_dynamic_1_ = nullptr;
+  }
+  if (minheart_dynamic_) {
+    delete minheart_dynamic_;
+    minheart_dynamic_ = nullptr;
+  }
+
+  if (maxRateIconView_) {
+    delete maxRateIconView_;
+    maxRateIconView_ = nullptr;
+  }
+  if (minRateIconView_) {
+    delete minRateIconView_;
+    minRateIconView_ = nullptr;
+  }
+  if (chartBackgroundView_) {
+    delete chartBackgroundView_;
+    chartBackgroundView_ = nullptr;
+  }
+  if (heartIconView_) {
+    delete heartIconView_;
+    heartIconView_ = nullptr;
+  }
+
+  if (imageAnimator) {
+    imageAnimator->Stop();
+    delete imageAnimator;
+    imageAnimator = nullptr;
+  }
+
+  if (heartSerial) {
+    heartchart->ClearDataSerial();
+    delete heartSerial;
+    heartSerial = nullptr;
+  }
+
+  if (heartchart) {
+    delete heartchart;
+    heartchart = nullptr;
+  }
+
+  g_pHeartCheckView = nullptr;
+}
+HeartChartView *HeartChartView::GetInstance(void) { return g_pHeartCheckView; }
+
+/* 更新显示数据 */
+void HeartChartView::UpdateShowHeart() {
+
+  if (displayheart_ == nullptr) {
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                  "HeartChartView::UpdateShowHeart is error");
+    return;
+  }
+
+  // 获取当前心率
+  uint16_t heart_ = HeartModel::GetInstance()->GetShowHeartdata();
+  std::string heartrateStr =
+      (heart_ == 0) ? "--" : (heart_ < 50 ? "--" : std::to_string(heart_));
+  // 更新当前心率显示
+  if (displayheart_ != nullptr) {
+    displayheart_->SetText(heartrateStr.c_str());
+  }
+}
+void HeartChartView::Update_data_Chart(int serialIndex) {
+  if (heartchart == nullptr) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Update_data_Chart fail %d",
+                  serialIndex);
+    return;
+  }
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"开始更新曲线");
+  /*清除原数据*/
+  heartSerial->ClearData();
+
+  /*更新所有项*/
+  for (int serialIndex = 0; serialIndex < 24; serialIndex++) {
+    heartdata[serialIndex].x = serialIndex;
+    heartdata[serialIndex].y =
+        HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"x:%d,y:%d\n", heartdata[serialIndex].x,heartdata[serialIndex].y);
+  }
+  /*重新添加*/
+  heartSerial->AddPoints(heartdata, 24);
+  heartSerial->SetLineColor(Color::Red());
+  heartSerial->SetFillColor(Color::Red());
+  heartSerial->EnableGradient(true);
+
+  // heartSerial->Refresh();
+
+  heartchart->AddDataSerial(heartSerial);
+
+  // heartchart->RefreshChart();
+
+  RootView::GetInstance()->Invalidate();
+
+  //更新为刚刚检测
+  SetLastHeart();
+
+  //更新最大最小值
+  SetDataTopAndBottom();
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"更新更新曲线完成");
+}
+void HeartChartView::CleanAllDataView() {
+  if (heartchart == nullptr || maxheart_ == nullptr || minheart_ == nullptr) {
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " CleanAllDataView fail");
+    return;
+  }
+  for (int serialIndex = 0; serialIndex < 24; serialIndex++) {
+    heartdata[serialIndex].x = serialIndex;
+    heartdata[serialIndex].y =
+        HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);
+  }
+
+  /*清空原数据*/
+  heartSerial->ClearData();
+  heartSerial->AddPoints(heartdata, 24);
+  heartSerial->SetLineColor(Color::Red());
+  heartSerial->SetFillColor(Color::Red());
+  heartSerial->EnableGradient(true);
+
+  heartchart->AddDataSerial(heartSerial);
+  // heartchart->RefreshChart();
+
+  /*更新最大最小值*/
+  SetDataTopAndBottom();
+}
+/*设置最大最小数据*/
+void HeartChartView::SetDataTopAndBottom() {
+  int MaxHeart = HeartModel::GetInstance()->GetShowMaxHeartdata();
+  int MinHeart = HeartModel::GetInstance()->GetShowMinHeartdata();
+
+  if (maxheart_ != nullptr) {
+    maxheart_->SetText(MaxHeart > 0 ? (std::to_string(MaxHeart)).c_str()
+                                    : "--");
+  }
+
+  if (minheart_ != nullptr) {
+    minheart_->SetText(MinHeart > 0 ? (std::to_string(MinHeart)).c_str()
+                                    : "--");
+  }
+
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MaxHeart: %d, MinHeart: %d", MaxHeart,
+                MinHeart);
+}
+/*设置曲线图数据*/
+void HeartChartView::SetDataChart() {
+  if (heartchart == nullptr) {
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Init_data_Chart new chart fail");
+    return;
+  }
+  heartSerial = new UIChartDataSerial();
+  heartSerial->SetMaxDataCount(24);
+#if HEART_DATA_TEST
+  Point temp[] = {{0, 150},  {1, 250},  {2, 170},  {3, 0},    {4, 140},
+                  {5, 190},  {6, 100},  {7, 40},   {8, 10},   {9, 100},
+                  {10, 60},  {11, 20},  {12, 150}, {13, 250}, {14, 170},
+                  {15, 140}, {16, 78},  {17, 80},  {18, 100}, {19, 20},
+                  {20, 100}, {21, 100}, {22, 100}, {23, 100}};
+  std::copy(std::begin(temp), std::end(temp), heartdata);
+#else
+  for (int serialIndex = 0; serialIndex < 24; serialIndex++) {
+    heartdata[serialIndex].x = serialIndex;
+    heartdata[serialIndex].y =
+        HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);
+  }
+#endif
+  heartSerial->AddPoints(heartdata, 24);
+  heartSerial->SetLineColor(Color::Red());
+  heartSerial->SetFillColor(Color::Red());
+  heartSerial->EnableGradient(true);
+
+  heartchart->AddDataSerial(heartSerial);
+  heartchart->Invalidate();
+}
+/*设置心率动画*/
+void HeartChartView::HeartImageAnimator() {
+  imageAnimator = new UIImageAnimatorView();
+  if (imageAnimator == nullptr) {
+    WEARABLE_LOGD(
+        WEARABLE_LOG_MODULE_APP,
+        "HeartRateView::[HeartbeatImageAnimator] new imageAnimator fail");
+    return;
+  }
+  imageAnimator->SetPosition(HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y,
+                             HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT);
+  imageAnimator->SetImageAnimatorSrc(g_heartImageInfo, HEARTBEAT_IMAGE_NUM,
+                                     HEARTBEAT_DELAY);
+  imageAnimator->SetRepeat(true);
+  AddViewToRootContainer(imageAnimator);
+  // imageAnimator->Start();
+}
+/*初始化心率曲线*/
+void HeartChartView::InitChartView(void) {
+  if (heartchart == nullptr) {
+    heartchart = new UIChartPolyline();
+  }
+  heartchart->SetPosition(80, 199);
+  heartchart->Resize(313, 122);
+  heartchart->SetViewId("uiChart1");
+  heartchart->SetStyle(STYLE_BACKGROUND_OPA, 0x00);
+
+  UIXAxis &heartXAxis = heartchart->GetXAxis();
+  heartXAxis.SetMarkNum(24);
+  heartXAxis.SetDataRange(0, 24);
+  heartXAxis.SetLineColor(Color::GetColorFromRGBA(0x33, 0x33, 0x33, 0xff));
+
+  UIYAxis &heartYAxis = heartchart->GetYAxis();
+  heartYAxis.SetMarkNum(4);
+  heartYAxis.SetDataRange(0, 220);
+  heartYAxis.SetLineColor(Color::GetColorFromRGBA(0x33, 0x33, 0x33, 0xff));
+
+  heartchart->SetGradientOpacity(78, 64);
+
+  // Add to rootView
+  AddViewToRootContainer(heartchart);
+}
+
+//初始化label
+/*
+需要显示一个动态心率的效果
+有5个label代表 曲线图的y轴
+    最大心率+10
+    最大心率+10-(最小心率-10)*3/4
+    最大心率+10-(最小心率-10)*2/4
+    最大心率+10-(最小心率-10)*1/4
+    最小心率-10
+*/
+void HeartChartView::InitChartLabel() {
+  //当前心率值
+  InitLabel(displayheart_, 133, 32, 200, 100, "label", "--", GILROY_BOLD_FONT,
+            65);
+  // 单位
+  InitRollLabel(uheart_, 283, 52, 100, 60, "label", STR_TIMES_PER_MIN,
+                DEFAULT_VECTOR_FONT_FILENAME, 30);
+  uheart_->SetTextColor(Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff));
+  //上一次检测信息
+  InitLabel(lastheart_, 53, 130, 360, 35, "label", "--",
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 30);
+  lastheart_->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION);
+  lastheart_->SetRollSpeed(23);
+  //最小心率 不居中
+  InitLabelAdapt(minheart_, 293, 380, 200, 35, "label", "--",
+                 DEFAULT_VECTOR_FONT_FILENAME_EN, 35);
+  //最大心率 不居中
+  InitLabelAdapt(maxheart_, 158, 380, 200, 35, "label", "--",
+                 DEFAULT_VECTOR_FONT_FILENAME_EN, 35);
+
+  //动态心率最大
+  InitLabel(maxheart_dynamic_, 30, 190, 50, 20, "label", "220",
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 20);
+  maxheart_dynamic_->SetTextColor(
+      Color::GetColorFromRGBA(0x33, 0x33, 0x33, 0xff));
+  //动态心率3/4
+  InitLabel(maxheart_dynamic_3_, 30, 218, 50, 20, "label", "160",
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 20);
+  maxheart_dynamic_3_->SetTextColor(
+      Color::GetColorFromRGBA(0x33, 0x33, 0x33, 0xff));
+  //动态心率2/4
+  InitLabel(maxheart_dynamic_2_, 30, 247, 50, 20, "label", "110",
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 20);
+  maxheart_dynamic_2_->SetTextColor(
+      Color::GetColorFromRGBA(0x33, 0x33, 0x33, 0xff));
+  //动态心率1/4
+  InitLabel(maxheart_dynamic_1_, 30, 277, 50, 20, "label", "50",
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 20);
+  maxheart_dynamic_1_->SetTextColor(
+      Color::GetColorFromRGBA(0x33, 0x33, 0x33, 0xff));
+  //动态心率最小
+  InitLabel(minheart_dynamic_, 30, 306, 50, 20, "label", "0",
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 20);
+  minheart_dynamic_->SetTextColor(
+      Color::GetColorFromRGBA(0x33, 0x33, 0x33, 0xff));
+
+  AddViewToRootContainer(displayheart_);
+  AddViewToRootContainer(uheart_);
+  AddViewToRootContainer(lastheart_);
+  AddViewToRootContainer(minheart_);
+  AddViewToRootContainer(maxheart_);
+  AddViewToRootContainer(maxheart_dynamic_);
+  AddViewToRootContainer(maxheart_dynamic_3_);
+  AddViewToRootContainer(maxheart_dynamic_2_);
+  AddViewToRootContainer(maxheart_dynamic_1_);
+  AddViewToRootContainer(minheart_dynamic_);
+}
+
+void HeartChartView::InitChartImageView() {
+
+  if (minRateIconView_ == nullptr) {
+    minRateIconView_ = new UIImageView();
+  }
+  minRateIconView_->SetPosition(266, 394);
+  minRateIconView_->Resize(100, 100);
+  minRateIconView_->SetViewId("minRateIcon");
+  minRateIconView_->SetSrc(BUTTOM_ICON_PATH);
+  if (maxRateIconView_ == nullptr) {
+    maxRateIconView_ = new UIImageView();
+  }
+  maxRateIconView_->SetPosition(129, 394);
+  maxRateIconView_->Resize(100, 100);
+  maxRateIconView_->SetViewId("maxRateIcon");
+  maxRateIconView_->SetSrc(TOP_ICON_PATH);
+
+  if (chartBackgroundView_ == nullptr) {
+    chartBackgroundView_ = new UIImageView();
+  }
+  chartBackgroundView_->SetPosition(30, 160);
+  chartBackgroundView_->Resize(100, 100);
+  chartBackgroundView_->SetViewId("chartBackground");
+  chartBackgroundView_->SetSrc(BACKGROUND_IMAGE_PATH);
+
+  AddViewToRootContainer(chartBackgroundView_);
+  AddViewToRootContainer(minRateIconView_);
+  AddViewToRootContainer(maxRateIconView_);
+
+  if (heartIconView_ == nullptr) {
+    heartIconView_ = new UIImageView();
+  }
+  heartIconView_->SetPosition(111, 57);
+  heartIconView_->Resize(100, 100);
+  heartIconView_->SetViewId("heartIcon");
+  heartIconView_->SetSrc(HEART_ICON_PATH);
+
+  AddViewToRootContainer(heartIconView_);
+  heartIconView_->SetVisible(true);
+#if 0
+  if (lineView_ == nullptr) {
+    lineView_ = new UIImageView();
+  }
+  lineView_->SetPosition(230, 385);
+  lineView_->Resize(1, 26);
+  lineView_->SetViewId("lineView");
+  lineView_->SetStyle(STYLE_BACKGROUND_COLOR, 0xff666666);
+  lineView_->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+
+  AddViewToRootContainer(lineView_);
+  lineView_->SetVisible(true);
+#endif
+}
+
+//更新图表配置
+void HeartChartView::UpdateChartConfig() {
+  if (minheart_dynamic_ == nullptr || maxheart_dynamic_1_ == nullptr ||
+      maxheart_dynamic_2_ == nullptr || maxheart_dynamic_3_ == nullptr ||
+      heartchart == nullptr) {
+    return;
+  }
+
+  // 获取动态心率数据
+  HeartModel::GetInstance()->SetArrayData();
+  uint16_t *dynamicArray = HeartModel::GetInstance()->GetArrayData();
+
+  //更新label
+  if (dynamicArray) {
+    minheart_dynamic_->SetText(std::to_string(dynamicArray[0]).c_str());
+    maxheart_dynamic_1_->SetText(std::to_string(dynamicArray[1]).c_str());
+    maxheart_dynamic_2_->SetText(std::to_string(dynamicArray[2]).c_str());
+    maxheart_dynamic_3_->SetText(std::to_string(dynamicArray[3]).c_str());
+    maxheart_dynamic_->SetText(std::to_string(dynamicArray[4]).c_str());
+  }
+  //更新chart
+  UIYAxis &heartYAxis = heartchart->GetYAxis();
+  heartYAxis.SetMarkNum(4);
+  heartYAxis.SetDataRange(dynamicArray[0], dynamicArray[4]);
+  heartYAxis.SetLineColor(Color::GetColorFromRGBA(0x33, 0x33, 0x33, 0xff));
+  heartchart->Invalidate();
+}
+//更新上一次检测信息
+void HeartChartView::SetLastHeart() {
+  if (lastheart_ == nullptr)
+    return;
+  std::string lastStr = HeartModel::GetInstance()->GetCheckString();
+  lastheart_->SetText(lastStr.c_str());
+}
+
+void HeartChartView::HeartbeatImageAnimatorStart() {
+  if (imageAnimator != nullptr) {
+    imageAnimator->Start();
+  }
+}
+
+void HeartChartView::HeartbeatImageAnimatorStop() {
+  if (imageAnimator != nullptr) {
+    imageAnimator->Stop();
+  }
+}
+/*初始化检测界面*/
+bool HeartChartView::HeartViewInit() {
+
+  //图片
+  InitChartImageView();
+  //标签
+  InitChartLabel();
+
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartChartViewInit is ok");
+  return true;
+}
+UIViewGroup *HeartChartView::GetchartGroup() {
+
+  if (!HeartViewInit()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "HeartChartView::InitHeartView fail");
+  }
+  HeartImageAnimator(); //暂时屏蔽
+  InitChartView();
+  // UpdateChartConfig(); 屏蔽动态适配
+  SetDataChart();
+  SetLastHeart();
+  SetDataTopAndBottom();
+  HeartbeatImageAnimatorStart();
+
+  return GetRootContainer();
+}
+void HeartChartView::OnStart() {
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartChartView::OnStart");
+  View<HeartChartPresenter>::OnStart();
+
+
+  if (!HeartViewInit()) {
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                  "HeartChartView::InitHeartView fail");
+  }
+
+  HeartImageAnimator();
+  InitChartView();
+  // UpdateChartConfig(); 屏蔽动态适配
+  SetDataChart();
+  SetLastHeart();
+  SetDataTopAndBottom();
+  HeartbeatImageAnimatorStart();
+
+  // 增加按键监听
+  RootView::OnKeyActListener *keyactListener =
+      (RootView::OnKeyActListener *)OHOS::HeartChartPresenter::GetInstance();
+  RootView::GetInstance()->SetOnKeyActListener(keyactListener);
+}
+
+} // namespace OHOS
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartDetectionPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartDetectionPresenter.cpp
new file mode 100644 (file)
index 0000000..75033b0
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: HeartDetectionPresenter.cpp
+ * Author:
+ * Create: 2021-11-23
+ */
+
+#include "heartrate/include/HeartDetectionView.h"
+#include "heartrate/include/HeartDetectionPresenter.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 "heartrate/include/HeartModel.h"
+#include "MainModel.h"
+#include "NativeRegisterManager.h"
+namespace OHOS
+{
+
+    REGIST_SLICE(VIEW_HEART_CHECK, HeartDetectionView, HeartDetectionPresenter);
+
+    // 当前Presenter属性实例化的内存指针
+    static HeartDetectionPresenter *g_pHeartDetectionPresenter = nullptr;
+
+    HeartDetectionPresenter::HeartDetectionPresenter()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartDetectionPresenter::HeartDetectionPresenter");
+        g_pHeartDetectionPresenter = this;
+        // display_time = DisplayBrightnessModel::GetInstance()->GetScreenDurationTime(); //需要配置公共接口 
+        display_time = 5*1000;
+        display_api->set_screen_auto_off_timeout(300 * 1000); // 设置常亮
+        ResetTickTimer();
+    }
+
+    HeartDetectionPresenter::~HeartDetectionPresenter()
+    {
+        display_api->set_screen_auto_off_timeout(display_time); // 恢复
+        g_pHeartDetectionPresenter = nullptr;
+    }
+    HeartDetectionPresenter *HeartDetectionPresenter::GetInstance()
+    {
+        return g_pHeartDetectionPresenter;
+    }
+    void HeartDetectionPresenter::NavigateBack()
+    {
+        NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+    }
+    void HeartDetectionPresenter::OnStart()
+    {
+        Presenter<HeartDetectionView>::OnStart();
+        if (!HeartCheckState)
+        {
+            HeartModel::GetInstance()->Heart_Start(HeartCheck::INITIATIVE);
+            HeartCheckState = true;
+        }
+    }
+    void HeartDetectionPresenter::OnResume(void)
+    {
+    }
+
+    void HeartDetectionPresenter::OnStop(void)
+    {
+        if (HeartCheckState)
+        {
+            HeartModel::GetInstance()->Heart_Stop();
+            HeartCheckState = false;
+        }
+    }
+
+    bool HeartDetectionPresenter::OnDrag(UIView &view, const DragEvent &event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartDetectionPresenter::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 false;
+    }
+
+    bool HeartDetectionPresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        if (strcmp(view.GetViewId(), STOPCHECK) == 0)
+        {
+            NavigateBack();
+        }
+        return true;
+    }
+
+    void HeartDetectionPresenter::OnTickEvent()
+    {
+        // 更新显示心率数据
+        HeartDetectionView::GetInstance()->UpShowHeartText();
+        uint64_t current_time = osKernelGetTick2ms();
+        // printf("current_time diff: %d\r\n", (current_time - startTime));
+        if ((startTime != 0) && (current_time - startTime > HEART_KEEP_TIME))
+        {
+            // 超时处理
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果: 超时处理 HEART_KEEP_TIME: %lld", current_time - startTime);
+            HeartModel::GetInstance()->SetResult(HeartResult::TIMEOUT);
+            HeartModel::GetInstance()->Heart_Stop();
+        }
+    }
+    void HeartDetectionPresenter::ResetTickTimer(void)
+    {
+        startTime = osKernelGetTick2ms();
+    }
+    // 增加按键事件
+    bool HeartDetectionPresenter::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/heartrate/src/HeartDetectionView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartDetectionView.cpp
new file mode 100644 (file)
index 0000000..073da09
--- /dev/null
@@ -0,0 +1,152 @@
+/***
+ * @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/fd230app/nativeui/heartrate/src/HeartDetectionView.cpp
+ */
+#include "UiConfig.h"
+#include "wearable_log.h"
+#include "HeartDetectionView.h"
+#include "HeartModel.h"
+#include "ui_image_animator.h"
+#include "HeartDetectionView.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 = 134;
+    static constexpr uint16_t IMAGE_POSITION_X = 150;
+    static constexpr uint16_t DETECTION_IMAGE_ANIMATORVIEW_SIZE = 20;
+    static constexpr uint16_t DETECTION_IMAGE_ANIMATORVIEW_SPEED = 40;
+
+    static ImageAnimatorInfo g_imageAnimatorInfo_heart[20] = {
+        {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},
+    };
+
+    static HeartDetectionView *g_pHeartCheckView = nullptr;
+    HeartDetectionView::HeartDetectionView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::HeartBandoffView");
+        g_pHeartCheckView = this;
+    }
+    HeartDetectionView::~HeartDetectionView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartDetectionView::~HeartDetectionView");
+
+        delete titleLabel;
+        titleLabel = nullptr;
+
+        delete testButton;
+        testButton = nullptr;
+
+        imageAnimator->Stop();
+        delete imageAnimator;
+        imageAnimator = nullptr;
+
+        delete HeartText;
+        HeartText = nullptr;
+
+        g_pHeartCheckView = this;
+    }
+    HeartDetectionView *HeartDetectionView::GetInstance(void)
+    {
+        return g_pHeartCheckView;
+    }
+    UIImageAnimatorView *HeartDetectionView::GetImageAnimator()
+    {
+        return imageAnimator;
+    }
+
+    /*更新显示数据*/
+    void HeartDetectionView::UpShowHeartText()
+    {
+        uint16_t heart_ = HeartModel::GetInstance()->GetShowHeartdata();
+        std::string heartrateStr = std::to_string(heart_);
+        if (HeartText != nullptr)
+            HeartText->SetText(heartrateStr.c_str());
+    }
+    /*初始化检测界面*/
+    bool HeartDetectionView::HeartDetectionViewInit()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartDetectionViewInit is begin");
+        /*初始化title*/
+        InitLabelExt(titleLabel, 83, 50, 300, 35, "title", STR_CHECKON, DEFAULT_VECTOR_FONT_FILENAME, 30);
+        AddViewToRootContainer(titleLabel);
+
+        /* -------------------------------------------------------------------------- */
+        imageAnimator = new UIImageAnimatorView();
+        if (imageAnimator == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::new UIImageAnimatorView fail");
+            return false;
+        }
+        imageAnimator->SetImageAnimatorSrc(g_imageAnimatorInfo_heart, DETECTION_IMAGE_ANIMATORVIEW_SIZE, DETECTION_IMAGE_ANIMATORVIEW_SPEED);
+        imageAnimator->SetRepeat(true);
+        AddViewToRootContainer(imageAnimator);
+
+        /* -------------------------------------------------------------------------- */
+        /*初始化心率值label*/
+        InitUILabel(HeartText, 83, 83, 300, 300, "hearttext", "--", GILROY_BOLD_FONT, 140);
+        AddViewToRootContainer(HeartText);
+
+        /* -------------------------------------------------------------------------- */
+        InitButtonExt(testButton, 118, 336, 230, 80, STOPCHECK, STR_CHECKSTOP, 30);
+        AddViewToRootContainer(testButton);
+
+        /* -------------------------------------------------------------------------- */
+        UIView::OnClickListener *clickLeftListener = (UIView::OnClickListener *)OHOS::HeartDetectionPresenter::GetInstance();
+        if (clickLeftListener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartDetectionView::new clickLeftListener fail");
+            return false;
+        }
+        testButton->SetOnClickListener(clickLeftListener);
+        /* -------------------------------------------------------------------------- */
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartDetectionViewInit is ok");
+        return true;
+    }
+    void HeartDetectionView::OnStart()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartDetectionView::OnStart");
+       
+        if (!HeartDetectionViewInit())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartDetectionView::InitHeartView fail");
+        }
+
+
+     
+        GetRootContainer()->SetDraggable(true);
+        GetRootContainer()->SetTouchable(true);
+        GetRootContainer()->SetOnDragListener(presenter_);     
+        // GetRootContainer()->SetOnKeyActListener(presenter_);
+
+        if (imageAnimator != nullptr)
+        {
+            imageAnimator->Start();
+        }
+    }
+  
+}
index d7bdba3..7a343c6 100644 (file)
-#include "HeartModel.h"\r
-#include "wearable_log.h"\r
-#include "graphic_service.h"\r
+#include "heartrate/include/HeartModel.h"\r
 #include "IndoorWalkPreparedView.h"\r
 #include "IndoorWalkPresenter.h"\r
 #include "MainViewSample.h"\r
-#include "HeartRateView.h"\r
+#include "graphic_service.h"\r
+#include "wearable_log.h"\r
+\r
+#include "DialModelHeartRate.h"\r
+#include "heartrate/include/HeartChartView.h"\r
+#include "heartrate/include/HeartDetectionPresenter.h"\r
+#include "heartrate/include/HeartRateView.h"\r
+#include "heartrate/include/HeartResultPresenter.h"\r
+\r
+#include "ConfigModel.h"\r
+#include "DialModelHeartRate.h"\r
+#include "custom_runtime.h"\r
+#include "custom_utils.h"\r
+\r
+#include "heart_blood/health_service/health_service.h"\r
+\r
+#ifdef PPG_HX3695\r
+#include "ppg_service.h"\r
+#endif\r
+\r
+#include "settings/include/SettingModel.h"\r
+#include "uiservice/include/ui_service.h"\r
+#include "wearable_log.h"\r
+#include <algorithm>\r
+\r
+\r
+// #include <bleEvent.h>\r
+\r
+#include <cmsis_os.h>\r
+#include <cmsis_os2.h>\r
+#include <custom_utils.h>\r
+#include <iostream>\r
+#include <memory>\r
+#include <ohos_types.h>\r
+#include <random>\r
+#include <service/graphic_service.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <sys/stat.h>\r
+#include <unistd.h>\r
+\r
+// #include "battery_hal.h"\r
+\r
+#include "languagecode/LanguageInit.h"\r
+#include "ui_service.h"\r
+\r
+#ifdef PPG_HX3695\r
+#include "hx3695.h"\r
+#endif\r
+\r
+\r
+#include <custom_save_runtime.h>\r
 \r
 #ifdef __cplusplus\r
 extern "C" {\r
 #endif\r
 \r
-/* 佩戴检测结果 */\r
+#define MAX_UNWEAR_COUNT 2\r
+#define MAX_VALID_HRS_COUNT 10    //最大有效数\r
+#define MAX_DISVALID_HRS_COUNT 15 //最大无效数\r
+#define MIN_DISPLAY_HEART 50      //最新心率\r
+#define DISPLAY_COUNT 0\r
+#define HEARTTEST 1 //[0 开启测试 1 关闭]\r
+\r
+/*佩戴检测结果*/\r
 enum {\r
-    SENSOR_WEAR_ON = 0,\r
-    SENSOR_WEAR_OFF,\r
-    SENSOR_WEAR_UNKNOW,\r
-    SENSOR_WEAR_MAX\r
+  SENSOR_WEAR_ON = 0,\r
+  SENSOR_WEAR_OFF,\r
+  SENSOR_WEAR_UNKNOW,\r
+  SENSOR_WEAR_MAX\r
 };\r
 \r
 using namespace OHOS;\r
 #define LEN 32\r
 \r
-static void Notify(void *args, const Topic topic, Request* request);\r
+static void Notify(void *args, const Topic topic, Request *request);\r
 \r
 Subscriber heartSubscirber = {\r
     .identity = nullptr,\r
     .args = nullptr,\r
     .Notify = Notify,\r
 };\r
+static void ProcessHeartRateUpdate(Request *request);\r
+static void RefreshHeartData();\r
+void save_heart_maxmin();\r
+void HeartDataSubscribeTopic(Topic topic) {\r
+  BroadcastApi *broadcastApi = nullptr;\r
+  IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME,\r
+                                                     BROADCAST_FEATURE_NAME);\r
+  if (api == nullptr) {\r
+    return;\r
+  }\r
+  int result =\r
+      api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
+  if (result != 0 || broadcastApi == nullptr) {\r
+    return;\r
+  }\r
+  int ret = broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic,\r
+                                         &heartSubscirber);\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartSubscribeTopic ret=%d,topic=%u",\r
+                ret, topic);\r
+  broadcastApi->Release((IUnknown *)broadcastApi);\r
+}\r
 \r
-void HeartDataSubscribeTopic(Topic topic)\r
-{\r
-    BroadcastApi *broadcastApi = nullptr;\r
-    IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME);\r
-    if (api == nullptr) {\r
-        return;\r
-    }\r
-    int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
-    if (result != 0 || broadcastApi == nullptr) {\r
-        return;\r
-    }\r
-    int ret = broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic, &heartSubscirber);\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartSubscribeTopic ret = %d, topic = %u", ret, topic);\r
-    broadcastApi->Release((IUnknown *)broadcastApi);\r
+void HearDatatUnsubscribeTopic(Topic topic) {\r
+  BroadcastApi *broadcastApi = nullptr;\r
+  IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME,\r
+                                                     BROADCAST_FEATURE_NAME);\r
+  if (api == nullptr) {\r
+    return;\r
+  }\r
+  int result =\r
+      api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
+  if (result != 0 || broadcastApi == nullptr) {\r
+    return;\r
+  }\r
+  broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic,\r
+                                 &heartSubscirber);\r
+  broadcastApi->Release((IUnknown *)broadcastApi);\r
 }\r
 \r
-void HearDatatUnsubscribeTopic(Topic topic)\r
-{\r
-    BroadcastApi *broadcastApi = nullptr;\r
-    IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME);\r
-    if (api == nullptr) {\r
-        return;\r
-    }\r
-    int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
-    if (result != 0 || broadcastApi == nullptr) {\r
-        return;\r
-    }\r
-    broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic, &heartSubscirber);\r
-    broadcastApi->Release((IUnknown *)broadcastApi);\r
+static void Notify(void *args, const Topic topic, Request *request) {\r
+  UNUSED(args);\r
+  UNUSED(topic);\r
+\r
+  // 训练过程中不需要判断数据准确性,不需要存储心率数据\r
+  if (uapi_dev_runtime_get_train_status() == 1 ||\r
+      uapi_dev_runtime_get_respiratory_training_status() || request == NULL) {\r
+    return;\r
+  }\r
+  if (request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA) {\r
+    GraphicService::GetInstance()->PostGraphicEvent(std::bind(\r
+        &HeartModel::RefreshHeartRateScreen, HeartModel::GetInstance()));\r
+  }\r
 }\r
 \r
-static void Notify(void *args, const Topic topic, Request* request)\r
-{\r
-    UNUSED(args);\r
-    UNUSED(topic);\r
-    if (request == nullptr) {\r
-        return;\r
-    }\r
-    if (request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA) {\r
-        HeartDatas *heartInfo = (HeartDatas*)malloc(sizeof(HeartDatas));\r
-        if (heartInfo == nullptr) {\r
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Notify] malloc fail");\r
-        }\r
+static void ProcessHeartRateUpdate(Request *request) {\r
+  uint16_t preheart = *reinterpret_cast<uint16_t *>(request->data);\r
+\r
+  // 直接处理心率数据,不进行筛选\r
+  uint16_t index_ = HeartModel::GetInstance()->GetIndex();\r
+  HeartDatas *heartInfo = (HeartDatas *)malloc(sizeof(HeartDatas));\r
+  if (heartInfo == NULL) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[Notify] malloc fail");\r
+    return;\r
+  }\r
+\r
+  heartInfo->index = index_;\r
+  heartInfo->maxX = index_;\r
+  heartInfo->minX = index_;\r
+  heartInfo->perSec = preheart;\r
+  heartInfo->rest = preheart;\r
+  /*最大最小值不为0*/\r
+  heartInfo->maxValue = preheart;\r
+  heartInfo->minValue = preheart;\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "heartRateData=%d%d", heartInfo->index,\r
+                preheart);\r
+  OHOS::HeartModel::GetInstance()->HeartRatePros(heartInfo);\r
+\r
+  free(heartInfo); // 释放内存\r
+  heartInfo = nullptr;\r
+}\r
 \r
-        int rets = memcpy_s(heartInfo, sizeof(HeartDatas), (HeartInfo*)request->data, request->len);\r
-        if (rets != EOK) {\r
-            free(heartInfo);\r
-            heartInfo = nullptr;\r
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "memcpy_s heartRateData fail! ret = %d", rets);\r
-            return;\r
-        }\r
+static void RefreshHeartData() {\r
+  OHOS::HeartModel::GetInstance()->ClearHeartData();\r
+  GraphicService::GetInstance()->PostGraphicEvent(std::bind(\r
+      &OHOS::HeartModel::Heart_Update_View, OHOS::HeartModel::GetInstance()));\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+namespace OHOS {\r
+void HeartModel::ClearHeartData(void) {\r
+  pretime = 0;\r
+  entryTimes = 0;\r
+  aveCount = 0;\r
+  preMaxValue = 0;\r
+  preMaxX = NUM_1;\r
+  preMinValue = HEART_RATE_LIMIT_UPPER;\r
+  preMinX = NUM_1;\r
+  countMax = 0;\r
+  countMin = 0;\r
+  healthDatas.heartRateMax.x = (uint16_t)0XFFFF;\r
+  healthDatas.heartRateMax.y = 0;\r
+  healthDatas.heartRateMin.x = (uint16_t)0XFFFF;\r
+  healthDatas.heartRateMin.y = (uint16_t)0XFFFF;\r
+  for (int i = 0; i < HEART_AVE_NUM; i++) {\r
+    healthDatas.heartRateAvg[i].x = (uint16_t)0XFFFF;\r
+    healthDatas.heartRateAvg[i].y = (uint16_t)0XFFFF;\r
+  }\r
+  if (HeartRateView::GetInstance() != nullptr) {\r
+    HeartRateView::GetInstance()->ClearElectrocardiogram();\r
+  }\r
+  SetAveHeartRateCount(0);\r
+  // GraphicService::GetInstance()->PostGraphicEvent(\r
+  //     std::bind(&HeartModel::RefreshHeartRateScreen,\r
+  //     HeartModel::GetInstance(),\r
+  //               healthDatas.heartRatePerSec,healthDatas.heartRateRest,\r
+  //               healthDatas.heartRateMax.y,healthDatas.heartRateMin.y));\r
+}\r
+\r
+HeartModel::HeartModel() {\r
+  /*初始化读取文件*/\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartModel()");\r
+  /*初始化历史文件*/\r
+  HealthService::GetInstance()->LoadDailyHeartRate();\r
+  /*读取上一次心率数据*/\r
+  HeartRateData data;\r
+  HealthService::GetInstance()->ReadHeartRateData(data);\r
+  currentheart = data.Heart;\r
+  timestamp_ms = data.timestamp;\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "currentheart %d timestamp_ms %d",\r
+                currentheart, timestamp_ms);\r
+  // 更新表盘心率数据\r
+  DialModelHeartRate::GetInstance()->UpdateHeartRate(currentheart);\r
+\r
+  //读取最大最小值\r
+  HealthService::GetInstance()->LoadHeartMaxMin(displayheart_max,\r
+                                                displayheart_min);\r
+  // 配置动态数组\r
+  SetArrayData();\r
+}\r
+\r
+HeartModel::~HeartModel() {\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::~HeartModel()");\r
+  HearDatatUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);\r
+  HearDatatUnsubscribeTopic(TOPIC_EVENT_NEXTDAY_UPDATE);\r
+  HearDatatUnsubscribeTopic(TOPIC_EVENT_UTCTIME_UPDATE);\r
+  HearDatatUnsubscribeTopic(TOPIC_EVENT_WEARSTATE_UPDATE);\r
+}\r
 \r
-        OHOS::HeartModel::GetInstance()->HeartRatePros(heartInfo);\r
+HeartModel *HeartModel::GetInstance(void) {\r
+  static HeartModel heartModel;\r
+  return &heartModel;\r
+}\r
+uint16_t HeartModel::GetIndex() { return index_; }\r
+void HeartModel::SetIndex(uint16_t index) { index_ = index; }\r
+\r
+void HeartModel::Init(void) {\r
+  HeartDataSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);\r
+  HeartDataSubscribeTopic(TOPIC_EVENT_NEXTDAY_UPDATE);\r
+  HeartDataSubscribeTopic(TOPIC_EVENT_UTCTIME_UPDATE);\r
+  HeartDataSubscribeTopic(TOPIC_EVENT_WEARSTATE_UPDATE);\r
+}\r
 \r
-        free(heartInfo);\r
-        heartInfo = nullptr;\r
+Point *HeartModel::GetAveHeartRate(void) { return healthDatas.heartRateAvg; }\r
+\r
+void HeartModel::HandleMaxHeart(uint16 coord, uint16 value) {\r
+  healthDatas.heartRateMax.x = coord;\r
+  healthDatas.heartRateMax.y = value;\r
+  // 插入最大心率 countMax 数据个数\r
+  if (preMaxValue != healthDatas.heartRateMax.y && aveCount < HEART_AVE_NUM) {\r
+    if (preMaxX == healthDatas.heartRateMax.x && countMax < HEART_AVE_NUM) {\r
+      healthDatas.heartRateAvg[countMax].y = healthDatas.heartRateMax.y;\r
+    } else if (aveCount > NUM_2 && (healthDatas.heartRateMax.x ==\r
+                                    healthDatas.heartRateAvg[aveCount - 1].x)) {\r
+      healthDatas.heartRateAvg[aveCount - 1].y = healthDatas.heartRateMax.y;\r
+    } else {\r
+      healthDatas.heartRateAvg[aveCount] = healthDatas.heartRateMax;\r
+      countMax = aveCount;\r
+      aveCount++;\r
     }\r
-    if (request->msgId == TOPIC_EVENT_NEXTDAY_UPDATE) {\r
-        OHOS::HeartModel::GetInstance()->ClearHeartData();\r
+    if (healthDatas.heartRateMax.x != 0) {\r
+      if (healthDatas.heartRateAvg[0].x == 0 &&\r
+          healthDatas.heartRateAvg[1].x == 0) {\r
+        for (int i = 1; i < (aveCount - 1); i++) {\r
+          healthDatas.heartRateAvg[i] = healthDatas.heartRateAvg[i + 1];\r
+        }\r
+        aveCount--;\r
+        countMax--;\r
+      }\r
     }\r
-    if (request->msgId == TOPIC_EVENT_UTCTIME_UPDATE) {\r
-        OHOS::HeartModel::GetInstance()->ClearHeartData();\r
+  }\r
+  preMaxValue = healthDatas.heartRateMax.y;\r
+  preMaxX = healthDatas.heartRateMax.x;\r
+}\r
+\r
+void HeartModel::HandleMinHeart(uint16 coord, uint16 value) {\r
+  // 最小心率\r
+  healthDatas.heartRateMin.x = coord;\r
+  healthDatas.heartRateMin.y = value;\r
+  // 插入最小心率\r
+  // avecount 当下有效数据个数,在MaxHeart中也用到,看起来似乎有问题???\r
+  // preMinValue 上一个心率最小值\r
+  // preMinX 上一个最小值对应的坐标\r
+  // 当上一个值与当前值不等,且没有超过总数限制,则进行数据处理\r
+  if (preMinValue != healthDatas.heartRateMin.y && aveCount < HEART_AVE_NUM) {\r
+\r
+    if (preMinX == healthDatas.heartRateMin.x && countMin < HEART_AVE_NUM) {\r
+      // 上一个最小坐标和当前值一致,且数据没超过限制,则直接赋值给有效数据\r
+      // countMin 即可\r
+      healthDatas.heartRateAvg[countMin].y = healthDatas.heartRateMin.y;\r
+    } else if (aveCount > NUM_2 && (healthDatas.heartRateMin.x ==\r
+                                    healthDatas.heartRateAvg[aveCount - 1].x)) {\r
+      // 有效数据大于2,且当前x值与原始数据最后一个x一致,最后一个数据赋值\r
+      healthDatas.heartRateAvg[aveCount - 1].y = healthDatas.heartRateMin.y;\r
+    } else {\r
+      healthDatas.heartRateAvg[aveCount] = healthDatas.heartRateMin;\r
+      countMin = aveCount;\r
+      aveCount++;\r
     }\r
-    if (request->msgId == TOPIC_EVENT_WEARSTATE_UPDATE) {\r
-        uint32 wearStatus = *((uint32*)request->data);\r
-        if (wearStatus == SENSOR_WEAR_OFF) {\r
-            OHOS::HeartModel::GetInstance()->SetWearStatus(false);\r
-            OHOS::HeartModel::GetInstance()->SetHeartRatePerSec(0);\r
-            if (OHOS::MainClockView::GetInstance() != nullptr) {\r
-                OHOS::MainClockView::GetInstance()->RefreshHeartRate(0);\r
-            }\r
-        } else {\r
-            OHOS::HeartModel::GetInstance()->SetWearStatus(true);\r
+\r
+    // 最初的值一直是0 ,则只显示1个 ,不会在后面增加数据。\r
+    if (healthDatas.heartRateMin.x != 0) {\r
+      if (healthDatas.heartRateAvg[0].x == 0 &&\r
+          healthDatas.heartRateAvg[1].x == 0) {\r
+        for (int i = 0; i < (aveCount - 1); i++) {\r
+          healthDatas.heartRateAvg[i] = healthDatas.heartRateAvg[i + 1];\r
         }\r
+        aveCount--;\r
+        countMin--;\r
+      }\r
     }\r
+  }\r
+  preMinValue = healthDatas.heartRateMin.y;\r
+  preMinX = healthDatas.heartRateMin.x;\r
 }\r
 \r
-#ifdef __cplusplus\r
+void HeartModel::HeartRatePros(HeartDatas *heartInfo) {\r
+  uint16_t perSecHeartRate = 0;\r
+  uint16_t restHeartRate = 0;\r
+\r
+  // 每秒心率\r
+  perSecHeartRate = heartInfo->perSec;\r
+  if (perSecHeartRate >= HEART_RATE_LIMIT_LOWER &&\r
+      perSecHeartRate <= HEART_RATE_LIMIT_UPPER) {\r
+    healthDatas.heartRatePerSec = perSecHeartRate;\r
+  }\r
+\r
+  // GraphicService::GetInstance()->PostGraphicEvent(\r
+  //     std::bind(&HeartModel::RefreshHeartRateScreen,\r
+  //     HeartModel::GetInstance(),\r
+  //               healthDatas.heartRatePerSec,healthDatas.heartRateRest,\r
+  //               healthDatas.heartRateMax.y,healthDatas.heartRateMin.y));\r
 }\r
-#endif\r
 \r
-namespace OHOS {\r
-void HeartModel::ClearHeartData(void)\r
-{\r
-    pretime = 0;\r
-    entryTimes = 0;\r
-    aveCount = 0;\r
-    preMaxValue = 0;\r
-    preMaxX = NUM_1;\r
-    preMinValue = HEART_RATE_LIMIT_UPPER;\r
-    preMinX = NUM_1;\r
-    countMax = 0;\r
-    countMin = 0;\r
-    healthDatas.heartRateMax.x = (uint16_t)0XFFFF;\r
-    healthDatas.heartRateMax.y = 0;\r
-    healthDatas.heartRateMin.x = (uint16_t)0XFFFF;\r
-    healthDatas.heartRateMin.y = (uint16_t)0XFFFF;\r
-    for (int i = 0; i < HEART_AVE_NUM; i++) {\r
-        healthDatas.heartRateAvg[i].x = (uint16_t)0XFFFF;\r
-        healthDatas.heartRateAvg[i].y = (uint16_t)0XFFFF;\r
-    }\r
-    if (HeartRateView::GetInstance() != nullptr) {\r
-        HeartRateView::GetInstance()->ClearElectrocardiogram();\r
+uint16_t HeartModel::GetAveHeartRateCount(void) { return aveCount; }\r
+\r
+uint16_t HeartModel::GetHeartRateMax(void) {\r
+  return healthDatas.heartRateMax.y;\r
+}\r
+\r
+uint16_t HeartModel::GetHeartRateMin(void) {\r
+  return healthDatas.heartRateMin.y;\r
+}\r
+\r
+void HeartModel::SetHeartRatePerSec(uint32 sec) {\r
+  healthDatas.heartRatePerSec = sec;\r
+  if (HeartRateView::GetInstance() == nullptr) {\r
+    return;\r
+  }\r
+  HeartRateView::GetInstance()->RefreshHeartRatePerSec(\r
+      healthDatas.heartRatePerSec);\r
+}\r
+\r
+void HeartModel::SetAveHeartRateCount(uint16_t value) { aveCount = value; }\r
+\r
+void HeartModel::RefreshHeartRateScreen() {\r
+  if (MainViewSample::GetInstance() != nullptr &&\r
+      HeartChartView::GetInstance() != nullptr) {\r
+    if (MainViewSample::GetInstance()->GetHorCurrentCard() == HEART_RATE) {\r
+      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                    "HeartChartView::GetInstance() start");\r
+      HeartChartView::GetInstance()->UpdateShowHeart();\r
+      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                    "HeartChartView::GetInstance() end");\r
     }\r
-    SetAveHeartRateCount(0);\r
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(&HeartModel::RefreshHeartRateScreen, HeartModel::GetInstance(),\r
-        healthDatas.heartRatePerSec, healthDatas.heartRateRest, healthDatas.heartRateMax.y, healthDatas.heartRateMin.y));\r
-}\r
-\r
-HeartModel::HeartModel()\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartModel()");\r
-}\r
-\r
-HeartModel::~HeartModel()\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::~HeartModel()");\r
-    HearDatatUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);\r
-    HearDatatUnsubscribeTopic(TOPIC_EVENT_NEXTDAY_UPDATE);\r
-    HearDatatUnsubscribeTopic(TOPIC_EVENT_UTCTIME_UPDATE);\r
-    HearDatatUnsubscribeTopic(TOPIC_EVENT_WEARSTATE_UPDATE);\r
-}\r
-\r
-HeartModel *HeartModel::GetInstance(void)\r
-{\r
-    static HeartModel heartModel;\r
-    return &heartModel;\r
-}\r
-\r
-void HeartModel::Init(void)\r
-{\r
-    HeartDataSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);\r
-    HeartDataSubscribeTopic(TOPIC_EVENT_NEXTDAY_UPDATE);\r
-    HeartDataSubscribeTopic(TOPIC_EVENT_UTCTIME_UPDATE);\r
-    HeartDataSubscribeTopic(TOPIC_EVENT_WEARSTATE_UPDATE);\r
-}\r
-\r
-Point* HeartModel::GetAveHeartRate(void)\r
-{\r
-    return healthDatas.heartRateAvg;\r
-}\r
-\r
-void HeartModel::HandleMaxHeart(uint16 coord, uint16 value)\r
-{\r
-    healthDatas.heartRateMax.x = coord;\r
-    healthDatas.heartRateMax.y = value;\r
-    // 插入最大心率\r
-    if (preMaxValue != healthDatas.heartRateMax.y && aveCount < HEART_AVE_NUM) {\r
-        if (preMaxX == healthDatas.heartRateMax.x && countMax < HEART_AVE_NUM) {\r
-            healthDatas.heartRateAvg[countMax].y = healthDatas.heartRateMax.y;\r
-        } else if (aveCount > NUM_2 && (healthDatas.heartRateMax.x == healthDatas.heartRateAvg[aveCount - 1].x)) {\r
-            healthDatas.heartRateAvg[aveCount - 1].y = healthDatas.heartRateMax.y;\r
-        } else {\r
-            healthDatas.heartRateAvg[aveCount] = healthDatas.heartRateMax;\r
-            countMax = aveCount;\r
-            aveCount++;\r
-        }\r
-        if (healthDatas.heartRateMax.x != 0) {\r
-            if (healthDatas.heartRateAvg[0].x == 0 && healthDatas.heartRateAvg[1].x == 0) {\r
-                for (int i = 1; i < (aveCount - 1); i++) {\r
-                    healthDatas.heartRateAvg[i] = healthDatas.heartRateAvg[i + 1];\r
-                }\r
-                aveCount--;\r
-                countMax--;\r
-            }\r
-        }\r
+  }\r
+}\r
+/*----------------------------------状态检测\r
+ *----------------------------------*/\r
+\r
+// 重新初始化\r
+void HeartModel::ClearDisplayData() {\r
+  /*显示的心率数据清空*/\r
+  // currentheart = 0;\r
+  // timestamp_ms = 0;\r
+  displayheart = 0;\r
+  displayheart_max = 0; // 显示最大心率\r
+  displayheart_min = 0; // 显示最小心率\r
+}\r
+// 获取心率数据\r
+uint16_t HeartModel::GetHeartdata() { return currentheart; }\r
+\r
+uint16_t HeartModel::GetShowHeartdata() { return displayheart; }\r
+uint16_t HeartModel::GetShowMaxHeartdata() { return displayheart_max; }\r
+uint16_t HeartModel::GetShowMinHeartdata() { return displayheart_min; }\r
+uint32_t HeartModel::GetCheckTime() { return timestamp_ms; }\r
+\r
+void HeartModel::SetCheckTime(uint32_t time) { timestamp_ms = time; }\r
+void HeartModel::SetResult(HeartResult result) { heartresult_ = result; }\r
+HeartResult HeartModel::GetResult() { return heartresult_; }\r
+// 控制心率检测\r
+void HeartModel::Heart_Control(HeartState state, HeartCheck check) {\r
+  #ifdef PPG_HX3695\r
+  //优先级低不对高优先级处理\r
+  if (check < checkstate) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                  "Higher execution instruction exists");\r
+    return;\r
+  }\r
+\r
+  //被动\r
+  if (check == HeartCheck::PASSIVITY) {\r
+    uapi_dev_runtime_set_hrs_passivity(1);\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                  "uapi_dev_runtime_set_hrs_passivity(1)");\r
+  } else {\r
+    uapi_dev_runtime_set_hrs_passivity(0);\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                  "uapi_dev_runtime_set_hrs_passivity(0)");\r
+  }\r
+\r
+  if (state == HeartState::End && heartstate == true) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartState End");\r
+    //状态数全部清空\r
+    valid_counter_ = 0;\r
+    disvalid_counter_ = 0;\r
+    unwear_counter_ = 0;\r
+    display_counter_ = 0;\r
+    displayheart = 0;\r
+    uint8_t md = PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST;\r
+    errcode_t ret = send_ppg_cmd_msg(md);\r
+    if(ret != ERRCODE_SUCC)\r
+    {\r
+        send_ppg_cmd_msg(md);\r
     }\r
-    preMaxValue = healthDatas.heartRateMax.y;\r
-    preMaxX = healthDatas.heartRateMax.x;\r
-}\r
-\r
-void HeartModel::HandleMinHeart(uint16 coord, uint16 value)\r
-{\r
-    // 最小心率\r
-    healthDatas.heartRateMin.x = coord;\r
-    healthDatas.heartRateMin.y = value;\r
-    // 插入最小心率\r
-    if (preMinValue != healthDatas.heartRateMin.y && aveCount < HEART_AVE_NUM) {\r
-        if (preMinX == healthDatas.heartRateMin.x && countMin < HEART_AVE_NUM) {\r
-            healthDatas.heartRateAvg[countMin].y = healthDatas.heartRateMin.y;\r
-        } else if (aveCount > NUM_2 && (healthDatas.heartRateMin.x == healthDatas.heartRateAvg[aveCount - 1].x)) {\r
-            healthDatas.heartRateAvg[aveCount - 1].y = healthDatas.heartRateMin.y;\r
-        } else {\r
-            healthDatas.heartRateAvg[aveCount] = healthDatas.heartRateMin;\r
-            countMin = aveCount;\r
-            aveCount++;\r
-        }\r
-        if (healthDatas.heartRateMin.x != 0) {\r
-            if (healthDatas.heartRateAvg[0].x == 0 && healthDatas.heartRateAvg[1].x == 0) {\r
-                for (int i = 0; i < (aveCount - 1); i++) {\r
-                    healthDatas.heartRateAvg[i] = healthDatas.heartRateAvg[i + 1];\r
-                }\r
-                aveCount--;\r
-                countMin--;\r
-            }\r
-        }\r
+    heartstate = false;\r
+    if (checkstate == HeartCheck::CARDCHECK) {\r
+      //重置传感器状态\r
+      sensorstate = false;\r
+      uapi_dev_runtime_set_heartrate_detect_status(0);\r
     }\r
-    preMinValue = healthDatas.heartRateMin.y;\r
-    preMinX = healthDatas.heartRateMin.x;\r
-}\r
 \r
-void  HeartModel::HeartRatePros(HeartDatas *heartInfo)\r
-{\r
-    uint16_t perSecHeartRate = 0;\r
-    uint16_t restHeartRate = 0;\r
+    //记录日志\r
+    if (checkstate == HeartCheck::PASSIVITY) {\r
+      uapi_save_runtime_log(RUNTIME_LOG_OXYGEN_PASSIVE_MEASURE_END);\r
+    } else {\r
+      uapi_save_runtime_log(RUNTIME_LOG_HEART_MEASURE_END);\r
+    }\r
 \r
-    // 每秒心率\r
-    perSecHeartRate = heartInfo->perSec;\r
-    if (perSecHeartRate > HEART_RATE_LIMIT_LOWER && perSecHeartRate <= HEART_RATE_LIMIT_UPPER) {\r
-        healthDatas.heartRatePerSec = perSecHeartRate;\r
+    // 复原检测状态\r
+    checkstate = HeartCheck::RESTSTSTE;\r
+  } else if (state == HeartState::Start && heartstate == false) {\r
+    /*充电状态下不进行检测*/\r
+    bool isCharging = get_charge_stat(); // 获取充电状态\r
+    if (isCharging) {\r
+      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "充电不能检测");\r
+      return;\r
+    }\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartState Start");\r
+    uint8_t md = PPG_SERVICE_CMD_TYPE_DO_PPG_TEST;\r
+    send_ppg_cmd_msg(md);\r
+    heartstate = true;\r
+    checkstate = check;\r
+\r
+    //记录日志\r
+    if (checkstate == HeartCheck::PASSIVITY) {\r
+      uapi_save_runtime_log(RUNTIME_LOG_HEART_PASSIVE_MEASURE);\r
+    } else {\r
+      uapi_save_runtime_log(RUNTIME_LOG_HEART_MEASURE);\r
+    }\r
+  }\r
+  #endif\r
+}\r
+// 开始检测\r
+void HeartModel::Heart_Start(HeartCheck check) {\r
+  if (!sensorstate) {\r
+    displayheart = 0;\r
+    SetResult(HeartResult::NOT_TESTED); // 重置检测\r
+    Heart_Control(HeartState::Start, check);\r
+    // ScreenTurnOn(60 * 1000); // 亮屏操作 600000ms 60秒关闭\r
+    sensorstate = true;\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "开始心率检测");\r
+    // 设置runtime\r
+    if (uapi_dev_runtime_get_heartrate_detect_status() == 0) {\r
+      uapi_dev_runtime_set_heartrate_detect_status(1);\r
+      ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);\r
+      // 主动检测的亮屏60s\r
+      heart_start_screen60s_timer();\r
     }\r
+  }\r
+}\r
 \r
-    // 静息心率\r
-    restHeartRate = heartInfo->rest;\r
-    if (restHeartRate > HEART_RATE_LIMIT_LOWER && restHeartRate <= HEART_RATE_LIMIT_UPPER) {\r
-        healthDatas.heartRateRest = restHeartRate;\r
+// 结束检测\r
+void HeartModel::Heart_Stop() {\r
+  valid_counter_ = 0;\r
+  disvalid_counter_ = 0;\r
+  unwear_counter_ = 0;\r
+  // display_counter_ = 0; 取消再次检测的--操作\r
+  // displayheart = 0;\r
+\r
+  // ScreenTurnOff(); //恢复正常亮屏\r
+\r
+  /*主界面卡片检测 或者 被动检测*/\r
+  if (checkstate == HeartCheck::PASSIVITY) {\r
+    if (heartresult_ == HeartResult::SUCCESS) {\r
+      Heart_Save();\r
+      /*更新曲线*/\r
+      GraphicService::GetInstance()->PostGraphicEvent(\r
+          std::bind(&HeartModel::Heart_Update_View, HeartModel::GetInstance()));\r
     }\r
-    HandleMinHeart(heartInfo->minX, heartInfo->minValue);\r
-    HandleMaxHeart(heartInfo->maxX, heartInfo->maxValue);\r
-    // 平均心率\r
-    uint16_t count = aveCount + heartInfo->index;\r
-    if (aveCount < HEART_AVE_NUM) {\r
-        for (int i = aveCount; i < count; i++) {\r
-            if (healthDatas.heartRateMin.x != heartInfo->value[i - aveCount].x && healthDatas.heartRateMax.x != heartInfo->value[i - aveCount].x) {\r
-                healthDatas.heartRateAvg[aveCount].x = heartInfo->value[i - aveCount].x;\r
-                healthDatas.heartRateAvg[aveCount].y = heartInfo->value[i - aveCount].y;\r
-                aveCount++;\r
-            }\r
-        }\r
+    /*关闭被动检测*/\r
+    Heart_Control(HeartState::End, HeartCheck::PASSIVITY);\r
+    return;\r
+  }\r
+  //呼吸训练模式下不进行息屏与保存\r
+  if (sensorstate && uapi_dev_runtime_get_respiratory_training_status() != 1) {\r
+    // 恢复正常亮屏\r
+    HeartModel::GetInstance()->heart_stop_screen60s_timer();\r
+    // 取消常亮屏\r
+    ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);\r
+    //设置runtime\r
+\r
+    Heart_Result(); // 处理结果\r
+\r
+    //为了防止主界面卡片一直重复开传感器\r
+    if (checkstate != HeartCheck::CARDCHECK) {\r
+      //重置传感器状态\r
+      sensorstate = false;\r
+      uapi_dev_runtime_set_heartrate_detect_status(0);\r
     }\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "本次心率检测结束");\r
+  }\r
+}\r
+// 保存检测数据\r
+void HeartModel::Heart_Save() {\r
+\r
+  uint32_t timestamp = HeartResultPresenter::GetInstance()->GetCurrentTime();\r
+  SetCheckTime(timestamp);\r
+\r
+  HealthService::GetInstance()->send_heart_save();\r
+\r
+  // 更新最大和最小心率\r
+  displayheart_max =\r
+      (displayheart_max < currentheart ? currentheart : displayheart_max);\r
+\r
+  // 确保最小心率的第一次赋值大于50\r
+  if (displayheart_min == 0 && currentheart > MIN_DISPLAY_HEART) {\r
+    displayheart_min = currentheart; // 初始化最小心率\r
+  } else {\r
+    displayheart_min =\r
+        (displayheart_min > currentheart && currentheart > MIN_DISPLAY_HEART)\r
+            ? currentheart\r
+            : displayheart_min;\r
+  }\r
+\r
+  // 将更新曲线写到这里提前更新\r
+  HealthService::GetInstance()->UpdateHourlyHeartRate(timestamp_ms,\r
+                                                      currentheart);\r
+  // WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "保存的心率数据:%d%ld",\r
+  // currentheart,data.timestamp);\r
+}\r
 \r
-    for (int i = 0; i < aveCount - 1; i++) {\r
-        if (healthDatas.heartRateAvg[i].x == healthDatas.heartRateAvg[i + 1].x) {\r
-            if (healthDatas.heartRateAvg[i].y != healthDatas.heartRateMin.y && healthDatas.heartRateAvg[i].y != healthDatas.heartRateMax.y) {\r
-                for (int j = i; j < aveCount - 1; j++) {\r
-                    healthDatas.heartRateAvg[j] = healthDatas.heartRateAvg[j + 1];\r
-                }\r
-                aveCount--;\r
-            } else if (healthDatas.heartRateAvg[i + 1].y != healthDatas.heartRateMin.y && healthDatas.heartRateAvg[i + 1].y != healthDatas.heartRateMax.y) {\r
-                for (int j = i + 1; j < aveCount - 1; j++) {\r
-                    healthDatas.heartRateAvg[j] = healthDatas.heartRateAvg[j + 1];\r
-                }\r
-                aveCount--;\r
-            }\r
+void HeartModel::Heart_Result() {\r
+\r
+  if (heartresult_ == HeartResult::SUCCESS) {\r
+    // 获取心率提醒状态和阈值\r
+    heartRemindState = ConfigModel::GetInstance()->get_configData_int(\r
+        ConfigModel::CONFIGMODEL_ITEM_HEARTRATE_REMIND);\r
+    thresholdValue = ConfigModel::GetInstance()->get_configData_int(\r
+        ConfigModel::CONFIGMODEL_ITEM_HEARTRATE_THRESHOLD_VALUE);\r
+\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "心率提醒状态:%d,阈值:%d,當前值:%d",\r
+                  heartRemindState, thresholdValue, currentheart);\r
+\r
+    if (heartRemindState) {\r
+      // 获取当前心率状态\r
+      thresholdState = ConfigModel::GetInstance()->get_configData_int(\r
+          ConfigModel::CONFIGMODEL_ITEM_HEARTRATE_MAX_MIN);\r
+\r
+      if (currentheart != 0) {\r
+        if (thresholdState == 0 && currentheart < thresholdValue) {\r
+          // 当前心率低于阈值\r
+          heartresult_ = HeartResult::LOW_RESULT;\r
+          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                        "检测结果:低结果情况,currentheart=%d,ThresholdValue=%d",\r
+                        currentheart, thresholdValue);\r
+        } else if (thresholdState == 1 && currentheart > thresholdValue) {\r
+          // 当前心率高于阈值\r
+          heartresult_ = HeartResult::HIGH_RESULT;\r
+          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                        "检测结果:高结果情况,currentheart=%d,ThresholdValue=%d",\r
+                        currentheart, thresholdValue);\r
         }\r
+      }\r
     }\r
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(&HeartModel::RefreshHeartRateScreen, HeartModel::GetInstance(),\r
-        healthDatas.heartRatePerSec, healthDatas.heartRateRest, healthDatas.heartRateMax.y, healthDatas.heartRateMin.y));\r
+  }\r
+  // 根据结果进行处理\r
+  handleHeartResult();\r
 }\r
-\r
-uint16_t HeartModel::GetAveHeartRateCount(void)\r
-{\r
-    return aveCount;\r
+// 处理检测结果\r
+void HeartModel::handleHeartResult() {\r
+  switch (heartresult_) {\r
+  case HeartResult::SUCCESS:\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果:成功");\r
+    Heart_Save();\r
+    // 更新曲线\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "准备更新UI");\r
+    GraphicService::GetInstance()->PostGraphicEvent(\r
+        std::bind(&HeartModel::Heart_Update_View, HeartModel::GetInstance()));\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "更新UI完成");\r
+    break;\r
+\r
+  case HeartResult::NOT_WORN:\r
+  case HeartResult::TIMEOUT:\r
+  case HeartResult::INVALID_DATA:\r
+    logAndChangeSlice(heartresult_);\r
+    break;\r
+\r
+  case HeartResult::LOW_RESULT:\r
+    Heart_Save();\r
+    handleLowHeartRate();\r
+    break;\r
+\r
+  case HeartResult::HIGH_RESULT:\r
+    Heart_Save();\r
+    handleHighHeartRate();\r
+    break;\r
+\r
+  default:\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果:未知状态");\r
+    break;\r
+  }\r
 }\r
-\r
-uint16_t HeartModel::GetHeartRateMax(void)\r
-{\r
-    return healthDatas.heartRateMax.y;\r
+//进行日志打印与界面切换\r
+void HeartModel::logAndChangeSlice(HeartResult result) {\r
+  const char *resultMsg =\r
+      (result == HeartResult::NOT_WORN)\r
+          ? "未佩戴状态"\r
+          : (result == HeartResult::TIMEOUT) ? "超时" : "无效数据";\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果:%s情况", resultMsg);\r
+  uapi_set_screen_on_api(); // 亮屏\r
+  //需要先判断界面 心率卡片界面\r
+  if (MainViewSample::GetInstance()) {\r
+    if (MainViewSample::GetInstance()->GetHorCurrentCard() == HEART_RATE)\r
+      NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_ABNORMAL);\r
+  } else\r
+    NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_ABNORMAL);\r
 }\r
-\r
-uint16_t HeartModel::GetHeartRateMin(void)\r
-{\r
-    return healthDatas.heartRateMin.y;\r
+// 处理低心率情况\r
+void HeartModel::handleLowHeartRate() {\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果:低结果情况");\r
+  HealthState lowHealthState = {HEART_CHECK, LOW, thresholdValue};\r
+  HealthService::GetInstance()->SetHealthCurrent(lowHealthState);\r
+  uapi_set_screen_on_api(); // 亮屏\r
+  if (MainViewSample::GetInstance()) {\r
+    if (MainViewSample::GetInstance()->GetHorCurrentCard() == HEART_RATE)\r
+      NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_INVALID);\r
+  } else\r
+    NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_INVALID);\r
 }\r
-\r
-void HeartModel::SetHeartRatePerSec(uint32 sec)\r
-{\r
-    healthDatas.heartRatePerSec = sec;\r
-    if (HeartRateView::GetInstance() == nullptr) {\r
-        return;\r
+// 处理高心率情况\r
+void HeartModel::handleHighHeartRate() {\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "检测结果:高结果情况");\r
+  HealthState highHealthState = {HEART_CHECK, HIGH, thresholdValue};\r
+  HealthService::GetInstance()->SetHealthCurrent(highHealthState);\r
+  uapi_set_screen_on_api(); // 亮屏\r
+  if (MainViewSample::GetInstance()) {\r
+    if (MainViewSample::GetInstance()->GetHorCurrentCard() == HEART_RATE)\r
+      NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_INVALID);\r
+  } else\r
+    NativeAbility::GetInstance().ChangeSlice(VIEW_CHECK_INVALID);\r
+}\r
+// 设置佩戴状态\r
+void HeartModel::SetWearStatus() {\r
+\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "佩戴状态 %d %d",\r
+                uapi_dev_runtime_get_heartrate_detect_status(),\r
+                unwear_counter_);\r
+\r
+  // 如果处于训练模式,提前返回\r
+  if (uapi_dev_runtime_get_train_status() == 1 ||\r
+      // uapi_dev_runtime_get_heartrate_detect_status() == 0 ||\r
+      uapi_dev_runtime_get_respiratory_training_status())\r
+    return;\r
+\r
+  unwear_counter_++;\r
+  uapi_save_runtime_log(RUNTIME_LOG_HEART_NOT_WEAR);\r
+\r
+  // 设置佩戴状态\r
+  if (checkstate == HeartCheck::CARDCHECK) {\r
+    if (unwear_counter_ > MAX_UNWEAR_COUNT) {\r
+      if (MainViewSample::GetInstance()) {\r
+        //只有在心率卡片界面才触发\r
+        if (MainViewSample::GetInstance()->GetHorCurrentCard() == HEART_RATE) {\r
+          SetResult(HeartResult::NOT_WORN);\r
+          uapi_save_runtime_log(RUNTIME_LOG_HEART_ERROR_NOT_WEAR);\r
+          Heart_Stop();\r
+        }\r
+      }\r
     }\r
-    HeartRateView::GetInstance()->RefreshHeartRatePerSec(healthDatas.heartRatePerSec);\r
+  } else {\r
+    SetResult(HeartResult::NOT_WORN);\r
+    uapi_save_runtime_log(RUNTIME_LOG_HEART_ERROR_NOT_WEAR);\r
+    Heart_Stop();\r
+  }\r
 }\r
 \r
-void HeartModel::SetAveHeartRateCount(uint16_t value)\r
-{\r
-    aveCount = value;\r
+void HeartModel::UpHeartdata(uint16_t heart) {\r
+  // 如果处于训练模式,提前返回\r
+  if (uapi_dev_runtime_get_train_status() == 1)\r
+    return;\r
+\r
+  int max_valid_count = 0;\r
+\r
+  // if (heart != 0) {\r
+  //   if (display_counter_ >= DISPLAY_COUNT) {\r
+  //     displayheart = heart;\r
+  //   } else {\r
+  //     displayheart = 0;\r
+  //   }\r
+  //   display_counter_++;\r
+  // } else {\r
+  //   displayheart = 0;\r
+  // }\r
+\r
+  displayheart = heart;\r
+\r
+  // 更新心率和计数器\r
+  if (displayheart != 0) {\r
+    currentheart = displayheart; // 更新当前心率\r
+    valid_counter_++;            // 增加有效计数器\r
+    disvalid_counter_ = 0;       // 清空无效计数器\r
+    uapi_save_runtime_log(RUNTIME_LOG_HEART_VALID_VALUE);\r
+  } else {\r
+    disvalid_counter_++; // 增加无效计数器\r
+    valid_counter_ = 0;  // 清零有效计数器\r
+    uapi_save_runtime_log(RUNTIME_LOG_HEART_INVALID_VALUE);\r
+  }\r
+\r
+  // 检查无效计数器是否达标\r
+  if (uapi_dev_runtime_get_sleep_monitoring_status()) //睡眠监测模式下,增加未佩戴个数最大值,避免误判\r
+    max_valid_count = MAX_DISVALID_HRS_COUNT * 2;\r
+  else\r
+    max_valid_count = MAX_DISVALID_HRS_COUNT;\r
+\r
+  if (disvalid_counter_ >= max_valid_count) {\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                  "检测结果:无效数达标 disvalid_counter:%d", disvalid_counter_);\r
+    SetResult(HeartResult::INVALID_DATA); // 标记为无效数据\r
+    uapi_save_runtime_log(RUNTIME_LOG_HEAR_ERROR_INVALID_VALUE);\r
+    Heart_Stop();\r
+    return;\r
+  }\r
+\r
+  // 检查有效计数器是否达标\r
+  if (valid_counter_ >= MAX_VALID_HRS_COUNT) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                  "检测结果:成功 valid_counter:%d currentheart:%d",\r
+                  valid_counter_, currentheart);\r
+    uapi_save_runtime_log(RUNTIME_LOG_HEAR_SUCCESS);\r
+    SetResult(HeartResult::SUCCESS); // 标记为成功检测\r
+    Heart_Stop();\r
+    return;\r
+  }\r
+\r
+  // 刷新心率显示\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                "[heart data update displayheart%d displayheart_max%d "\r
+                "displayheart_min%d]",\r
+                displayheart, displayheart_max, displayheart_min);\r
+\r
+  // GraphicService::GetInstance()->PostGraphicEvent(\r
+  //     std::bind(&HeartModel::RefreshHeartRateScreen,\r
+  //     HeartModel::GetInstance(),\r
+  //               displayheart));\r
 }\r
 \r
-void HeartModel::SetWearStatus(bool status)\r
-{\r
-    wearStatus = status;\r
+void HeartModel::Heart_Update_View(void) {\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "更新心率界面");\r
+  int hour = HealthService::GetInstance()->GetCurrentHour();\r
+  if (HeartRateView::GetInstance() != nullptr) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "更新主界面卡片");\r
+    HeartRateView::GetInstance()->Update_data_Chart(hour);\r
+  }\r
+  if (HeartChartView::GetInstance() != nullptr) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "更新测量心率卡片");\r
+    HeartChartView::GetInstance()->Update_data_Chart(hour);\r
+  }\r
 }\r
 \r
-bool HeartModel::GetWearStatus(void)\r
-{\r
-    return wearStatus;\r
+void HeartModel::CleanAllData(void) {\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Nextday!");\r
+  if (MainViewSample::GetInstance() != nullptr &&\r
+      HeartRateView::GetInstance() != nullptr) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "更新主界面心率卡片");\r
+    HeartRateView::GetInstance()->CleanAllDataView();\r
+  }\r
+  if (HeartChartView::GetInstance() != nullptr) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "更新测量心率卡片");\r
+    HeartChartView::GetInstance()->CleanAllDataView();\r
+  }\r
 }\r
 \r
-void HeartModel::RefreshHeartRateScreen(uint16_t perSec, uint16_t rest, uint16_t maxRate, uint16_t minRate)\r
-{\r
-    UNUSED(rest);\r
-    Point *rateData;\r
-    int len = GetAveHeartRateCount();\r
-    rateData = GetAveHeartRate();\r
-\r
-    uint16_t currentViewId = NativeAbility::GetInstance().GetCurSliceId();\r
-    if (currentViewId == VIEW_MAIN && MainClockView::GetInstance() != nullptr) {\r
-        MainClockView::GetInstance()->RefreshHeartRate(perSec);\r
+// 配置5个动态心率数据\r
+// 最大 最小\r
+void HeartModel::SetArrayData() {\r
+  // 如果没有进行心率检测,则默认为0-220\r
+  if (displayheart_max == 0 || displayheart_min == 0) {\r
+    dynamic_heartrate[0] = 0;\r
+    dynamic_heartrate[1] = 40;\r
+    dynamic_heartrate[2] = 100;\r
+    dynamic_heartrate[3] = 160;\r
+    dynamic_heartrate[4] = 220;\r
+    return; // 直接返回\r
+  }\r
+\r
+  // 计算心率范围并添加缓冲\r
+  uint16_t adjusted_min =\r
+      (displayheart_min > 10) ? (displayheart_min / 2) : displayheart_min;\r
+  uint16_t adjusted_max =\r
+      (displayheart_max < 210) ? (displayheart_max + 10) : displayheart_max;\r
+\r
+  uint16_t range = adjusted_max - adjusted_min;\r
+  uint16_t interval = range / 4; // 每个部分的宽度\r
+\r
+  // 设置动态心率数据\r
+  dynamic_heartrate[0] = adjusted_min;\r
+  dynamic_heartrate[1] = adjusted_min + interval;\r
+  dynamic_heartrate[2] = adjusted_min + 2 * interval;\r
+  dynamic_heartrate[3] = adjusted_min + 3 * interval;\r
+  dynamic_heartrate[4] = adjusted_max;\r
+\r
+  // 确保所有值为整数\r
+  for (int i = 0; i < 5; i++) {\r
+    dynamic_heartrate[i] = static_cast<uint16_t>(round(dynamic_heartrate[i]));\r
+  }\r
+\r
+  // 打印动态心率数据\r
+  for (int i = 0; i < 5; i++) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "dynamic_heartrate[%d]=%d", i,\r
+                  dynamic_heartrate[i]);\r
+  }\r
+}\r
+// 获取动态心率配置数组\r
+uint16_t *HeartModel::GetArrayData() { return dynamic_heartrate; }\r
+\r
+// 获取检测字符串\r
+// 获取检测字符串\r
+// TODO: 适配多国语言\r
+std::string HeartModel::GetCheckString() {\r
+  std::string check_string = "检测结果未知";\r
+\r
+  // 获取检测数据\r
+  if (currentheart == 0) {\r
+    if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN) {\r
+      check_string = "暂无检测数据";\r
+    } else {\r
+      check_string = "No detection data is available";\r
     }\r
-\r
-    if (IndoorWalkPreparedView::GetInstance() != nullptr) {\r
-        IndoorWalkPreparedView::GetInstance()->RefreshHeartbeatData(perSec);\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "检测数据:%s", check_string.c_str());\r
+    return check_string;\r
+  }\r
+\r
+  // 获取目前的时间戳\r
+  uint32_t currentTime;\r
+  if (uapi_get_timestampe_ss(&currentTime) != ERRCODE_SUCC) {\r
+    if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN) {\r
+      check_string = "获取当前时间失败";\r
+    } else {\r
+      check_string = "Get time failed";\r
     }\r
-    if (IndoorWalkPresenter::GetInstance() != nullptr) {\r
-        IndoorWalkPresenter::GetInstance()->ModifiesHeartRate(perSec);\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "获取当前时间失败");\r
+    return check_string;\r
+  }\r
+\r
+  // 检查时间戳是否有效\r
+  if (timestamp_ms == 0) {\r
+    if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN) {\r
+      check_string = std::to_string(currentheart) + " " + "时间无效,无法检测";\r
+    } else {\r
+      check_string =\r
+          std::to_string(currentheart) + " " + "Invalid time, cannot detect";\r
     }\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "时间戳无效,无法检测:%s",\r
+                  check_string.c_str());\r
+    return check_string;\r
+  }\r
+\r
+  // 进行时间戳相减计算\r
+  uint32_t diff = currentTime - timestamp_ms;\r
+  uint32_t diff_min = diff / 60;\r
+  uint32_t diff_hour = diff_min / 60;\r
+\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "当前时间:%d, 上次检测时间:%d",\r
+                currentTime, timestamp_ms);\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                "时间差(秒):%d, 时间差(分钟):%d, 时间差(小时):%d", diff,\r
+                diff_min, diff_hour);\r
+\r
+  // 根据时间差生成检测字符串\r
+  if (diff_min < 1) {\r
+    if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN) {\r
+      check_string = std::to_string(currentheart) + "次/分 " + "刚刚检测"; //\r
+    } else {\r
+      check_string = std::to_string(currentheart) + " bpm " + "Just detected";\r
+    }\r
+  } else if (diff_hour < 1) { // Within one hour\r
+    if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN) {\r
+      check_string = std::to_string(currentheart) + "次/分 " +\r
+                     std::to_string(diff_min) + "分钟前";\r
+    } else {\r
+      check_string = std::to_string(currentheart) + " bpm " +\r
+                     std::to_string(diff_min) + " minutes ago";\r
+    }\r
+  } else {\r
+    if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN) {\r
+      check_string = std::to_string(currentheart) + "次/分 " + "超过一个小时前";\r
+    } else {\r
+      check_string =\r
+          std::to_string(currentheart) + " bpm " + "More than an hour ago";\r
+    }\r
+  }\r
 \r
-    if (MainViewSample::GetInstance() != nullptr && HeartRateView::GetInstance() != nullptr) {\r
-        if (MainViewSample::GetInstance()->GetHorCurrentCard() == HEART_RATE) {\r
-            HeartRateView::GetInstance()->SetHeartRateData(rateData, sizeof(Point) * len);\r
-            HeartRateView::GetInstance()->RefreshElectrocardiogram();\r
-            HeartRateView::GetInstance()->RefreshHeartRatePerSec(perSec);\r
-            HeartRateView::GetInstance()->RefreshHeartRateMax(maxRate);\r
-            HeartRateView::GetInstance()->RefreshHeartRateMin(minRate);\r
-        }\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "检测结果:%s", check_string.c_str());\r
+  return check_string; // Return the final string\r
+}\r
+\r
+// 声明定时器变量\r
+static osTimerId_t g_screen60s_timer = nullptr;\r
+static uint16_t SCREEN_60S_TIME = 60;\r
+\r
+static void heart_start_screen60s_timer_callbackProc(int data) {\r
+  WEARABLE_LOGD(\r
+      WEARABLE_LOG_MODULE_APP,\r
+      "HeartModel::heart_start_screen60s_timer_callbackProc,time = %d",\r
+      SCREEN_60S_TIME);\r
+  SCREEN_60S_TIME -= 30;\r
+  WEARABLE_LOGD(\r
+      WEARABLE_LOG_MODULE_APP,\r
+      "HeartModel::heart_start_screen60s_timer_callbackProc,time = %d",\r
+      SCREEN_60S_TIME);\r
+  if (SCREEN_60S_TIME <= 0) {\r
+    // 60s后息屏停止定时\r
+    HeartModel::GetInstance()->heart_stop_screen60s_timer();\r
+    // 取消常亮屏\r
+    ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "heart_stop_screen60s_timer");\r
+  }\r
+}\r
+static void heart_start_screen60s_timer_callback(int data) {\r
+  GraphicService::GetInstance()->PostGraphicEvent(\r
+      std::bind(heart_start_screen60s_timer_callbackProc, data));\r
+}\r
+void HeartModel::heart_start_screen60s_timer(uint32_t interval) {\r
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                "HeartModel::heart_start_screen60s_timer");\r
+  /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回\r
+   * ------------------------- */\r
+  if (g_screen60s_timer != nullptr) {\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");\r
+    return;\r
+  }\r
+  /* --------------------------------- 2.创建定时器\r
+   * -------------------------------- */\r
+  g_screen60s_timer =\r
+      osTimerNew((osTimerFunc_t)heart_start_screen60s_timer_callback,\r
+                 osTimerPeriodic, nullptr, nullptr);\r
+  // 检查定时器创建是否成功\r
+  if (g_screen60s_timer == nullptr) {\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");\r
+    return;\r
+  }\r
+  /* ----------------------------- 3.将毫秒转换为系统时钟节拍数\r
+   * ---------------------------- */\r
+  int tick = osMs2Tick(interval);\r
+  /* --------------------------------- 4.启动定时器\r
+   * -------------------------------- */\r
+  osStatus_t ret = osTimerStart(g_screen60s_timer, tick);\r
+  /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为\r
+   * nullptr -------------------- */\r
+  if (ret != osOK) {\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!",\r
+                  ret);\r
+    if (g_screen60s_timer != nullptr) {\r
+      ret = osTimerDelete(g_screen60s_timer);\r
+    }\r
+    g_screen60s_timer = nullptr;\r
+    return;\r
+  }\r
+}\r
+void HeartModel::heart_stop_screen60s_timer(void) {\r
+  // 检查定时器是否存在\r
+  if (g_screen60s_timer != nullptr) {\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                  "HeartModel::heart_stop_screen60s_timer");\r
+    osTimerStop(g_screen60s_timer);\r
+    // 删除定时器并置为 nullptr\r
+    osStatus_t ret = osTimerDelete(g_screen60s_timer);\r
+    if (ret != osOK) {\r
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                    "osTimerDelete failed, ret = %lx!!", ret);\r
     }\r
+    g_screen60s_timer = nullptr;\r
+    SCREEN_60S_TIME = 60;\r
+  }\r
 }\r
+void HeartModel::reset_heart_screen60s_timer_time() {\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "reset_heart_screen60s_timer_time");\r
+  SCREEN_60S_TIME = 60;\r
+  if (nullptr == g_screen60s_timer) {\r
+    ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); // 重新常亮屏\r
+    heart_start_screen60s_timer();            // 开启定时器\r
+  }\r
 }\r
 \r
+} // namespace OHOS\r
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartNoteView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartNoteView.cpp
new file mode 100644 (file)
index 0000000..4fc7ca9
--- /dev/null
@@ -0,0 +1,115 @@
+
+#include "heartrate/include/HeartNoteView.h"
+#include "heartrate/include/HeartChartPresenter.h"
+#include "ui_resource_string.h"
+#include "uicomponents/UIComponents.h"
+#include "wearable_log.h"
+#include <custom_utils.h>
+namespace OHOS {
+
+static const char *ICON_PATH_NOTE = "/user/res/Blood/Error.bin";
+
+HeartNoteView::HeartNoteView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartNoteView::HeartNoteView");
+}
+
+HeartNoteView::~HeartNoteView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartNoteView::~HeartNoteView");
+  CrearAllView();
+}
+
+bool HeartNoteView::CrearAllView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartNoteView::CrearAllView");
+  if (heartNoteView) {
+    heartNoteView->RemoveAll();
+    if (noteimage) {
+      delete noteimage;
+      noteimage = nullptr;
+    }
+    if (StButton) {
+      delete StButton;
+      StButton = nullptr;
+    }
+    if (ReButton) {
+      delete ReButton;
+      ReButton = nullptr;
+    }
+    if (titleLabel) {
+      delete titleLabel;
+      titleLabel = nullptr;
+    }
+    if (noteLabel) {
+      delete noteLabel;
+      noteLabel = nullptr;
+    }
+    delete heartNoteView;
+    heartNoteView = nullptr;
+  }
+  return true;
+}
+UIScrollView *HeartNoteView::CreateHeartNoteView(void) {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                "CreateHeartNoteView::CreateHeartNoteView");
+  /* --------------------------------------------------------------------------
+   */
+  if (heartNoteView == nullptr) {
+    heartNoteView = new UIScrollView();
+    if (heartNoteView == nullptr) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heartNoteView new fail");
+      return nullptr;
+    }
+  }
+  heartNoteView->SetPosition(0, 0, 466, 466);
+  heartNoteView->SetScrollBlankSize(50);
+  heartNoteView->SetReboundSize(35);
+  heartNoteView->SetThrowDrag(true);
+  heartNoteView->SetMaxScrollDistance(1000);
+  heartNoteView->SetDirection(UIScrollView::VERTICAL);
+  // 设置拖拽监听器
+  UIView::OnDragListener *dragListener =
+      static_cast<UIView::OnDragListener *>(HeartChartPresenter::GetInstance());
+  if (!dragListener) {
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                  "HeartChartPresenter::获取实例失败!");
+    return nullptr; // 获取失败,返回空指针
+  }
+  heartNoteView->SetOnDragListener(dragListener);
+
+  /* 初始化图片 */
+  InitImageView(noteimage, 193, 120, 80, 80, "image", ICON_PATH_NOTE);
+
+  /*初始化title*/
+  InitRollLabel(titleLabel, 83, 50, 300, 35, "title", STR_CHECKERROR,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  InitLabelExt(noteLabel, 53, 230, 360, 70, "time", STR_PWUWC,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  // 设置来回滚动属性
+  noteLabel->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION);
+  noteLabel->SetRollSpeed(23);
+
+  /*初始化button*/
+  InitButtonExt(StButton, 58, 320, 170, 90, CLICK_HEART_STOP, STR_STOP, 30);
+  StButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919); // 设置按键颜色
+
+  UIView::OnClickListener *buttonClickst =
+      static_cast<UIView::OnClickListener *>(
+          HeartChartPresenter::GetInstance());
+  StButton->SetOnClickListener(buttonClickst);
+
+  InitButtonExt(ReButton, 238, 320, 170, 90, CLICK_HEART_RESTART, STR_RECHECK,
+                30);
+  ReButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xffFF8A36); // 设置按键颜色
+  UIView::OnClickListener *buttonClickre =
+      static_cast<UIView::OnClickListener *>(
+          HeartChartPresenter::GetInstance());
+  ReButton->SetOnClickListener(buttonClickre);
+
+  heartNoteView->Add(noteimage);
+  heartNoteView->Add(titleLabel);
+  heartNoteView->Add(noteLabel);
+  heartNoteView->Add(StButton);
+  heartNoteView->Add(ReButton);
+
+  return heartNoteView;
+}
+} // namespace OHOS
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartRateCardView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartRateCardView.cpp
new file mode 100644 (file)
index 0000000..1c938c0
--- /dev/null
@@ -0,0 +1,68 @@
+#include "heartrate/include/HeartRateCardView.h"
+#include "heartrate/include/HeartChartView.h"
+
+namespace OHOS {
+static HeartRateCardView *g_pHeartRateCardView = nullptr;
+HeartRateCardView::HeartRateCardView() {
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                "HeartRateCardView::HeartRateCardView");
+  SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);
+  g_pHeartRateCardView = this;
+}
+HeartRateCardView::~HeartRateCardView() {
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                "HeartRateCardView::~HeartRateCardView");
+  ClearAll();
+  g_pHeartRateCardView = nullptr;
+}
+HeartRateCardView *HeartRateCardView::GetInstance() {
+  return g_pHeartRateCardView;
+}
+void HeartRateCardView::ClearAll(void) {
+  if (viewiInitStatus == true) {
+    RemoveAll();
+    if (heartRateGroupView != nullptr) {
+      heartRateGroupView->RemoveAll();
+      heartRateCardView->HeartbeatImageAnimatorStop();
+      delete heartRateCardView;
+      heartRateCardView = nullptr;
+      delete heartRateGroupView;
+      heartRateGroupView = nullptr;
+    }
+  }
+}
+
+bool HeartRateCardView::InitView(void) {
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateCardView::InitView");
+  heartRateCardView = new HeartChartView();
+  if (heartRateCardView == nullptr) {
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                  "HeartChartView::new HeartChartView fail!");
+    return false;
+  }
+
+  heartRateGroupView =
+      dynamic_cast<UIViewGroup *>(heartRateCardView->GetchartGroup());
+  if (heartRateGroupView == nullptr) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "HeartChartView->HeartChartViewInit() == nullptr!!");
+    return false;
+  }
+
+  Add(heartRateGroupView);
+  return true;
+}
+UIViewGroup *HeartRateCardView::GetHeartRateCardView() {
+  return heartRateGroupView;
+}
+void HeartRateCardView::PreLoad(void) {
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateCardView::PreLoad");
+  if (!viewiInitStatus) {
+    InitView();
+    viewiInitStatus = true;
+  }
+}
+void HeartRateCardView::UnLoad(void) {
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateCardView::UnLoad");
+}
+} // namespace OHOS
\ No newline at end of file
index 32e84d6..0c8d3fc 100644 (file)
 #include "ScreenModels.h"\r
 #include "ui_resource_image.h"\r
 #include "common/image_cache_manager.h"\r
-\r
-namespace OHOS {\r
-static HeartRateView *g_pHeartRateView = nullptr;\r
+#include "heart_blood/health_service/health_service.h"\r
+#include "string.h"\r
+#define HEART_DATA_TEST 0\r
+namespace OHOS\r
+{\r
+    static HeartRateView *g_pHeartRateView = nullptr;\r
 \r
 // 背景坐标图形\r
-#define ACT_IMAGE_X 0                               // 图片坐标起点\r
-#define ACT_IMAGE_Y 115                             // 图片坐标起点\r
-#define ACT_IMAGE_COOR_X 45                         // 200刻度线到最左端的像素点\r
+#define ACT_IMAGE_X 38                              // 图片坐标起点\r
+#define ACT_IMAGE_Y 130                             // 图片坐标起点\r
+#define ACT_IMAGE_COOR_X 80                         // 200刻度线到最左端的像素点\r
 #define ACT_IMAGE_COOR_Y 145                        // 200刻度线到顶端的像素点\r
 #define ACT_IMAGE_COOR_PIXELS 160                   // 实际背景坐标0到200心率值的实际像素点\r
 #define ACT_IMAGE_COOR_VALUE HEART_RATE_LIMIT_UPPER // 图片刻度表示的心率范围\r
-#define ACT_IMAGE_COOR_WIDTH 454\r
-#define ACT_IMAGE_COOR_HEIGHT 220\r
+#define ACT_IMAGE_COOR_WIDTH 390\r
+#define ACT_IMAGE_COOR_HEIGHT 200\r
 \r
 // 心电图坐标适配\r
 #define COORDINATE_VALUE 5 // 余量\r
@@ -36,13 +39,120 @@ static HeartRateView *g_pHeartRateView = nullptr;
 #define COORDINATE_GRAD_MAX_OPA 180\r
 \r
 // 心形心跳\r
-#define HEARTBEAT_IMAGE_WIDTH 92\r
-#define HEARTBEAT_IMAGE_HEIGHT 92\r
-#define HEARTBEAT_IMAGE_X 130\r
-#define HEARTBEAT_IMAGE_Y 25\r
-#define HEARTBEAT_IMAGE_NUM 19\r
-#define HEARTBEAT_DELAY 50\r
-\r
+static constexpr int HEARTBEAT_IMAGE_WIDTH = 54;\r
+static constexpr int HEARTBEAT_IMAGE_HEIGHT = 50;\r
+static constexpr int HEARTBEAT_IMAGE_X = 111;\r
+static constexpr int HEARTBEAT_IMAGE_Y = 57;\r
+static constexpr int HEARTBEAT_IMAGE_NUM = 21;\r
+static constexpr int HEARTBEAT_DELAY = 50;\r
+// 心跳image\r
+static ImageAnimatorInfo g_heartBeatImageInfo[HEARTBEAT_IMAGE_NUM] = {\r
+    {PNG_A004_070_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_071_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_072_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_073_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_074_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_075_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_076_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_077_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_078_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_079_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_080_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_081_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_082_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_083_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_084_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_085_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_086_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_087_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_088_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_089_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+    {PNG_A004_090_IMAGE_PATH,\r
+     {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y},\r
+     HEARTBEAT_IMAGE_WIDTH,\r
+     HEARTBEAT_IMAGE_HEIGHT,\r
+     IMG_SRC_FILE_PATH},\r
+};\r
 // 最高心率\r
 #define TOP_IMAGE_WIDTH 32\r
 #define TOP_IMAGE_HEIGHT 32\r
@@ -89,10 +199,10 @@ static HeartRateView *g_pHeartRateView = nullptr;
 #define REST_HEART_TEXT_HEIGHT2 (REST_HEART_TEXT_FONT_SIZE + 5)\r
 \r
 // 每秒心率\r
-#define PERSEC_HEART_RATE_FONT_SIZE 45\r
-#define PERSEC_HEART_RATE_X 225\r
-#define PERSEC_HEART_RATE_Y 55\r
-#define PERSEC_HEART_RATE_WIDTH 90\r
+#define PERSEC_HEART_RATE_FONT_SIZE 60\r
+#define PERSEC_HEART_RATE_X 202\r
+#define PERSEC_HEART_RATE_Y 62\r
+#define PERSEC_HEART_RATE_WIDTH 102\r
 #define PERSEC_HEART_RATE_HEIGHT (PERSEC_HEART_RATE_FONT_SIZE + 5)\r
 \r
 #define PERSEC_HEART_TEXT_FONT_SIZE 30\r
@@ -101,686 +211,961 @@ static HeartRateView *g_pHeartRateView = nullptr;
 #define PERSEC_HEART_TEXT_WIDTH 75\r
 #define PERSEC_HEART_TEXT_HEIGHT (PERSEC_HEART_TEXT_FONT_SIZE + 5)\r
 \r
-// 心跳image\r
-static ImageAnimatorInfo g_heartBeatImageInfo[HEARTBEAT_IMAGE_NUM] = {\r
-    {PNG_A004_070_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_071_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_072_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_073_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_074_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_075_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_076_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_077_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_078_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_079_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-\r
-    {PNG_A004_080_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_081_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_082_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_083_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_084_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_085_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_086_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_087_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_088_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-};\r
 \r
-HeartRateView::HeartRateView()\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView");\r
-    dataNume = 0;\r
-    currIndex = 0;\r
-    serialIndex = 0;\r
-    maxRate = 0;\r
-    minRate = HEART_RATE_LIMIT_UPPER;\r
-    InitHeartRateData();\r
-    SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);\r
-\r
-    g_pHeartRateView = this;\r
-}\r
-\r
-HeartRateView::~HeartRateView()\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::~HeartRateView");\r
-    if (viewiInitStatus) {\r
-        int32_t i;\r
-        RemoveAll();\r
-        delete imageViewCoordinate;\r
-        imageViewCoordinate = nullptr;\r
+    HeartRateView::HeartRateView()\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView");\r
+        dataNume = 0;\r
+        currIndex = 0;\r
+        serialIndex = 0;\r
+        maxRate = 0;\r
+        minRate = HEART_RATE_LIMIT_UPPER;\r
+        InitHeartRateData();\r
+        SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);\r
 \r
-        chart->ClearDataSerial();\r
-        for (i = 0; i < HEART_AVE_NUM; i++) {\r
-            delete dataSerial[i];\r
-            dataSerial[i] = nullptr;\r
+        g_pHeartRateView = this;\r
+    }\r
+\r
+    HeartRateView::~HeartRateView()\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::~HeartRateView");\r
+        if (viewiInitStatus == true)\r
+        {\r
+            int32_t i;\r
+            RemoveAll();\r
+            // UnLoadHeartRateImageRes();\r
+            delete imageViewCoordinate;\r
+            imageViewCoordinate = nullptr;\r
+\r
+            chart->ClearDataSerial();\r
+            for (i = 0; i < HEART_AVE_NUM; i++)\r
+            {\r
+                delete dataSerial[i];\r
+                dataSerial[i] = nullptr;\r
+            }\r
+            heartchart->ClearDataSerial();\r
+            delete heartSerial;\r
+            heartSerial = nullptr;\r
+            delete heartchart;\r
+            delete chart;\r
+            chart = nullptr;\r
+            delete imageViewTop;\r
+            imageViewTop = nullptr;\r
+            delete imageViewBottom;\r
+            imageViewBottom = nullptr;\r
+            delete dataTopAndbottom;\r
+            dataTopAndbottom = nullptr;\r
+            imageAnimator->Stop();\r
+            delete imageAnimator;\r
+            imageAnimator = nullptr;\r
+            delete topRate;\r
+            topRate = nullptr;\r
+            delete bottomRate;\r
+            bottomRate = nullptr;\r
+            delete ratePerSec;\r
+            ratePerSec = nullptr;\r
+            delete ratePerSecText;\r
+            ratePerSecText = nullptr;\r
+            delete restRate;\r
+            restRate = nullptr;\r
+            delete restRateText1;\r
+            restRateText1 = nullptr;\r
+            delete restRateText2;\r
+            restRateText2 = nullptr;\r
         }\r
-        delete chart;\r
-        chart = nullptr;\r
-        delete imageViewTop;\r
-        imageViewTop = nullptr;\r
-        delete imageViewBottom;\r
-        imageViewBottom = nullptr;\r
-        delete dataTopAndbottom;\r
-        dataTopAndbottom = nullptr;\r
-        imageAnimator->Stop();\r
-        delete imageAnimator;\r
-        imageAnimator = nullptr;\r
-        delete topRate;\r
-        topRate = nullptr;\r
-        delete bottomRate;\r
-        bottomRate = nullptr;\r
-        delete ratePerSec;\r
-        ratePerSec = nullptr;\r
-        delete ratePerSecText;\r
-        ratePerSecText = nullptr;\r
-        delete restRate;\r
-        restRate = nullptr;\r
-        delete restRateText1;\r
-        restRateText1 = nullptr;\r
-        delete restRateText2;\r
-        restRateText2 = nullptr;\r
-    }\r
-    g_pHeartRateView = nullptr;\r
-}\r
-\r
-HeartRateView *HeartRateView::GetInstance(void)\r
-{\r
-    return g_pHeartRateView;\r
-}\r
+        g_pHeartRateView = nullptr;\r
+    }\r
 \r
-int32_t HeartRateView::InitHeartRateData(void) // 初始化心率数据,将存放心率数据的有效字节设置为无效值\r
-{\r
-    heartRateData[0].x = INVALID_HEART_VALUE;\r
-    heartRateData[0].y = INVALID_HEART_VALUE;\r
+    HeartRateView *HeartRateView::GetInstance(void)\r
+    {\r
+        return g_pHeartRateView;\r
+    }\r
+\r
+    int32_t HeartRateView::InitHeartRateData(void) // 初始化心率数据,将存放心率数据的有效字节设置为无效值\r
+    {\r
+        int32_t ret;\r
+\r
+        heartRateData[0].x = INVALID_HEART_VALUE;\r
+        heartRateData[0].y = INVALID_HEART_VALUE;\r
 \r
-    int32_t ret = memset_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM);\r
-    if (ret != 0) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InitHeartRateData] memset_s heartRateData fail! ret = %d", ret);\r
+        ret = memset_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM);\r
+        if (ret != 0)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InitHeartRateData] memset_s heartRateData fail! ret = %d", ret);\r
+        }\r
+        return ret;\r
     }\r
-    return ret;\r
-}\r
 \r
-int32_t HeartRateView::SetHeartRateData(Point *rateData, uint32 rateDataSize)\r
-{\r
-    if (rateData == nullptr) {\r
-        return OHOS_FAILURE;\r
+    int32_t HeartRateView::SetHeartRateData(Point *rateData, uint32 rateDataSize)\r
+    {\r
+        int ret;\r
+\r
+        if (rateData == nullptr)\r
+        {\r
+            return OHOS_FAILURE;\r
+        }\r
+\r
+        if (rateDataSize > sizeof(Point) * HEART_AVE_NUM)\r
+        {\r
+            rateDataSize = sizeof(Point) * HEART_AVE_NUM;\r
+        }\r
+        InitHeartRateData();\r
+        ret = memcpy_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, rateData, rateDataSize);\r
+        if (ret != EOK)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s heartRateData fail! ret = %d", ret);\r
+            return OHOS_FAILURE;\r
+        }\r
+\r
+        return OHOS_SUCCESS;\r
     }\r
+    int32_t HeartRateView::HeartRateDataProc(void)\r
+    {\r
+        int32_t i, ret;\r
+        Point datain[HEART_AVE_NUM];\r
+\r
+        ret = memcpy_s(datain, sizeof(Point) * HEART_AVE_NUM, heartRateData, sizeof(Point) * HEART_AVE_NUM);\r
+        if (ret != EOK)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s rateDataTmp fail! ret = %d", ret);\r
+            return OHOS_FAILURE;\r
+        }\r
+\r
+        ret = memset_s(rateDataTmp, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM); // 替换为无效值\r
+        if (ret != EOK)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memset_s rateDataTmp fail! ret = %d", ret);\r
+            return OHOS_FAILURE;\r
+        }\r
+\r
+        dataNume = 0;\r
+        for (i = 0; i < HEART_AVE_NUM; i += 15) // 每跨过15个点代表一个小时\r
+        {\r
+            if (datain[i].x >= 0 && datain[i].x < HEART_AVE_NUM && datain[i].y > 0 &&\r
+                datain[i].y <= HEART_RATE_LIMIT_UPPER)\r
+            {\r
+                rateDataTmp[dataNume].x = datain[i].x + COORDINATE_VALUE;\r
+                rateDataTmp[dataNume].y = datain[i].y * ACT_IMAGE_COOR_PIXELS / ACT_IMAGE_COOR_VALUE;\r
+                dataNume++;\r
+            }\r
+        }\r
 \r
-    if (rateDataSize > sizeof(Point) * HEART_AVE_NUM) {\r
-        rateDataSize = sizeof(Point) * HEART_AVE_NUM;\r
+        return OHOS_SUCCESS;\r
     }\r
-    InitHeartRateData();\r
-    int32_t ret = memcpy_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, rateData, rateDataSize);\r
-    if (ret != EOK) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s heartRateData fail! ret = %d", ret);\r
-        return OHOS_FAILURE;\r
+\r
+    void HeartRateView::SetLabel(UILabel *label, LabelInfo labelInfo)\r
+    {\r
+        label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelInfo.fontSize);\r
+        label->SetPosition(labelInfo.x, labelInfo.y);\r
+        label->Resize(labelInfo.width, labelInfo.height);\r
+        label->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT);\r
+        Add(label);\r
     }\r
-    return OHOS_SUCCESS;\r
-}\r
 \r
+    void HeartRateView::HeartRateLabelDisplay(void)\r
+    {\r
+        LabelInfo PerSecLabel = {PERSEC_HEART_RATE_FONT_SIZE, PERSEC_HEART_RATE_X, PERSEC_HEART_RATE_Y,\r
+                                 PERSEC_HEART_RATE_WIDTH, PERSEC_HEART_RATE_HEIGHT};\r
+        LabelInfo PerSecTextLabel = {PERSEC_HEART_TEXT_FONT_SIZE, PERSEC_HEART_TEXT_X, PERSEC_HEART_TEXT_Y,\r
+                                     PERSEC_HEART_TEXT_WIDTH, PERSEC_HEART_TEXT_HEIGHT};\r
+\r
+        LabelInfo topLabel = {HEART_RATE_LIMIT_FONT_SIZE, TOP_TEXT_X, TOP_TEXT_Y, TOP_TEXT_WIDTH, TOP_TEXT_HEIGHT};\r
+        LabelInfo bottomLabel = {HEART_RATE_LIMIT_FONT_SIZE, BOTTOM_TEXT_X, BOTTOM_TEXT_Y, BOTTOM_TEXT_WIDTH,\r
+                                 BOTTOM_TEXT_HEIGHT};\r
+\r
+        topRate = new UILabel();\r
+        bottomRate = new UILabel();\r
+        ratePerSec = new UILabel();\r
+        ratePerSecText = new UILabel();\r
+\r
+        if (topRate == nullptr || bottomRate == nullptr || ratePerSec == nullptr || ratePerSecText == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateLabelDisplay] new UILabel fail");\r
+        }\r
 \r
-int32_t HeartRateView::HeartRateDataProc(void)\r
-{\r
-    Point datain[HEART_AVE_NUM];\r
-    int32_t ret = memcpy_s(datain, sizeof(Point) * HEART_AVE_NUM, heartRateData, sizeof(Point) * HEART_AVE_NUM);\r
-    if (ret != EOK) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s rateDataTmp fail! ret = %d", ret);\r
-        return OHOS_FAILURE;\r
+        // 实时心率\r
+        SetLabel(ratePerSec, PerSecLabel);\r
+        SetLabel(ratePerSecText, PerSecTextLabel);\r
+        ratePerSec->SetText("--");\r
+        ratePerSec->SetFont(GILROY_BOLD_FONT, PERSEC_HEART_RATE_FONT_SIZE);\r
+        ratePerSecText->SetText("次/分");\r
+\r
+        // 最高最低心率\r
+        SetLabel(topRate, topLabel);\r
+        SetLabel(bottomRate, bottomLabel);\r
+        topRate->SetText("--");\r
+        bottomRate->SetText("--");\r
     }\r
 \r
-    ret = memset_s(rateDataTmp, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM); // 替换为无效值\r
-    if (ret != EOK) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memset_s rateDataTmp fail! ret = %d", ret);\r
-        return OHOS_FAILURE;\r
+    void HeartRateView::HeartRateCoordinate(void)\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateCoordinate start");\r
+        // 坐标图片\r
+        imageViewCoordinate = new UIImageView();\r
+        if (imageViewCoordinate == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new imageViewCoordinate fail");\r
+            return;\r
+        }\r
+        imageViewCoordinate->SetPosition(ACT_IMAGE_X, ACT_IMAGE_Y);\r
+        imageViewCoordinate->SetWidth(ACT_IMAGE_COOR_WIDTH);\r
+        imageViewCoordinate->SetHeight(ACT_IMAGE_COOR_HEIGHT);\r
+        Add(imageViewCoordinate);\r
+\r
+        //  心电图坐标适配\r
+        chart = new UIChartPolyline();\r
+        if (chart == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new chart fail");\r
+            return;\r
+        }\r
+        chart->SetPosition(COORDINATE_POINT_X, COORDINATE_POINT_Y);\r
+        chart->SetWidth(COORDINATE_WIDTH);\r
+        chart->SetHeight(COORDINATE_HEIGHT);\r
+        chart->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
+        chart->SetStyle(STYLE_BACKGROUND_OPA, 0);\r
+        chart->SetStyle(STYLE_LINE_WIDTH, 1); // line width\r
+\r
+        UIXAxis &xAxis = chart->GetXAxis();\r
+        UIYAxis &yAxis = chart->GetYAxis();\r
+        xAxis.SetDataRange(0, COORDINATE_WIDTH); // 24小时对应的秒数\r
+        yAxis.SetDataRange(0, COORDINATE_HEIGHT);\r
+        xAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+        yAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+        chart->SetGradientOpacity(COORDINATE_GRAD_MIN_OPA, COORDINATE_GRAD_MAX_OPA);\r
+        chart->SetVisible(false); // 设置不可见\r
+        Add(chart);\r
     }\r
+    void HeartRateView::InitChartTest(void)\r
+    {\r
+        if (heartchart == nullptr)\r
+        {\r
+            heartchart = new UIChartPolyline();\r
+        }\r
+        heartchart->SetPosition(95, 178);\r
+        heartchart->Resize(320, 110);\r
+        heartchart->SetViewId("uiChart");\r
+        heartchart->SetStyle(STYLE_BACKGROUND_OPA, 0x00);\r
+\r
+        UIXAxis &heartXAxis = heartchart->GetXAxis();\r
+        UIYAxis &heartYAxis = heartchart->GetYAxis();\r
+        heartXAxis.SetMarkNum(1);\r
+        heartXAxis.SetDataRange(0, 24);\r
+        heartXAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+        heartYAxis.SetMarkNum(1);\r
+        heartYAxis.SetDataRange(0, 220);\r
+        heartYAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+\r
+        // heartchart->SetGradientOpacity(60, 0);\r
+        heartchart->SetGradientOpacity(COORDINATE_GRAD_MIN_OPA, COORDINATE_GRAD_MAX_OPA);\r
+        Add(heartchart);\r
+    }\r
+    void HeartRateView::Init_data_Chart()\r
+    {\r
+        if (heartchart == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Init_data_Chart new chart fail");\r
+            return;\r
+        }\r
+        heartSerial = new UIChartDataSerial();\r
+        heartSerial->SetMaxDataCount(24);\r
+#if HEART_DATA_TEST\r
+        Point temp[] = {\r
+            {0, 150}, {1, 250}, {2, 170}, {3, 0}, {4, 140}, {5, 190}, {6, 100}, {7, 40}, {8, 10}, {9, 100}, {10, 60}, {11, 20}, {12, 150}, {13, 250}, {14, 170}, {15, 140}, {16, 78}, {17, 80}, {18, 100}, {19, 20}, {20, 100}, {21, 100}, {22, 100}, {23, 100}};\r
+        std::copy(std::begin(temp), std::end(temp), heartdata);\r
+#else\r
+        for (int serialIndex = 0; serialIndex < 24; serialIndex++)\r
+        {\r
+            heartdata[serialIndex].x = serialIndex;\r
+            heartdata[serialIndex].y = HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);\r
+        }\r
+#endif\r
+        heartSerial->AddPoints(heartdata, 24);\r
+\r
+        // heartSerial->SetFillColor(Color::GetColorFromRGBA(0xea, 0x53, 0x15, 0xff));\r
+        // heartSerial->SetLineColor(Color::GetColorFromRGBA(0xd8, 0x14, 0x14, 0xff));\r
+        // heartSerial->EnableGradient(true);\r
 \r
-    dataNume = 0;\r
-    for (int32_t i = 0; i < HEART_AVE_NUM; i++) {\r
-        if (datain[i].x >= 0 && datain[i].x < HEART_AVE_NUM && datain[i].y > 0 &&\r
-            datain[i].y <= HEART_RATE_LIMIT_UPPER) {\r
-            rateDataTmp[dataNume].x = datain[i].x + COORDINATE_VALUE;\r
-            rateDataTmp[dataNume].y = datain[i].y * ACT_IMAGE_COOR_PIXELS / ACT_IMAGE_COOR_VALUE;\r
-            dataNume++;\r
+        heartSerial->SetLineColor(Color::Red());\r
+        heartSerial->SetFillColor(Color::Red());\r
+        heartSerial->EnableGradient(true);\r
+\r
+        heartchart->AddDataSerial(heartSerial);\r
+        heartchart->Invalidate();\r
+    }\r
+    void HeartRateView::Update_data_Chart(int serialIndex)\r
+    {\r
+        if (heartchart == nullptr || topRate == nullptr || bottomRate == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Update_data_Chart fail %d", serialIndex);\r
+            return;\r
         }\r
+\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"开始更新曲线");\r
+\r
+        /*清空原数据*/\r
+        heartSerial->ClearData();\r
+\r
+        heartdata[serialIndex].x = serialIndex;\r
+        heartdata[serialIndex].y = HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);\r
+\r
+        heartSerial->AddPoints(heartdata, 24);\r
+        heartSerial->SetLineColor(Color::Red());\r
+        heartSerial->SetFillColor(Color::Red());\r
+        heartSerial->EnableGradient(true);\r
+\r
+        heartchart->AddDataSerial(heartSerial);\r
+        heartchart->Invalidate();\r
+\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"更新曲线完成");\r
+        // heartchart->RefreshChart();\r
     }\r
-    return OHOS_SUCCESS;\r
-}\r
+    void HeartRateView::CleanAllDataView()\r
+    {\r
+        if (heartchart == nullptr || topRate == nullptr || bottomRate == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CleanAllDataView fail");\r
+            return;\r
+        }\r
+        for (int serialIndex = 0; serialIndex < 24; serialIndex++)\r
+        {\r
+            heartdata[serialIndex].x = serialIndex;\r
+            heartdata[serialIndex].y = HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);\r
+        }\r
 \r
-void HeartRateView::SetLabel(UILabel *label, LabelInfo labelInfo)\r
-{\r
-    label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelInfo.fontSize);\r
-    label->SetPosition(labelInfo.x, labelInfo.y);\r
-    label->Resize(labelInfo.width, labelInfo.height);\r
-    label->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT);\r
-    Add(label);\r
-}\r
-\r
-void HeartRateView::HeartRateLabelDisplay(void)\r
-{\r
-    LabelInfo PerSecLabel = { PERSEC_HEART_RATE_FONT_SIZE, PERSEC_HEART_RATE_X, PERSEC_HEART_RATE_Y,\r
-                              PERSEC_HEART_RATE_WIDTH, PERSEC_HEART_RATE_HEIGHT };\r
-    LabelInfo PerSecTextLabel = { PERSEC_HEART_TEXT_FONT_SIZE, PERSEC_HEART_TEXT_X, PERSEC_HEART_TEXT_Y,\r
-                                  PERSEC_HEART_TEXT_WIDTH, PERSEC_HEART_TEXT_HEIGHT };\r
-\r
-    LabelInfo topLabel = { HEART_RATE_LIMIT_FONT_SIZE, TOP_TEXT_X, TOP_TEXT_Y, TOP_TEXT_WIDTH, TOP_TEXT_HEIGHT };\r
-    LabelInfo bottomLabel = { HEART_RATE_LIMIT_FONT_SIZE, BOTTOM_TEXT_X, BOTTOM_TEXT_Y, BOTTOM_TEXT_WIDTH,\r
-                              BOTTOM_TEXT_HEIGHT };\r
-\r
-    LabelInfo restRateLabel = { REST_HEART_RATE_FONT_SIZE, REST_HEART_RATE_X, REST_HEART_RATE_Y, REST_HEART_RATE_WIDTH,\r
-                                REST_HEART_RATE_HEIGHT };\r
-    LabelInfo restRateTextLabel1 = { REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X1, REST_HEART_TEXT_Y1,\r
-                                     REST_HEART_TEXT_WIDTH1, REST_HEART_TEXT_HEIGHT1 };\r
-    LabelInfo restRateTextLabel2 = { REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X2, REST_HEART_TEXT_Y2,\r
-                                     REST_HEART_TEXT_WIDTH2, REST_HEART_TEXT_HEIGHT2 };\r
-\r
-    topRate = new UILabel();\r
-    bottomRate = new UILabel();\r
-    ratePerSec = new UILabel();\r
-    ratePerSecText = new UILabel();\r
-    restRate = new UILabel();\r
-    restRateText1 = new UILabel();\r
-    restRateText2 = new UILabel();\r
-\r
-    if (topRate == nullptr || bottomRate == nullptr || ratePerSec == nullptr || ratePerSecText == nullptr ||\r
-        restRate == nullptr || restRateText1 == nullptr || restRateText2 == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateLabelDisplay] new UILabel fail");\r
-    }\r
-\r
-    // 实时心率\r
-    SetLabel(ratePerSec, PerSecLabel);\r
-    SetLabel(ratePerSecText, PerSecTextLabel);\r
-    ratePerSec->SetText("--");\r
-    ratePerSecText->SetText("次/分");\r
-\r
-    // 最高最低心率\r
-    SetLabel(topRate, topLabel);\r
-    SetLabel(bottomRate, bottomLabel);\r
-    topRate->SetText("--");\r
-    bottomRate->SetText("--");\r
-\r
-    // 静息心率\r
-    SetLabel(restRate, restRateLabel);\r
-    SetLabel(restRateText1, restRateTextLabel1);\r
-    SetLabel(restRateText2, restRateTextLabel2);\r
-    restRateText1->SetText("静息");\r
-    restRate->SetText("--");\r
-    restRateText2->SetText("次/分");\r
-}\r
-\r
-void HeartRateView::HeartRateCoordinate(void)\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateCoordinate start");\r
-    // 坐标图片\r
-    imageViewCoordinate = new UIImageView();\r
-    if (imageViewCoordinate == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new imageViewCoordinate fail");\r
-        return;\r
-    }\r
-    imageViewCoordinate->SetPosition(ACT_IMAGE_X, ACT_IMAGE_Y);\r
-    imageViewCoordinate->SetWidth(ACT_IMAGE_COOR_WIDTH);\r
-    imageViewCoordinate->SetHeight(ACT_IMAGE_COOR_HEIGHT);\r
-    Add(imageViewCoordinate);\r
-\r
-    //  心电图坐标适配\r
-    chart = new UIChartPolyline();\r
-    if (chart == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new chart fail");\r
-        return;\r
-    }\r
-    chart->SetPosition(COORDINATE_POINT_X, COORDINATE_POINT_Y);\r
-    chart->SetWidth(COORDINATE_WIDTH);\r
-    chart->SetHeight(COORDINATE_HEIGHT);\r
-    chart->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
-    chart->SetStyle(STYLE_BACKGROUND_OPA, 0);\r
-    chart->SetStyle(STYLE_LINE_WIDTH, 1); // line width\r
-\r
-    UIXAxis &xAxis = chart->GetXAxis();\r
-    UIYAxis &yAxis = chart->GetYAxis();\r
-    xAxis.SetDataRange(0, COORDINATE_WIDTH); // 24小时对应的秒数\r
-    yAxis.SetDataRange(0, COORDINATE_HEIGHT);\r
-    xAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
-    yAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
-    chart->SetGradientOpacity(COORDINATE_GRAD_MIN_OPA, COORDINATE_GRAD_MAX_OPA);\r
-    Add(chart);\r
-}\r
-\r
-void HeartRateView::InsertTopAndBottomRateImage(void)\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InsertTopAndBottomRateImage start");\r
-    imageViewTop = new UIImageView();\r
-    imageViewBottom = new UIImageView();\r
-    if (imageViewTop == nullptr || imageViewBottom == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InsertTopAndBottomRateImage] new imageViewTop or imageViewBottom fail");\r
-        return;\r
-    }\r
-    imageViewTop->SetPosition(TOP_IMAGE_X, TOP_IMAGE_Y);\r
-    imageViewTop->SetWidth(TOP_IMAGE_WIDTH);\r
-    imageViewTop->SetHeight(TOP_IMAGE_HEIGHT);\r
-    Add(imageViewTop);\r
-    imageViewBottom->SetPosition(BOTTOM_IMAGE_X, BOTTOM_IMAGE_Y);\r
-    imageViewBottom->SetWidth(BOTTOM_IMAGE_WIDTH);\r
-    imageViewBottom->SetHeight(BOTTOM_IMAGE_HEIGHT);\r
-    Add(imageViewBottom);\r
-}\r
-\r
-void HeartRateView::UpdataTopAndBottomRate(void)\r
-{\r
-    if (chart == nullptr) {\r
-        return;\r
+        /*清空原数据*/\r
+        heartSerial->ClearData();\r
+        heartSerial->AddPoints(heartdata, 24);\r
+        heartSerial->SetLineColor(Color::Red());\r
+        heartSerial->SetFillColor(Color::Red());\r
+        heartSerial->EnableGradient(true);\r
+\r
+        heartchart->AddDataSerial(heartSerial);\r
+        heartchart->Invalidate();\r
+        // heartchart->RefreshChart();\r
+\r
+        /*更新最大最小值*/\r
+        SetDataTopAndBottom();\r
     }\r
-    if (dataTopAndbottom != nullptr) {\r
-        chart->DeleteDataSerial(dataTopAndbottom);\r
-        delete dataTopAndbottom;\r
-        dataTopAndbottom = nullptr;\r
+    /*设置最大最小数据*/\r
+    void HeartRateView::SetDataTopAndBottom()\r
+    {\r
+        int MaxHeart = HeartModel::GetInstance()->GetHeartRateMax();\r
+        int MinHeart = HeartModel::GetInstance()->GetHeartRateMin();\r
+\r
+        if (topRate != nullptr)\r
+        {\r
+            topRate->SetText(MaxHeart > 0 ? (std::to_string(MaxHeart)).c_str() : "--");\r
+        }\r
+\r
+        if (bottomRate != nullptr)\r
+        {\r
+            bottomRate->SetText(MinHeart > 0 ? (std::to_string(MinHeart)).c_str() : "--");\r
+        }\r
+\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MaxHeart: %d, MinHeart: %d", MaxHeart, MinHeart);\r
     }\r
-    dataTopAndbottom = new UIChartDataSerial();\r
-    if (dataTopAndbottom == nullptr) {\r
-        return;\r
+    void HeartRateView::InsertTopAndBottomRateImage(void)\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InsertTopAndBottomRateImage start");\r
+        imageViewTop = new UIImageView();\r
+        imageViewBottom = new UIImageView();\r
+        if (imageViewTop == nullptr || imageViewBottom == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InsertTopAndBottomRateImage] new imageViewTop or imageViewBottom fail");\r
+            return;\r
+        }\r
+        imageViewTop->SetPosition(TOP_IMAGE_X, TOP_IMAGE_Y);\r
+        imageViewTop->SetWidth(TOP_IMAGE_WIDTH);\r
+        imageViewTop->SetHeight(TOP_IMAGE_HEIGHT);\r
+        Add(imageViewTop);\r
+        imageViewBottom->SetPosition(BOTTOM_IMAGE_X, BOTTOM_IMAGE_Y);\r
+        imageViewBottom->SetWidth(BOTTOM_IMAGE_WIDTH);\r
+        imageViewBottom->SetHeight(BOTTOM_IMAGE_HEIGHT);\r
+        Add(imageViewBottom);\r
     }\r
-    if (dataNume != 1) {\r
-        dataTopAndbottom->SetMaxDataCount(dataNume);        // number of data points\r
-        dataTopAndbottom->AddPoints(rateDataTmp, dataNume); // number of data points\r
-    } else {\r
-        Point tmp[NUM_2];\r
-        tmp[0].x = tmp[1].x = rateDataTmp[0].x;\r
-        tmp[0].y = tmp[1].y = rateDataTmp[0].y;\r
-        dataTopAndbottom->SetMaxDataCount(NUM_2); // number of data points\r
-        dataTopAndbottom->AddPoints(tmp, NUM_2);  // number of data points\r
-    }\r
-    dataTopAndbottom->SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0)); // 设置透明\r
-    chart->AddDataSerial(dataTopAndbottom);\r
-    chart->Invalidate();\r
-\r
-    UIChartDataSerial::PointStyle pointStyle;\r
-    // 最低心跳\r
-    dataTopAndbottom->EnableBottomPoint(true);\r
-    pointStyle.radius = BOTTOM_RADIUS; // Inner radius\r
-    pointStyle.fillColor = Color::Gray();\r
-    pointStyle.strokeWidth = BOTTOM_STROKE_WIDTH; // border width\r
-    pointStyle.strokeColor = Color::Black();\r
-    dataTopAndbottom->SetBottomPointStyle(pointStyle);\r
-    chart->Invalidate();\r
-\r
-    uint16_t bottom = dataTopAndbottom->GetValleyData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
-    // 最高心跳\r
-    dataTopAndbottom->EnableTopPoint(true);\r
-    pointStyle.fillColor = Color::Red();\r
-    pointStyle.radius = TOP_RADIUS; // Inner radius\r
-    pointStyle.strokeColor = Color::Black();\r
-    pointStyle.strokeWidth = TOP_STROKE_WIDTH; // border width\r
-    dataTopAndbottom->SetTopPointStyle(pointStyle);\r
-    chart->Invalidate();\r
-\r
-    uint16_t top = dataTopAndbottom->GetPeakData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
-    if (top <= HEART_RATE_LIMIT_UPPER) {\r
-        maxRate = (maxRate >= top) ? maxRate : top;\r
-    }\r
-    if (bottom != 0) {\r
-        minRate = (minRate <= bottom) ? minRate : bottom;\r
-    }\r
-}\r
-\r
-void HeartRateView::ElectrocardiogramOnePoint(Point *rateData, uint16_t index)\r
-{\r
-    Point tmp[NUM_2];\r
 \r
-    if (rateData == nullptr || chart == nullptr || index >= HEART_AVE_NUM || serialIndex >= HEART_AVE_NUM) {\r
-        return;\r
+    void HeartRateView::UpdataTopAndBottomRate(void)\r
+    {\r
+        uint16_t bottom, top;\r
+        if (chart == nullptr)\r
+        {\r
+            return;\r
+        }\r
+        if (dataTopAndbottom != nullptr)\r
+        {\r
+            chart->DeleteDataSerial(dataTopAndbottom);\r
+            delete dataTopAndbottom;\r
+            dataTopAndbottom = nullptr;\r
+        }\r
+        dataTopAndbottom = new UIChartDataSerial();\r
+        if (dataTopAndbottom == nullptr)\r
+        {\r
+            return;\r
+        }\r
+        if (dataNume != 1)\r
+        {\r
+            dataTopAndbottom->SetMaxDataCount(dataNume);        // number of data points\r
+            dataTopAndbottom->AddPoints(rateDataTmp, dataNume); // number of data points\r
+        }\r
+        else\r
+        {\r
+            Point tmp[NUM_2];\r
+            tmp[0].x = tmp[1].x = rateDataTmp[0].x;\r
+            tmp[0].y = tmp[1].y = rateDataTmp[0].y;\r
+            dataTopAndbottom->SetMaxDataCount(NUM_2); // number of data points\r
+            dataTopAndbottom->AddPoints(tmp, NUM_2);  // number of data points\r
+        }\r
+        dataTopAndbottom->SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0)); // 设置透明\r
+        chart->AddDataSerial(dataTopAndbottom);\r
+        chart->Invalidate();\r
+\r
+        UIChartDataSerial::PointStyle pointStyle;\r
+        // 最低心跳\r
+        dataTopAndbottom->EnableBottomPoint(true);\r
+        pointStyle.radius = BOTTOM_RADIUS; // Inner radius\r
+        pointStyle.fillColor = Color::Gray();\r
+        pointStyle.strokeWidth = BOTTOM_STROKE_WIDTH; // border width\r
+        pointStyle.strokeColor = Color::Black();\r
+        dataTopAndbottom->SetBottomPointStyle(pointStyle);\r
+        chart->Invalidate();\r
+\r
+        bottom = dataTopAndbottom->GetValleyData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
+        // 最高心跳\r
+        dataTopAndbottom->EnableTopPoint(true);\r
+        pointStyle.fillColor = Color::Red();\r
+        pointStyle.radius = TOP_RADIUS; // Inner radius\r
+        pointStyle.strokeColor = Color::Black();\r
+        pointStyle.strokeWidth = TOP_STROKE_WIDTH; // border width\r
+        dataTopAndbottom->SetTopPointStyle(pointStyle);\r
+        chart->Invalidate();\r
+\r
+        top = dataTopAndbottom->GetPeakData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
+        if (top <= HEART_RATE_LIMIT_UPPER)\r
+        {\r
+            maxRate = (maxRate >= top) ? maxRate : top;\r
+        }\r
+        if (bottom != 0)\r
+        {\r
+            minRate = (minRate <= bottom) ? minRate : bottom;\r
+        }\r
     }\r
+    void HeartRateView::ElectrocardiogramOnePoint(Point *rateData, uint16_t index)\r
+    {\r
+        Point tmp[NUM_2];\r
+\r
+        if (rateData == nullptr || chart == nullptr || index >= HEART_AVE_NUM || serialIndex >= HEART_AVE_NUM)\r
+        {\r
+            return;\r
+        }\r
 \r
-    tmp[0].x = tmp[1].x = rateData[index].x;\r
-    tmp[0].y = tmp[1].y = rateData[index].y;\r
+        tmp[0].x = tmp[1].x = rateData[index].x;\r
+        tmp[0].y = tmp[1].y = rateData[index].y;\r
 \r
-    dataSerial[serialIndex] = new UIChartDataSerial();\r
-    if (dataSerial[serialIndex] == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramOnePoint] new dataSerial[%d] fail", serialIndex);\r
+        dataSerial[serialIndex] = new UIChartDataSerial();\r
+        if (dataSerial[serialIndex] == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramOnePoint] new dataSerial[%d] fail", serialIndex);\r
+            serialIndex++;\r
+            return;\r
+        }\r
+\r
+        dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // 设置最大显示的像素点\r
+        dataSerial[serialIndex]->AddPoints(tmp, NUM_2);\r
+        dataSerial[serialIndex]->SetLineColor(Color::Red());\r
+        dataSerial[serialIndex]->SetFillColor(Color::Red());\r
+        dataSerial[serialIndex]->EnableGradient(true);\r
+\r
+        chart->AddDataSerial(dataSerial[serialIndex]);\r
+        chart->Invalidate();\r
         serialIndex++;\r
-        return;\r
     }\r
 \r
-    dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // 设置最大显示的像素点\r
-    dataSerial[serialIndex]->AddPoints(tmp, NUM_2);\r
-    dataSerial[serialIndex]->SetLineColor(Color::Red());\r
-    dataSerial[serialIndex]->SetFillColor(Color::Red());\r
-    dataSerial[serialIndex]->EnableGradient(true);\r
-\r
-    chart->AddDataSerial(dataSerial[serialIndex]);\r
-    chart->Invalidate();\r
-    serialIndex++;\r
-}\r
+    void HeartRateView::ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume)\r
+    {\r
+        uint16_t i = 0;\r
+        uint16_t j = 0;\r
+        uint16_t tmp = 1;\r
+        if (rateData == nullptr || chart == nullptr || rateDataNume > HEART_AVE_NUM)\r
+        {\r
+            return;\r
+        }\r
 \r
-void HeartRateView::ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume)\r
-{\r
-    uint16_t i = 0;\r
-    uint16_t j = 0;\r
-    uint16_t tmp = 1;\r
-    if (rateData == nullptr || chart == nullptr || rateDataNume > HEART_AVE_NUM) {\r
-        return;\r
-    }\r
-\r
-    while (i < rateDataNume) {\r
-        while ((j + 1 < rateDataNume) && (rateData[j + 1].x - rateData[j].x <= NUM_4)) { // 15分钟对应的秒数\r
-            tmp++;\r
-            j++;\r
-        }\r
-        if (tmp == 1) {\r
-            ElectrocardiogramOnePoint(rateData, i);\r
-        } else {\r
-            if (serialIndex >= HEART_AVE_NUM) {\r
-                return;\r
+        while (i < rateDataNume)\r
+        {\r
+            while ((j + 1 < rateDataNume) && (rateData[j + 1].x - rateData[j].x <= NUM_4))\r
+            { // 15分钟对应的秒数\r
+                tmp++;\r
+                j++;\r
             }\r
-            if (serialIndex > 0 && dataSerial[serialIndex - 1] != nullptr && i == 0) {\r
-                dataSerial[serialIndex - 1]->AddPoints(rateData + 1, tmp - 1); // number of data points\r
-                chart->Invalidate();\r
-            } else {\r
-                dataSerial[serialIndex] = new UIChartDataSerial();\r
-                if (dataSerial[serialIndex] == nullptr) {\r
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramMultiPoint] new dataSerial[%d] fail", serialIndex);\r
-                    serialIndex++;\r
+            if (tmp == 1)\r
+            {\r
+                ElectrocardiogramOnePoint(rateData, i);\r
+            }\r
+            else\r
+            {\r
+                if (serialIndex >= HEART_AVE_NUM)\r
+                {\r
                     return;\r
                 }\r
-\r
-                dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // number of data points\r
-                dataSerial[serialIndex]->AddPoints(rateData + i, tmp);   // number of data points\r
-                dataSerial[serialIndex]->SetLineColor(Color::Red());\r
-                dataSerial[serialIndex]->SetFillColor(Color::Red());\r
-                dataSerial[serialIndex]->EnableGradient(true);\r
-\r
-                chart->AddDataSerial(dataSerial[serialIndex]);\r
-                chart->Invalidate();\r
-                serialIndex++;\r
+                if (serialIndex > 0 && dataSerial[serialIndex - 1] != nullptr && i == 0)\r
+                {\r
+                    dataSerial[serialIndex - 1]->AddPoints(rateData + 1, tmp - 1); // number of data points\r
+                    chart->Invalidate();\r
+                }\r
+                else\r
+                {\r
+                    dataSerial[serialIndex] = new UIChartDataSerial();\r
+                    if (dataSerial[serialIndex] == nullptr)\r
+                    {\r
+                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramMultiPoint] new dataSerial[%d] fail", serialIndex);\r
+                        serialIndex++;\r
+                        return;\r
+                    }\r
+\r
+                    dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // number of data points\r
+                    dataSerial[serialIndex]->AddPoints(rateData + i, tmp);   // number of data points\r
+                    dataSerial[serialIndex]->SetLineColor(Color::Red());\r
+                    dataSerial[serialIndex]->SetFillColor(Color::Red());\r
+                    dataSerial[serialIndex]->EnableGradient(true);\r
+\r
+                    chart->AddDataSerial(dataSerial[serialIndex]);\r
+                    chart->Invalidate();\r
+                    serialIndex++;\r
+                }\r
             }\r
+            i += tmp;\r
+            j = i;\r
+            tmp = 1;\r
         }\r
-        i += tmp;\r
-        j = i;\r
-        tmp = 1;\r
     }\r
-}\r
 \r
-void HeartRateView::HeartRateElectrocardiogram(void)\r
-{\r
-    if (dataNume == 0) {\r
-        return;\r
-    }\r
-    serialIndex = 0;\r
-    if (dataNume != 1) {\r
-        ElectrocardiogramMultiPoint(rateDataTmp, dataNume); // 多个点\r
-    } else {\r
-        ElectrocardiogramOnePoint(rateDataTmp, 0); // 一个点\r
+    void HeartRateView::HeartRateElectrocardiogram(void)\r
+    {\r
+        if (dataNume == 0)\r
+        {\r
+            return;\r
+        }\r
+        serialIndex = 0;\r
+        if (dataNume != 1)\r
+        {\r
+            ElectrocardiogramMultiPoint(rateDataTmp, dataNume); // 多个点\r
+        }\r
+        else\r
+        {\r
+            ElectrocardiogramOnePoint(rateDataTmp, 0); // 一个点\r
+        }\r
+        currIndex = dataNume;\r
     }\r
-    currIndex = dataNume;\r
-}\r
 \r
-void HeartRateView::HeartbeatImageAnimator()\r
-{\r
-    imageAnimator = new UIImageAnimatorView();\r
-    if (imageAnimator == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartbeatImageAnimator] new imageAnimator fail");\r
-        return;\r
-    }\r
-    imageAnimator->SetPosition(HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT);\r
-    imageAnimator->SetImageAnimatorSrc(g_heartBeatImageInfo, HEARTBEAT_IMAGE_NUM, HEARTBEAT_DELAY);\r
-    imageAnimator->SetRepeat(true);\r
-    Add(imageAnimator);\r
-    imageAnimator->Start();\r
-}\r
-\r
-void HeartRateView::HeartbeatImageAnimatorStart(void)\r
-{\r
-    if (imageAnimator != nullptr) {\r
+    void HeartRateView::HeartbeatImageAnimator()\r
+    {\r
+        imageAnimator = new UIImageAnimatorView();\r
+        if (imageAnimator == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartbeatImageAnimator] new imageAnimator fail");\r
+            return;\r
+        }\r
+        imageAnimator->SetPosition(HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT);\r
+        imageAnimator->SetImageAnimatorSrc(g_heartBeatImageInfo, HEARTBEAT_IMAGE_NUM, HEARTBEAT_DELAY);\r
+        imageAnimator->SetRepeat(true);\r
+        Add(imageAnimator);\r
         imageAnimator->Start();\r
     }\r
-}\r
 \r
-void HeartRateView::HeartbeatImageAnimatorStop(void)\r
-{\r
-    if (imageAnimator != nullptr) {\r
-        imageAnimator->Stop();\r
+    void HeartRateView::HeartbeatImageAnimatorStart(void)\r
+    {\r
+        if (imageAnimator != nullptr)\r
+        {\r
+            imageAnimator->Start();\r
+        }\r
     }\r
-}\r
 \r
-bool HeartRateView::InitView(void)\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitView");\r
-    HeartRateDataProc();\r
-    HeartRateLabelDisplay();\r
-    HeartbeatImageAnimator();\r
-    HeartRateCoordinate();\r
-    InsertTopAndBottomRateImage();\r
-    HeartRateElectrocardiogram();\r
-    UpdataTopAndBottomRate();\r
-    HeartbeatImageAnimatorStop();\r
-    InitRefreshInterface();\r
-    return true;\r
-}\r
-\r
-void HeartRateView::PreLoad(void)\r
-{\r
-    if (!viewiInitStatus) {\r
-        if (InitView()) {\r
-            viewiInitStatus = true;\r
+    void HeartRateView::HeartbeatImageAnimatorStop(void)\r
+    {\r
+        if (imageAnimator != nullptr)\r
+        {\r
+            imageAnimator->Stop();\r
         }\r
     }\r
 \r
-    if (!resLoadStatus) {\r
-        // ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewTop, HEART_HEARTRATE_TOP);\r
-        // ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewBottom, HEART_HEARTRATE_BOTTOM);\r
-        // ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewCoordinate, HEART_HEARTRATECOOR);\r
-        resLoadStatus = true;\r
+    bool HeartRateView::InitView(void)\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InitView");\r
+        HeartRateDataProc();\r
+        HeartRateLabelDisplay();\r
+        HeartbeatImageAnimator();\r
+        HeartRateCoordinate();\r
+        InitChartTest();\r
+        Init_data_Chart();\r
+        InsertTopAndBottomRateImage();\r
+        HeartRateElectrocardiogram();\r
+        UpdataTopAndBottomRate();\r
+        // HeartbeatImageAnimatorStop(); 进入界面进行 动画播放\r
+        InitRefreshInterface();\r
+        return true;\r
     }\r
-}\r
 \r
-void HeartRateView::UnLoad(void)\r
-{\r
-    if (resLoadStatus) {\r
-        ImageInfo* img = nullptr;\r
-        imageViewTop->SetSrc(img);\r
-        imageViewBottom->SetSrc(img);\r
-        imageViewCoordinate->SetSrc(img);\r
-        ImageCacheManager::GetInstance().UnloadAllInMultiRes(HEART_IAMGES);\r
-        resLoadStatus = false;\r
+    /*预加载心率图片资源*/\r
+    void HeartRateView::PreLoadHeartRateImageRes(void)\r
+    {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::PreLoadHeartRateImageRes");\r
+        if (!resLoadStatus)\r
+        {\r
+            /*心率背景图*/\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewTop, HEART_RATE_TOP);\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewBottom, HEART_RATE_BOTTOM);\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewCoordinate, HEART_RATE_COOR);\r
+            resLoadStatus = true;\r
+        }\r
     }\r
-}\r
 \r
-void HeartRateView::InitRefreshInterface(void)\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitRefreshInterface");\r
-\r
-    Point *rateData = HeartModel::GetInstance()->GetAveHeartRate();\r
-    uint16_t len = HeartModel::GetInstance()->GetAveHeartRateCount();\r
-    SetHeartRateData(rateData, sizeof(Point) * len);\r
-    uint16_t maxHeartRate = HeartModel::GetInstance()->GetHeartRateMax();\r
-    uint16_t minHeartRate = HeartModel::GetInstance()->GetHeartRateMin();\r
-    RefreshElectrocardiogram();\r
-    if (maxHeartRate > 0 && maxHeartRate < HEART_RATE_LIMIT_UPPER) {\r
-        RefreshHeartRateMax(HeartModel::GetInstance()->GetHeartRateMax());\r
-    }\r
-    if (minHeartRate > 0 && minHeartRate < HEART_RATE_LIMIT_UPPER) {\r
-        RefreshHeartRateMin(HeartModel::GetInstance()->GetHeartRateMin());\r
+    /*卸载心率图片资源*/\r
+    void HeartRateView::UnLoadHeartRateImageRes(void)\r
+    {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::UnLoadHeartRateImageRes");\r
+        if (resLoadStatus)\r
+        {\r
+            ImageInfo *img = nullptr;\r
+            imageViewTop->SetSrc(img);\r
+            imageViewBottom->SetSrc(img);\r
+            imageViewCoordinate->SetSrc(img);\r
+            // ImageCacheManager::GetInstance().UnloadAllInMultiRes(HEART_IAMGES);\r
+            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_TOP, HEART_IAMGES);\r
+            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_BOTTOM, HEART_IAMGES);\r
+            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_COOR, HEART_IAMGES);\r
+            resLoadStatus = false;\r
+        }\r
     }\r
-}\r
 \r
-// 刷新心率曲线\r
-void HeartRateView::RefreshElectrocardiogram(void)\r
-{\r
-    int32_t ret = HeartRateDataProc();\r
-    if (ret != OHOS_SUCCESS) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[RefreshElectrocardiogram()] fail");\r
-        return;\r
+    void HeartRateView::PreLoad(void)\r
+    {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::PreLoad");\r
+        if (!viewiInitStatus)\r
+        {\r
+            if (InitView())\r
+            {\r
+                viewiInitStatus = true;\r
+            }\r
+        }\r
+        PreLoadHeartRateImageRes();\r
     }\r
-    Point *rate = rateDataTmp;\r
 \r
-    if (chart == nullptr) {\r
-        return;\r
+    void HeartRateView::UnLoad(void)\r
+    {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::UnLoad");\r
+        UnLoadHeartRateImageRes();\r
     }\r
 \r
-    if (currIndex >= HEART_AVE_NUM) {\r
-        currIndex = HEART_AVE_NUM;\r
+    void HeartRateView::InitRefreshInterface(void)\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitRefreshInterface");\r
+\r
+        Point *rateData = HeartModel::GetInstance()->GetAveHeartRate();\r
+        uint16_t len = HeartModel::GetInstance()->GetAveHeartRateCount();\r
+        SetHeartRateData(rateData, sizeof(Point) * len);\r
+        // 展示最大,最小,最近一次心率\r
+        uint16_t maxRate = HeartModel::GetInstance()->GetShowMaxHeartdata();\r
+        uint16_t minRate = HeartModel::GetInstance()->GetShowMinHeartdata();\r
+        uint16_t perRate = HeartModel::GetInstance()->GetShowHeartdata();\r
+\r
+        RefreshHeartRateMax(maxRate);\r
+        RefreshHeartRateMin(minRate);\r
+        HeartModel::GetInstance()->SetHeartRatePerSec(perRate);\r
     }\r
-    if (dataNume > currIndex) {\r
-        uint16_t tmp = dataNume - currIndex;\r
-        if (currIndex > 0) {\r
-            rate += (currIndex - 1);\r
-            tmp += 1;\r
+\r
+    // 刷新心率曲线\r
+    void HeartRateView::RefreshElectrocardiogram(void)\r
+    {\r
+        int32_t ret;\r
+        uint16_t tmp, count;\r
+        Point *rate = nullptr;\r
+        Point modPoint;\r
+\r
+        ret = HeartRateDataProc();\r
+        if (ret != OHOS_SUCCESS)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[RefreshElectrocardiogram()] fail");\r
+            return;\r
+        }\r
+        rate = rateDataTmp;\r
+\r
+        if (chart == nullptr)\r
+        {\r
+            return;\r
         }\r
-        ElectrocardiogramMultiPoint(rate, tmp);\r
-        currIndex = dataNume;\r
-    } else if (dataNume == currIndex) { // 当前点平均心率刷新\r
-        if (serialIndex > 0 && serialIndex <= HEART_AVE_NUM && dataSerial[serialIndex - 1] != nullptr) {\r
-            Point modPoint;\r
-            modPoint.x = rate[currIndex - 1].x;\r
-            modPoint.y = rate[currIndex - 1].y;\r
 \r
-            uint16_t count = dataSerial[serialIndex - 1]->GetDataCount();\r
-            dataSerial[serialIndex - 1]->ModifyPoint(count - 1, modPoint);\r
-            chart->Invalidate();\r
+        if (currIndex >= HEART_AVE_NUM)\r
+        {\r
+            currIndex = HEART_AVE_NUM;\r
         }\r
-    } else {\r
-        return;\r
+        if (dataNume > currIndex)\r
+        {\r
+            tmp = dataNume - currIndex;\r
+            if (currIndex > 0)\r
+            {\r
+                rate += (currIndex - 1);\r
+                tmp += 1;\r
+            }\r
+            ElectrocardiogramMultiPoint(rate, tmp);\r
+            currIndex = dataNume;\r
+        }\r
+        else if (dataNume == currIndex)\r
+        { // 当前点平均心率刷新\r
+            if (serialIndex > 0 && serialIndex <= HEART_AVE_NUM && dataSerial[serialIndex - 1] != nullptr)\r
+            {\r
+                modPoint.x = rate[currIndex - 1].x;\r
+                modPoint.y = rate[currIndex - 1].y;\r
+\r
+                count = dataSerial[serialIndex - 1]->GetDataCount();\r
+                dataSerial[serialIndex - 1]->ModifyPoint(count - 1, modPoint);\r
+                chart->Invalidate();\r
+            }\r
+        }\r
+        else\r
+        {\r
+            return;\r
+        }\r
+        UpdataTopAndBottomRate(); // 最高、最低心率\r
     }\r
-    UpdataTopAndBottomRate(); // 最高、最低心率\r
-}\r
 \r
-// 清空心率曲线\r
-void HeartRateView::ClearElectrocardiogram(void)\r
-{\r
-    int32_t i;\r
-    dataNume = 0;\r
-    currIndex = 0;\r
-    maxRate = 0;\r
-    minRate = HEART_RATE_LIMIT_UPPER;\r
-    InitHeartRateData();\r
+    // 清空心率曲线\r
+    void HeartRateView::ClearElectrocardiogram(void)\r
+    {\r
+        int32_t i;\r
+        dataNume = 0;\r
+        currIndex = 0;\r
+        maxRate = 0;\r
+        minRate = HEART_RATE_LIMIT_UPPER;\r
+        InitHeartRateData();\r
+\r
+        if (chart == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chart == nullptr");\r
+            return;\r
+        }\r
 \r
-    if (chart == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chart == nullptr");\r
-        return;\r
-    }\r
+        if (ratePerSec != nullptr && topRate != nullptr && bottomRate != nullptr && restRate != nullptr)\r
+        {\r
+            ratePerSec->SetText("--");\r
+            topRate->SetText("--");\r
+            bottomRate->SetText("--");\r
+            restRate->SetText("--");\r
+        }\r
 \r
-    if (ratePerSec != nullptr && topRate != nullptr && bottomRate != nullptr && restRate != nullptr) {\r
-        ratePerSec->SetText("--");\r
-        topRate->SetText("--");\r
-        bottomRate->SetText("--");\r
-        restRate->SetText("--");\r
-    }\r
+        chart->DeleteDataSerial(dataTopAndbottom);\r
+        delete dataTopAndbottom;\r
+        dataTopAndbottom = nullptr;\r
+        for (i = 0; i < serialIndex; i++)\r
+        {\r
+            delete dataSerial[i];\r
+            dataSerial[i] = nullptr;\r
+        }\r
+        chart->ClearDataSerial();\r
 \r
-    chart->DeleteDataSerial(dataTopAndbottom);\r
-    delete dataTopAndbottom;\r
-    dataTopAndbottom = nullptr;\r
-    for (i = 0; i < serialIndex; i++) {\r
-        delete dataSerial[i];\r
-        dataSerial[i] = nullptr;\r
+        serialIndex = 0;\r
+        chart->Invalidate();\r
     }\r
-    chart->ClearDataSerial();\r
 \r
-    serialIndex = 0;\r
-    chart->Invalidate();\r
-}\r
+    // 刷新每秒上报的心率\r
+    void HeartRateView::RefreshHeartRatePerSec(uint16_t value)\r
+    {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView %d", value);\r
 \r
-// 刷新每秒上报的心率\r
-void HeartRateView::RefreshHeartRatePerSec(uint16_t value)\r
-{\r
-    char heartRate[NUM_4] = "--";\r
-    int32_t ret = 0;\r
+        if (ratePerSec == nullptr)\r
+        {\r
+            return;\r
+        }\r
 \r
-    if (ratePerSec == nullptr) {\r
-        return;\r
+        // 判断心率值,并设置文本\r
+        if (value == 0 || value < 50)\r
+        {\r
+            ratePerSec->SetText("--");\r
+        }\r
+        else\r
+        {\r
+            std::string ratePerSecStr = std::to_string(value);\r
+            ratePerSec->SetText(ratePerSecStr.c_str());\r
+        }\r
     }\r
 \r
-    if (value == 0) {\r
-        ratePerSec->SetText("--");\r
-        HeartbeatImageAnimatorStop();\r
-        return;\r
-    }\r
-    HeartbeatImageAnimatorStart();\r
-    if (value > NUM_99) {\r
-        ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
-    } else {\r
-        ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
-    }\r
-    if (ret > EOK) {\r
-        ratePerSec->SetText(heartRate);\r
-    }\r
-}\r
+    // 刷新最大心率\r
+    void HeartRateView::RefreshHeartRateMax(uint16_t max)\r
+    {\r
+        if (topRate == nullptr)\r
+        {\r
+            return;\r
+        }\r
 \r
-// 刷新最大心率\r
-void HeartRateView::RefreshHeartRateMax(uint16_t max)\r
-{\r
-    char top[NUM_4] = "--";\r
-    int32_t ret = 0;\r
-    maxRate = (maxRate >= max) ? maxRate : max;\r
-    if (topRate == nullptr) {\r
-        return;\r
-    }\r
-    if (maxRate <= HEART_RATE_LIMIT_LOWER) {\r
-        topRate->SetText("--");\r
-        return;\r
-    }\r
-    ret = sprintf_s(top, sizeof(top), "%u", maxRate);\r
-    if (ret > EOK) {\r
-        topRate->SetText(top);\r
+        // 设置刷新文本\r
+        if (max >= HEART_RATE_LIMIT_UPPER || max < 60)\r
+        {\r
+            topRate->SetText("--");\r
+        }\r
+        else\r
+        {\r
+            std::string topRateStr = std::to_string(max);\r
+            topRate->SetText(topRateStr.c_str());\r
+        }\r
     }\r
-}\r
 \r
-// 刷新最小心率\r
-void HeartRateView::RefreshHeartRateMin(uint16_t min)\r
-{\r
-    char bottom[NUM_4] = "--";\r
-    int32_t ret = 0;\r
+    // 刷新最小心率\r
+    void HeartRateView::RefreshHeartRateMin(uint16_t min)\r
+    {\r
+        if (bottomRate == nullptr)\r
+        {\r
+            return;\r
+        }\r
 \r
-    minRate = (minRate <= min) ? minRate : min;\r
-    if (bottomRate == nullptr) {\r
-        return;\r
-    }\r
-    if (minRate >= HEART_RATE_LIMIT_UPPER) {\r
-        bottomRate->SetText("--");\r
-        return;\r
-    }\r
-    ret = sprintf_s(bottom, sizeof(bottom), "%u", minRate);\r
-    if (ret > EOK) {\r
-        bottomRate->SetText(bottom);\r
+        // 设置刷新文本\r
+        if (min >= HEART_RATE_LIMIT_UPPER || min < 60)\r
+        {\r
+            bottomRate->SetText("--");\r
+        }\r
+        else\r
+        {\r
+            std::string bottomRateStr = std::to_string(min);\r
+            bottomRate->SetText(bottomRateStr.c_str());\r
+        }\r
     }\r
-}\r
+    // 刷新静息心率\r
+    void HeartRateView::RefreshRestHeartRate(uint16_t value)\r
+    {\r
+        char heartRate[NUM_4] = "--";\r
+        int32_t ret = 0;\r
+\r
+        if (restRate == nullptr)\r
+        {\r
+            return;\r
+        }\r
 \r
-// 刷新静息心率\r
-void HeartRateView::RefreshRestHeartRate(uint16_t value)\r
-{\r
-    char heartRate[NUM_4] = "--";\r
-    int32_t ret = 0;\r
+        if (value == 0 || value == (uint16_t)0xFFFF)\r
+        {\r
+            // 无效值\r
+            restRate->SetText("--");\r
+        }\r
+        else\r
+        {\r
+            if (value > NUM_99)\r
+            {\r
+                ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
+            }\r
+            else\r
+            {\r
+                ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
+            }\r
 \r
-    if (restRate == nullptr) {\r
-        return;\r
+            if (ret > EOK)\r
+            {\r
+                restRate->SetText(heartRate);\r
+            }\r
+        }\r
     }\r
 \r
-    if (value == 0 || value == (uint16_t)0xFFFF) { // 无效值\r
-        restRate->SetText("--");\r
-    } else {\r
-        if (value > NUM_99) {\r
-            ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
-        } else {\r
-            ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
+#if 0\r
+#ifdef __cplusplus\r
+    extern "C"\r
+    {\r
+#endif\r
+        /* 定时器回调函数 */\r
+        void HeartTimerCallback()\r
+        {\r
+            g_motionTimes++;\r
+            HeartCardPresenter *gHeartCardPresenter = HeartPresenter::GetInstance();\r
+            if (gHeartCardPresenter == nullptr)\r
+            {\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartTimerCallback::gHeartCardPresenter new fail");\r
+                return;\r
+            }\r
+            // gHeartCardPresenter->ModifiesTime();\r
+            // PRINT("HeartTimerCallback\r\n");\r
         }\r
 \r
-        if (ret > EOK) {\r
-            restRate->SetText(heartRate);\r
+        /* 开启定时器 */\r
+        void InitTimer(void)\r
+        {\r
+            if (g_startCounting != NULL)\r
+            {\r
+                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer already exists!!");\r
+                return;\r
+            }\r
+            g_startCounting = osTimerNew((osTimerFunc_t)HeartTimerCallback, osTimerPeriodic, NULL, NULL);\r
+            if (g_startCounting == NULL)\r
+            {\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer osTimerNew failed!!");\r
+                return;\r
+            }\r
+            int tick = osMs2Tick(MS_ONE_SECONDS);\r
+            osStatus_t retTimer = osTimerStart(g_startCounting, tick);\r
+            if (retTimer != osOK)\r
+            {\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer osTimerStart failed, ret = %lx!!", retTimer);\r
+                if (g_startCounting != NULL)\r
+                {\r
+                    retTimer = osTimerDelete(g_startCounting);\r
+                    if (retTimer != osOK)\r
+                    {\r
+                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::osTimerDelete failed, ret = %lx!!", retTimer);\r
+                        return;\r
+                    }\r
+                    g_startCounting = NULL;\r
+                }\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitTimer!");\r
+                return;\r
+            }\r
         }\r
+        /* 关闭定时器 */\r
+        void DisableTimer(void)\r
+        {\r
+            if (g_startCounting != NULL)\r
+            {\r
+                osStatus_t ret = osTimerDelete(g_startCounting);\r
+                if (ret != osOK)\r
+                {\r
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret);\r
+                    return;\r
+                }\r
+                g_startCounting = NULL;\r
+                PRINT("g_motionTimes:%d\r\n", sportdata->duration);\r
+                g_motionTimes = 0;\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DisableTimer!");\r
+            }\r
+        }\r
+        /* 暂停定时器 */\r
+        void PauseTimer(void)\r
+        {\r
+            // 检查定时器是否存在\r
+            if (g_startCounting != NULL)\r
+            {\r
+                // 暂停定时器,但不删除它\r
+                osStatus_t ret = osTimerStop(g_startCounting);\r
+                if (ret != osOK)\r
+                {\r
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopWatch_PauseTimer osTimerStop failed, ret = %lx!!", ret);\r
+                }\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PauseTimer!");\r
+            }\r
+        }\r
+\r
+        /*恢复定时器*/\r
+        void ResumeTimer(void)\r
+        {\r
+            // 检查定时器是否存在\r
+            if (g_startCounting != NULL)\r
+            {\r
+                int tick = osMs2Tick(MS_ONE_SECONDS);\r
+                // 恢复定时器\r
+                osStatus_t ret = osTimerStart(g_startCounting, tick);\r
+                if (ret != osOK)\r
+                {\r
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer osTimerStart failed, ret = %lx!!", ret);\r
+                }\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer!");\r
+            }\r
+        }\r
+\r
+#ifdef __cplusplus\r
     }\r
-}\r
+#endif\r
+#endif\r
 } // namespace OHOS\r
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartResultPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartResultPresenter.cpp
new file mode 100644 (file)
index 0000000..f64c063
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: heart view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#include "heartrate/include/HeartResultPresenter.h"
+#include "common/task_manager.h"
+#include "HeartModel.h"
+
+#include "heartrate/include/HeartDetectionView.h"
+#include "heartrate/include/HeartResultView.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>
+
+#ifdef PPG_HX3695
+#include "ppg_service.h"
+#endif
+
+#include "power_display_service.h"
+#include "custom_utils.h"
+
+#ifdef ENABLE_CYWEE
+#include "cywee_service.h"
+#endif
+
+// #include "battery_hal.h"
+
+#include "heart_blood/health_service/health_service.h"
+#include "NativeRegisterManager.h"
+
+#define BLOODKEYABLE 1
+namespace OHOS
+{
+
+    REGIST_SLICE(VIEW_HEART_RESULT, HeartResultView, HeartResultPresenter);
+
+
+    static constexpr uint16_t PROGRESS_VALUE_MIN = 0;
+    static constexpr uint16_t PROGRESS_VALUE_MAX = 10;
+    
+
+    static HeartResultPresenter *g_pHeartResultPresenter;
+    /* -------------------------------------------------------------------------- */
+    // 获取当前的时间戳
+    uint32_t HeartResultPresenter::GetCurrentTime()
+    {
+        uint32_t time;
+        if (uapi_get_timestampe_ss(&time) != ERRCODE_SUCC)
+        {
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp");
+            return 0;
+        }
+        return time;
+    }
+
+    // 获取时间差,现在传进来的是两个时间戳
+    int HeartResultPresenter::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;
+    }
+    /* -------------------------------------------------------------------------- */
+    HeartResultPresenter::HeartResultPresenter()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartResultPresenter::new HeartResultPresenter");
+        g_pHeartResultPresenter = this;
+    }
+    HeartResultPresenter::~HeartResultPresenter()
+    {
+        g_pHeartResultPresenter = nullptr;
+    }
+    HeartResultPresenter *HeartResultPresenter::GetInstance()
+    {
+        return g_pHeartResultPresenter;
+    }
+    void HeartResultPresenter::OnStart()
+    {
+        Presenter<HeartResultView>::OnStart();
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartResultPresenter::On Start ");
+    }
+    void HeartResultPresenter::OnPause(void) {}
+
+    void HeartResultPresenter::OnResume(void) {}
+
+    void HeartResultPresenter::OnStop(void) {}
+
+    bool HeartResultPresenter::OnDrag(UIView &view, const DragEvent &event)
+    {
+        return true;
+    }
+    bool HeartResultPresenter::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 HeartResultPresenter::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 HeartResultPresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        if (strcmp(view.GetViewId(), CLICK_HEART) == 0)
+        {
+            // 如果正在充电进入提醒界面
+            // bool isCharging = get_charge_stat();
+            bool isCharging = false;
+            if (isCharging)
+            {
+                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_HEART_CHECK, TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+            }
+        }
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartPresenter::OnClick");
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartResultView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/heartrate/src/HeartResultView.cpp
new file mode 100644 (file)
index 0000000..c008893
--- /dev/null
@@ -0,0 +1,203 @@
+/***
+ * @Date: 2024-04-15 10:55:58
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-30 16:39:56
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartResultView.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 "HeartModel.h"
+
+#include "UiConfig.h"
+#include "uicomponents/UIComponents.h"
+#include "MainPresenterSample.h"
+
+#include "heartrate/include/HeartResultPresenter.h"
+#include "heartrate/include/HeartResultView.h"
+namespace OHOS
+{
+    static HeartResultView *g_pHeartResultView{nullptr};
+    static const char *HEARTBACKPATH = "/user/res/Blood/beijing.bin";
+
+    HeartResultView::HeartResultView()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartResultView::HeartResultView");
+        g_pHeartResultView = this;
+    }
+
+    HeartResultView::~HeartResultView()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartResultView::~HeartResultView");
+        DeInit();
+        g_pHeartResultView = nullptr;
+    }
+
+    HeartResultView *HeartResultView::GetInstance()
+    {
+        return g_pHeartResultView;
+    }
+
+    /* -------------------------------------------------------------------------- */
+    void HeartResultView::UpHeartText()
+    {
+        // 更新心率数据
+        uint16_t heart = HeartModel::GetInstance()->GetHeartdata();
+        if (heart != 0) // 判断是否为默认数据
+        {
+            // 更新数据
+            std::string heartrateStr = std::to_string(heart);
+            heartLabel->SetText(heartrateStr.c_str());
+
+            // 获取时间差
+            uint32_t time = HeartResultPresenter::GetInstance()->GetCurrentTime();
+            uint32_t check_time = HeartModel::GetInstance()->GetCheckTime();
+            int time_diff = HeartResultPresenter::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
+        {
+            heartLabel->SetText("--");
+            timeLabel->SetTextId(STR_CHECKNO);
+        }
+    }
+
+    /* -------------------------------------------------------------------------- */
+    /***
+     * @description:
+     * @return 添加按键是否成功
+     */
+    bool HeartResultView::AddButton()
+    {
+        InitButtonExt(checkButton, 118, 336, 230, 80, CLICK_HEART, STR_CHECK, 30);
+        checkButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xffFF5A36); // 设置按键颜色
+        // 设置按键监听
+        UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::HeartResultPresenter::GetInstance();
+        checkButton->SetOnClickListener(clickListener);
+
+        AddViewToRootContainer(checkButton);
+        return true;
+    }
+    /***
+     * @description:
+     * @return 初始化标签是否成功
+     */
+    bool HeartResultView::InitLable()
+    {
+        /*初始化title*/
+        InitLabelExt(titleLabel, 83, 50, 300, 35, "title", STR_HEARTDATA, DEFAULT_VECTOR_FONT_FILENAME, 30);
+        /*初始化心率值label*/
+        InitUILabel(heartLabel, 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);
+
+        UpHeartText();
+
+        AddViewToRootContainer(titleLabel);
+        AddViewToRootContainer(heartLabel);
+        AddViewToRootContainer(timeLabel);
+
+        return true;
+    }
+    /***
+     * @description:
+     * @return 初始化背景是否成功
+     */
+    bool HeartResultView::Initbackground()
+    {
+
+        background = new UIImageView();
+        background->SetPosition(0, 0, 466, 466);
+        background->SetSrc(HEARTBACKPATH);
+
+        AddViewToRootContainer(background);
+        return true;
+    }
+    /***
+     * @description:
+     * @return 是否初始化成功
+     */
+    bool HeartResultView::HeartResultViewInit()
+    {
+
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "bool HeartResultView::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 HeartResultView::DeInit()
+    {
+        if (background != nullptr)
+        {
+            delete background;
+            background = nullptr;
+        }
+        if (heartLabel != nullptr)
+        {
+            delete heartLabel;
+            heartLabel = nullptr;
+        }
+        if (timeLabel != nullptr)
+        {
+            delete timeLabel;
+            timeLabel = nullptr;
+        }
+        if (titleLabel != nullptr)
+        {
+            delete titleLabel;
+            titleLabel = nullptr;
+        }
+    }
+
+    void HeartResultView::OnStart()
+    {
+       
+
+        if (!HeartResultViewInit())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartResultView::InitHeartView fail");
+        }
+
+  
+        GetRootContainer()->SetDraggable(true);
+        GetRootContainer()->SetTouchable(true);
+        GetRootContainer()->SetOnDragListener(presenter_);     
+        // GetRootContainer()->SetOnKeyActListener(presenter_);
+    }
+    
+}