运动:优化运动时长计算与显示 1435/2 1435/head
authorCaisking <3449750381@qq.com>
Thu, 21 Nov 2024 09:11:07 +0000 (17:11 +0800)
committerCaisking <3449750381@qq.com>
Thu, 21 Nov 2024 09:11:07 +0000 (17:11 +0800)
code/sdk/application/wearable/fd230app/nativeui/traing/include/TraingModel.h
code/sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp
code/sdk/application/wearable/fd230app/nativeui/traing/training_card/src/TraingCardPresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/traing/training_card/src/TraingCardView.cpp

index 283dc8e..6321185 100644 (file)
@@ -19,6 +19,7 @@
 #include <iostream>
 #include <memory>
 #include <queue>
+#include <stdint.h>
 #include <string>
 #include <unordered_map>
 #include <vector>
@@ -302,6 +303,7 @@ public:
                         const char *errorMsg); /*获取日期*/
   bool GetFormattedTime(std::string &timeOutput,
                         const char *errorMsg); /*获取时间*/
+  uint32_t get_current_time();
 
   // 训练项相关配置
   void IsSpecialSport(UIResourceTextId sportId_); /*判断是否为特殊训练*/
index 9aba0af..389d593 100644 (file)
 #include <vector>
 
 #include "bleService.h"
+#include "chip_system_time.h"
 
 extern "C" errcode_t uapi_get_timestampe_ms(uint32_t *tm);
