--- /dev/null
+/***
+ * @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
--- /dev/null
+/***
+ * @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
--- /dev/null
+/***
+ * @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
--- /dev/null
+
+
+#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
#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
#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
#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
--- /dev/null
+/***
+ * @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
--- /dev/null
+#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
#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
#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
#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
--- /dev/null
+/***
+ * @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
--- /dev/null
+
+#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
--- /dev/null
+/***
+ * @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;
+ }
+}
--- /dev/null
+/***
+ * @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
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/***
+ * @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();
+ }
+ }
+
+}
-#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(¤tTime) != 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
--- /dev/null
+
+#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
--- /dev/null
+#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
#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
#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
#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
#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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/***
+ * @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_);
+ }
+
+}