From 14a3b9fa24ed51ddc90657a701ce048183e02582 Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Wed, 10 Jun 2026 17:11:05 +0800 Subject: [PATCH] =?utf8?q?=E4=BC=98=E5=8C=96=E5=AE=9A=E6=97=B6=E5=99=A8?= =?utf8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../bloodpressure/include/BPMainPresenter.h | 6 ++- .../bloodpressure/src/BPMainPresenter.cpp | 41 +++++++++++++++---- .../ecg/include/ECGMeasureResultView.h | 5 ++- .../nativeui/ecg/src/ECGInstructionView.cpp | 4 +- .../nativeui/ecg/src/ECGMeasureResultView.cpp | 39 ++++++++++++++---- 5 files changed, 73 insertions(+), 22 deletions(-) diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h index 9ca6101fe..0fdcb98d3 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/include/BPMainPresenter.h @@ -60,11 +60,13 @@ private: void StopPpgSession(); void SetScreenAlwaysOnForBp(bool enable); bool PollPpgResult(); + void TryCompleteCalibrationAtEnd(); static bool IsValidBpReading(int sbp, int dbp); static void ProgressTimerThunk(void *arg); - /** 约 30s 完成(算法需 ~30s ECG 采集) */ + /** 约 30s 完成(300ms × 100 步) */ static constexpr uint32_t kProgressTickMs = 300U; + static constexpr uint32_t kPollIntervalMs = 1000U; static constexpr int kProgressMaxPercent = 100; GraphicTimer *progressTimer_{nullptr}; @@ -72,6 +74,8 @@ private: int progressPercent_{0}; bool progressDataReceived_{false}; bool progressPaused_{false}; + bool calibAlgorithmDone_{false}; + uint32_t pollElapsedMs_{0}; int16_t stopReturnView_{MAX_BPVIEW}; bool stopIsMeasure_{false}; BPProgressMode lastTimeoutMode_{BPProgressMode::None}; diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp index a6e81c149..1cbe4c294 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/bloodpressure/src/BPMainPresenter.cpp @@ -131,6 +131,8 @@ void BPMainPresenter::StartProgressSession(BPProgressMode mode) { progressPercent_ = 0; progressDataReceived_ = false; progressPaused_ = false; + calibAlgorithmDone_ = false; + pollElapsedMs_ = 0; UpdateProgressUi(0); StartPpgSession(mode); uapi_set_screen_on_api(); @@ -161,6 +163,8 @@ void BPMainPresenter::StopProgressSession() { progressPercent_ = 0; progressDataReceived_ = false; progressPaused_ = false; + calibAlgorithmDone_ = false; + pollElapsedMs_ = 0; } /** 判断血压读数是否有效 */ @@ -211,7 +215,7 @@ void BPMainPresenter::SetScreenAlwaysOnForBp(bool enable) { } } -/** 轮询PPG结果 */ +/** 轮询 PPG 结果:测量模式成功则立即完成;校准模式仅标记算法完成,等待进度结束 */ bool BPMainPresenter::PollPpgResult() { #ifdef SUPPORT_PPG_SERVICE int sbp = 0; @@ -231,16 +235,15 @@ bool BPMainPresenter::PollPpgResult() { } if (progressMode_ == BPProgressMode::Calibrate) { - /* 校准模式:算法产出 NoCal 值即表示本轮回合采集完成 */ if (sbp <= 0 || dbp <= 0) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] cali poll no result sbp=%d dbp=%d", sbp, dbp); return false; } - BPModel *model = BPModel::GetInstance(); + calibAlgorithmDone_ = true; WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "[BP] cali algorithm done, use input sbp=%d dbp=%d (algo nocall %d/%d)", - model->GetInputSbp(), model->GetInputDbp(), sbp, dbp); - NotifyCalibrationComplete(model->GetInputSbp(), model->GetInputDbp()); + "[BP] cali algorithm done (nocall %d/%d), wait progress end input sbp=%u dbp=%u", + sbp, dbp, BPModel::GetInstance()->GetInputSbp(), + BPModel::GetInstance()->GetInputDbp()); return true; } #else @@ -249,6 +252,14 @@ bool BPMainPresenter::PollPpgResult() { return false; } +void BPMainPresenter::TryCompleteCalibrationAtEnd() { + if (progressMode_ != BPProgressMode::Calibrate || !calibAlgorithmDone_ || progressDataReceived_) { + return; + } + BPModel *model = BPModel::GetInstance(); + NotifyCalibrationComplete(model->GetInputSbp(), model->GetInputDbp()); +} + void BPMainPresenter::UpdateProgressUi(int percent) { if (progressMode_ == BPProgressMode::Calibrate) { BPCalibratingView *view = BPCalibratingView::GetInstance(); @@ -264,6 +275,15 @@ void BPMainPresenter::OnProgressTick() { return; } + pollElapsedMs_ += kProgressTickMs; + if (pollElapsedMs_ >= kPollIntervalMs) { + pollElapsedMs_ -= kPollIntervalMs; + PollPpgResult(); + if (progressDataReceived_) { + return; + } + } + progressPercent_ += 1; if (progressPercent_ > kProgressMaxPercent) { progressPercent_ = kProgressMaxPercent; @@ -271,8 +291,13 @@ void BPMainPresenter::OnProgressTick() { UpdateProgressUi(progressPercent_); if (progressPercent_ >= kProgressMaxPercent && !progressDataReceived_) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] progress 100%%, poll ppg result"); - if (PollPpgResult()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] progress 100%%, final poll"); + PollPpgResult(); + if (progressDataReceived_) { + return; + } + TryCompleteCalibrationAtEnd(); + if (progressDataReceived_) { return; } WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BP] poll failed, goto timeout"); diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMeasureResultView.h b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMeasureResultView.h index 47639bad9..b87cc5eb1 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMeasureResultView.h +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/include/ECGMeasureResultView.h @@ -6,8 +6,8 @@ #include "components/ui_label_button.h" #include "components/ui_view_group.h" -#define ECG_PATH_HEART_ICON "/user/res/heart_chart/hearticon.bin" -#define ECG_PATH_RESULT_BACKGROUND "/user/res/ecg/result_background.bin" +#define ECG_PATH_HEART_RED_ICON "/user/res/ecg/heart_red.bin" +#define ECG_PATH_RESULT_BACKGROUND "/user/res/ecg/background.bin" namespace OHOS { class ECGMeasureResultView { @@ -25,6 +25,7 @@ private: UILabel *bpmValueLabel_{nullptr}; UILabel *bpmUnitLabel_{nullptr}; UILabel *resultLabel_{nullptr}; + UILabel *noteLabel_{nullptr}; UILabelButton *confirmButton_{nullptr}; }; diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGInstructionView.cpp b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGInstructionView.cpp index 25414d3be..35f1354d2 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGInstructionView.cpp +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGInstructionView.cpp @@ -65,7 +65,7 @@ void ECGInstructionView::InitWaitContact() { InitUILabel(titleLabel_, 0, 50, 466, 35, "ecg_wait_contact_title", "ECG测量", DEFAULT_VECTOR_FONT_FILENAME, 30); titleLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - InitImageView(imageView_, 141, 36, 184, 184, "ecg_wait_contact", ECG_PATH_WAIT_CONTACT); + InitImageView(imageView_, 55, 95, 360, 300, "ecg_wait_contact", ECG_PATH_WAIT_CONTACT); InitUILabel(contentLabel_, 0, 401, 466, 30, "ecg_wait_contact_content", "将手指放在电极上", DEFAULT_VECTOR_FONT_FILENAME, 30); contentLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); @@ -82,7 +82,7 @@ void ECGInstructionView::InitContactGood() { InitUILabel(titleLabel_, 0, 50, 466, 35, "ecg_contact_good_title", "ECG测量", DEFAULT_VECTOR_FONT_FILENAME, 30); titleLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - InitImageView(imageView_, 141, 36, 184, 184, "ecg_contact_good", ECG_PATH_CONTACT_GOOD); + InitImageView(imageView_, 55, 95, 360, 300, "ecg_contact_good", ECG_PATH_CONTACT_GOOD); InitUILabel(contentLabel_, 0, 401, 466, 30, "ecg_contact_good_content", "保持手指不动", DEFAULT_VECTOR_FONT_FILENAME, 30); contentLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); diff --git a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMeasureResultView.cpp b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMeasureResultView.cpp index 259a1b18a..db6c9fdf1 100644 --- a/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMeasureResultView.cpp +++ b/code/sdk/application/wearable/n9/nativeapp/nativeui/ecg/src/ECGMeasureResultView.cpp @@ -6,6 +6,19 @@ #include "uicomponents/UIComponents.h" namespace OHOS { +namespace { +static constexpr int16_t ECG_RESULT_ROW_Y = 168; +static constexpr int16_t ECG_HEART_X = 129; +static constexpr int16_t ECG_HEART_Y = ECG_RESULT_ROW_Y + 8; +static constexpr int16_t ECG_HEART_W = 54; +static constexpr int16_t ECG_HEART_H = 54; +static constexpr int16_t ECG_BPM_X = ECG_HEART_X + ECG_HEART_W + 12; +static constexpr int16_t ECG_BPM_Y = ECG_RESULT_ROW_Y; +static constexpr int16_t ECG_BPM_W = 66; +static constexpr int16_t ECG_BPM_H = 66; +static constexpr int16_t ECG_BPM_UNIT_X = ECG_BPM_X + ECG_BPM_W + 8; +static constexpr int16_t ECG_BPM_UNIT_Y = ECG_RESULT_ROW_Y + 35; +} // namespace static ECGMeasureResultView *g_instance = nullptr; @@ -18,12 +31,14 @@ ECGMeasureResultView::~ECGMeasureResultView() { delete bpmValueLabel_; delete bpmUnitLabel_; delete resultLabel_; + delete noteLabel_; delete confirmButton_; delete backgroundIcon_; delete group_; heartIcon_ = nullptr; backgroundIcon_ = nullptr; bpmValueLabel_ = nullptr; + noteLabel_ = nullptr; bpmUnitLabel_ = nullptr; resultLabel_ = nullptr; backgroundIcon_ = nullptr; @@ -60,23 +75,29 @@ UIViewGroup *ECGMeasureResultView::InitView() { InitImageView(backgroundIcon_, 0, 43, 466, 380, "ecg_result_background", ECG_PATH_RESULT_BACKGROUND); - InitImageView(heartIcon_, 206, 100, 54, 50, "ecg_result_heart", ECG_PATH_HEART_ICON); + InitImageView(heartIcon_, ECG_HEART_X, ECG_HEART_Y, ECG_HEART_W, ECG_HEART_H, "ecg_result_heart", + ECG_PATH_HEART_RED_ICON); - - InitUILabel(bpmValueLabel_, 0, 170, 466, 90, "ecg_result_bpm", "--", - DEFAULT_VECTOR_FONT_FILENAME, 72); + InitUILabel(bpmValueLabel_, ECG_BPM_X, ECG_BPM_Y, ECG_BPM_W, ECG_BPM_H, "ecg_result_bpm", "--", + DEFAULT_VECTOR_FONT_FILENAME, 65); bpmValueLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - InitUILabel(bpmUnitLabel_, 0, 250, 466, 30, "ecg_result_bpm_unit", "bpm", - DEFAULT_VECTOR_FONT_FILENAME, 26); + InitUILabel(bpmUnitLabel_, ECG_BPM_UNIT_X, ECG_BPM_UNIT_Y, 72, 30, "ecg_result_bpm_unit", "次/分", + DEFAULT_VECTOR_FONT_FILENAME, 30); + bpmUnitLabel_->SetTextColor(Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff)); bpmUnitLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - InitUILabel(resultLabel_, 0, 290, 466, 40, "ecg_result_type", "窦性心律", - DEFAULT_VECTOR_FONT_FILENAME, 32); + InitUILabel(resultLabel_, 0, 50, 466, 35, "ecg_result_type", "窦性心律", + DEFAULT_VECTOR_FONT_FILENAME, 30); resultLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - InitLabelButton(confirmButton_, 93, 330, 280, 90, ECG_CLICK_CONFIRM, "完成", 30); + InitUILabel(noteLabel_, 0, 412, 466, 35, "ecg_result_note", "测量结果仅供参考", + DEFAULT_VECTOR_FONT_FILENAME, 30); + noteLabel_->SetTextColor(Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff)); + noteLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + + InitLabelButton(confirmButton_, 93, 304, 280, 90, ECG_CLICK_CONFIRM, "重新测量", 30); confirmButton_->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919); confirmButton_->SetStyle(STYLE_BORDER_RADIUS, 45); confirmButton_->SetOnClickListener(static_cast(ECGMainPresenter::GetInstance())); -- 2.17.1