+extern "C" errcode_t uapi_get_timestampe_ss(uint32_t *tm);
 
 #ifdef __cplusplus
 extern "C" {
@@ -579,6 +581,15 @@ void TraingModel::ResetSharedTrainingData() {
   shock_count = 0; //重置震动计数
 }
 
+uint32_t TraingModel::get_current_time() {
+  uint32_t time;
+  if (uapi_get_timestampe_ss(&time) != ERRCODE_SUCC) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp");
+    return 0;
+  }
+  return time;
+}
+
 /*设置运动开始与结束*/
 void TraingModel::SetTimestamp() {
   uint32_t time;
@@ -1600,7 +1611,7 @@ void TraingModel::set_sport_config(UIResourceTextId id) {
 }
 
 /* -------------------------------------------------------------------------- */
-#if TIMER
+
 #include <chrono>
 #include <iomanip>
 #include <sstream>
@@ -1681,122 +1692,135 @@ void TraingModel::StoreDataIfMinutePassed() {
 #ifdef __cplusplus
 extern "C" {
 #endif
+#include <stdbool.h> // 确保包含该头文件以使用布尔类型
+
+// 全局变量
+static bool isPaused = false;            // 定时器暂停状态
+static uint32_t pauseStartTimestamp = 0; // 当前暂停开始的时间戳
+static uint32_t totalPausedDuration = 0; // 总暂停时长
+// static uint32_t g_motionTimes = 0; // 总运动时间
+// static TimerHandle_t g_startCounting = NULL; // 定时器句柄
+
+/* 日志错误信息 */
+void LogError(const char *msg, osStatus_t ret) {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s ret = %lx!!", msg, ret);
+}
+
 /* 定时器回调函数 */
-void TraingTimerCallback() {
-  g_motionTimes++;
-  if (g_motionTimes != 0) {
-    sportdata->duration = g_motionTimes;
-  }
-  // 检查并发送实时数据
-  OHOS::TraingModel::GetInstance()->SendLiveDataIfNecessary();
-  // 更新时间目标完成度
-  OHOS::TraingModel::GetInstance()->CheckTimeTag();
-  // 特殊运动才存储心率配速表
-  if (OHOS::TraingModel::GetInstance()->GetIsSpecial())
-    OHOS::TraingModel::GetInstance()
-        ->StoreDataIfMinutePassed(); //存储心率配速表
-
-  if ((sportdata->goaldegree >= 100) && (shock_count < 4)) {
-    shock_count++;
-    ui_api_vibrate_once_func(); //震动一次 共计3次
-  }
-#if 0
-    TraingCardPresenter *gTraingCardPresenter = TraingCardPresenter::GetInstance();
-    if (gTraingCardPresenter == nullptr)
-    {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingTimerCallback::gTraingCardPresenter new fail");
-        return;
+void TraingTimerCallback(void) {
+  // 只在活动状态下进行更新
+  if (!isPaused) {
+
+    if (pauseStartTimestamp == 0) {
+      //开始时将该值设置为运动开始值
+      pauseStartTimestamp = sportdata->starttime;
     }
-    gTraingCardPresenter->ModifiesTime();
-#endif
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingTimerCallback\r\n");
+
+    uint32_t currentTimestamp =
+        OHOS::TraingModel::GetInstance()->get_current_time(); // 获取当前时间戳
+    g_motionTimes = (currentTimestamp - pauseStartTimestamp) +
+                    totalPausedDuration; // 更新运动时间
+    sportdata->duration = g_motionTimes; // 更新持续时间
+
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                  "更新运动时间。当前运动时间: %d %d %d %d", currentTimestamp,
+                  pauseStartTimestamp, totalPausedDuration, g_motionTimes);
+
+    // 检查并发送实时数据
+    OHOS::TraingModel::GetInstance()->SendLiveDataIfNecessary();
+    OHOS::TraingModel::GetInstance()->CheckTimeTag();
+
+    // 记录特殊活动的心率/配速数据
+    if (OHOS::TraingModel::GetInstance()->GetIsSpecial()) {
+      OHOS::TraingModel::GetInstance()->StoreDataIfMinutePassed();
+    }
+
+    // 振动反馈
+    if ((sportdata->goaldegree >= 100) && (shock_count < 4)) {
+      shock_count++;
+      ui_api_vibrate_once_func(); // 触发振动反馈
+      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "触发了振动。振动计数: %d",
+                    shock_count);
+    }
+  }
+
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingTimerCallback 被执行。");
 }
 
-/* å¼\80å\90¯定时器 */
-void InitTimer(void) {
+/* å\90¯å\8a¨定时器 */
+void StartTimer(void) {
   if (g_startCounting != NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "TraingModel::TraingTimer already exists!!");
+    LogError("定时器已经存在", osError);
     return;
   }
+
   g_startCounting = osTimerNew((osTimerFunc_t)TraingTimerCallback,
                                osTimerPeriodic, NULL, NULL);
   if (g_startCounting == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "TraingModel::TraingTimer osTimerNew failed!!");
+    LogError("定时器创建失败", osError);
     return;
   }
+
   int tick = osMs2Tick(MS_ONE_SECONDS);
   osStatus_t retTimer = osTimerStart(g_startCounting, tick);
   if (retTimer != osOK) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "TraingModel::TraingTimer osTimerStart failed, ret = %lx!!",
-                  retTimer);
-    if (g_startCounting != NULL) {
-      retTimer = osTimerDelete(g_startCounting);
-      if (retTimer != osOK) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                      "TraingModel::osTimerDelete failed, ret = %lx!!",
-                      retTimer);
-        return;
-      }
-      g_startCounting = NULL;
-    }
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitTimer!");
-    return;
+    LogError("定时器启动失败", retTimer);
+    osTimerDelete(g_startCounting);
+    g_startCounting = NULL;
   }
 }
-/* 关闭定时器 */
-void DisableTimer(void) {
+
+/* 停止并重置定时器 */
+void StopAndResetTimer(void) {
   if (g_startCounting != NULL) {
     osTimerStop(g_startCounting);
     osStatus_t ret = osTimerDelete(g_startCounting);
     if (ret != osOK) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret);
-      return;
+      LogError("定时器删除失败", ret);
     }
     g_startCounting = NULL;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "g_motionTimes:%d\r\n",
-                  sportdata->duration);
     g_motionTimes = 0;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DisableTimer!");
+    pauseStartTimestamp = 0;
+    totalPausedDuration = 0; // 重置总暂停时长
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已停止并重置。");
   }
 }
+
 /* 暂停定时器 */
 void PauseTimer(void) {
-  // 检查定时器是否存在
-  if (g_startCounting != NULL) {
-    // 暂停定时器,但不删除它
-    osStatus_t ret = osTimerStop(g_startCounting);
-    if (ret != osOK) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "StopWatch_PauseTimer osTimerStop failed, ret = %lx!!",
-                    ret);
-    }
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PauseTimer!");
+  if (g_startCounting != NULL && !isPaused) {
+    osTimerStop(g_startCounting);
+
+    totalPausedDuration = sportdata->duration; //记录暂停前的时间;后续加上
+
+    isPaused = true; // 设置为暂停状态
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已暂停。暂停开始时间戳: %u",
+                  pauseStartTimestamp);
   }
 }
 
-/*恢复定时器*/
+/* 恢复定时器 */
 void ResumeTimer(void) {
-  // 检查定时器是否存在
-  if (g_startCounting != NULL) {
+  if (g_startCounting != NULL && isPaused) {
+
+    uint32_t currentTimestamp =
+        OHOS::TraingModel::GetInstance()->get_current_time(); // 获取当前时间戳
+    pauseStartTimestamp = currentTimestamp; // 保存暂停开始的时间戳 将这个更新
+
     int tick = osMs2Tick(MS_ONE_SECONDS);
-    // 恢复定时器
-    osStatus_t ret = osTimerStart(g_startCounting, tick);
-    if (ret != osOK) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "ResumeTimer osTimerStart failed, ret = %lx!!", ret);
+    if (osTimerStart(g_startCounting, tick) != osOK) {
+      LogError("恢复定时器时启动失败", osError);
     }
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer!");
+    isPaused = false; // 设置为活动状态
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已恢复。当前运动时间: %u %d",
+                  g_motionTimes, pauseStartTimestamp);
   }
 }
 
 #ifdef __cplusplus
 }
 #endif
-#endif
 /* ---------------------------------- 数据存储
  * ---------------------------------- */
 static int32 SaveTraingDataToFile(void) {
index de4edf2..4416121 100644 (file)
@@ -42,8 +42,8 @@ extern "C" void do_cywee_service_check_msg(int cmd, int data[]);
 #define DATATEST 0\r
 \r
 extern "C" {\r
-void InitTimer();\r
-void DisableTimer();\r
+void StartTimer();\r
+void StopAndResetTimer();\r
 void PauseTimer();\r
 void ResumeTimer();\r
 }\r
@@ -188,7 +188,7 @@ bool TraingCardPresenter::ControlSensor(ExerciseState state) {
     // 退出进入普通模式\r
     do_cywee_service_check_msg(CYWEE_SERVICE_CMD_NORMAL_MODE, NULL);\r
     opensensorstuats = false; // 恢复标志位\r
-    DisableTimer();           // 关闭计时器\r
+    StopAndResetTimer();           // 关闭计时器\r
     break;\r
   case ExerciseState::Pause:\r
     do_cywee_service_check_msg(CYWEE_SERVICE_CMD_PAUSE, 0);\r
index 223a549..dbec98e 100644 (file)
@@ -22,8 +22,8 @@
 \r
 \r
 extern "C" {\r
-void InitTimer();\r
-void DisableTimer();\r
+void StartTimer();\r
+void StopAndResetTimer();\r
 void PauseTimer();\r
 }\r
 \r
@@ -555,7 +555,7 @@ static TraingCardView *g_pTraingCardView{nullptr};
 TraingCardView::TraingCardView() {\r
   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingCardView::TraingCardView");\r
   if (TraingModel::GetInstance()->GetSportState() == ExerciseState::General) {\r
-    InitTimer(); // 开启计时器\r
+    StartTimer(); // 开启计时器\r
     TraingModel::GetInstance()->SetSportState(\r
         ExerciseState::Start); // 设置运动状态为开始\r
     TraingModel::GetInstance()->SetTimestamp();\r
@@ -571,7 +571,7 @@ TraingCardView::~TraingCardView() {
 \r
   g_pTraingCardView = nullptr;\r
   if (TraingModel::GetInstance()->GetSportState() == ExerciseState::End) {\r
-    DisableTimer(); // 关闭计时器\r
+    StopAndResetTimer(); // 关闭计时器\r
     TraingModel::GetInstance()->SetTimestamp();\r
   } else {\r
     TraingModel::GetInstance()->SetSportState(ExerciseState::Pause);\r