修复APP发起运动无法同步数据的问题
authorCaisking <Casiking@zhihuishixun.com>
Wed, 15 Oct 2025 04:06:45 +0000 (12:06 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Wed, 15 Oct 2025 04:06:45 +0000 (12:06 +0800)
code/sdk/application/wearable/fd230/nativeapp/nativeui/traing/src/TraingModel.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/traing/training_card/src/TraingCardPresenter.cpp
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/src/TraingModel.cpp
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/training_card/src/TraingCardPresenter.cpp
code/sdk/application/wearable/n9/nativeapp/nativeui/traing/src/TraingModel.cpp
code/sdk/zhihui/drivers/cywee/dml/cywee_dml.c

index 4e8f79c..6b98910 100644 (file)
      offset = 0;
      break;
    }
-   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " offset %d id %d", offset, id);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "编译id offset %d id %d", offset, id);
    return id - offset;
  }
  
      Startstate = true;
      Endstate = false; // 确保"开始"和"结束"状态互斥
  
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始运动");
+      //打印目前运动配置项
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "*******************************");
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始运动");
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportType:%d", sportdata->sportType);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportId:%d", sportdata->sportId);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportTagType:%d", sportdata->sportTagType);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportTag:%d", sportdata->tag);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "*******************************");
+  
  
      sport_start_data_timer(300); //开启数据获取定时器 刷新频率是300ms
  
  }
  
  /*
-     uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练
-     uint32_t bt;  // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4
-    - 水上项目,5 - 冰上项目,6 - 极限运动,7 - 其他 uint32_t ty;  //
-    训练类型:自由训练 uint32_t st;  // 开始时间戳(单位:秒) uint32_t sp;  //
-    结束时间戳(单位:秒) uint32_t tgt; // 训练目标类型:0 - 距离,1 - 卡路里,2
-    - 时间,3 - 步数 uint32_t tg;  //
-    训练目标值:路程(单位:米),卡路里(单位:kcal),时间(单位:分钟),步数(单位:步)
-     uint32_t pg;  // 目标完成度(单位:%)
-     uint32_t du;  // 训练总时长(单位:秒)
-     uint32_t ca;  // 消耗卡路里(单位:kcal)
-     uint32_t di;  // 完成的距离(单位:米)
-     uint32_t hr;  // 平均心率
-     uint32_t stp; // 步数
-     uint32_t ti;  // 训练强度:0 - 较低强度,1 - 中等强度,2 - 高等强度,3 -
-    超高强度 uint32_t cir; // 圈数 uint32_t alt; // 最高海拔高度
+   uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练
+   uint32_t bt;  // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4 - 水上项目,5 - 冰上项目,6 - 极限运动,7 - 其他 
+   uint32_t  ty;  //训练类型:自由训练 
+   uint32_t st;  // 开始时间戳(单位:秒)
+   uint32_t sp;  // 结束时间戳(单位:秒) 
+   uint32_t tgt; // 训练目标类型:0 - 距离,1 - 卡路里,2- 时间,3 - 步数 
+   uint32_t tg;  //训练目标值:路程(单位:米),卡路里(单位:kcal),时间(单位:分钟),步数(单位:步)
+   uint32_t pg;  // 目标完成度(单位:%)
+   uint32_t du;  // 训练总时长(单位:秒)
+   uint32_t ca;  // 消耗卡路里(单位:kcal)
+   uint32_t di;  // 完成的距离(单位:米)
+   uint32_t hr;  // 平均心率
+   uint32_t stp; // 步数
+   uint32_t ti;  // 训练强度:0 - 较低强度,1 - 中等强度,2 - 高等强度,3 - 超高强度 
+   uint32_t cir; // 圈数 
+   uint32_t alt; // 最高海拔高度
  */
  /*保存数据*/
  bool TraingModel::SaveSportData() {
    Trainingdata data;
    data.src = Openingway;
    data.bt = static_cast<uint32_t>(sportdata->sportType);
-   data.ty = static_cast<uint32_t>(
-       GetBleSportId(sportdata->sportType, sportdata->sportId));
+   data.ty = static_cast<uint32_t>(GetBleSportId(sportdata->sportType, sportdata->sportId));
    data.st = static_cast<uint32_t>(sportdata->starttime);
    data.sp = static_cast<uint32_t>(sportdata->endtime);
    data.tgt = static_cast<uint32_t>(sportdata->sportTagType);
      // 保存GPS数据
      if (!SaveCanvasData()) {
        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveCanvasData is error!");
-       return false; //必须手表端存储成功
+       // return false; 
      }
      if (!SaveGPSData()) {
        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData is error!");
        cJSON_AddNumberToObject(itemJSON, "spc", data->spc);
        cJSON_AddNumberToObject(itemJSON, "std", data->std);
        cJSON_AddNumberToObject(itemJSON, "cdc", data->cdc);
- 
        cJSON_AddItemReferenceToArray(data_arryJSON, itemJSON);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"src:%d",data->src);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"bt:%d",data->bt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ty:%d",data->ty);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"st:%d",data->st);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sp:%d",data->sp);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tgt:%d",data->tgt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tg:%d",data->tg);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"pg:%d",data->pg);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"du:%d",data->du);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ca:%d",data->ca);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"di:%d",data->di);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hr:%d",data->hr);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"stp:%d",data->stp);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ti:%d",data->ti);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cir:%d",data->cir);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"alt:%d",data->alt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"apc:%d",data->apc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"fpc:%d",data->fpc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"spc:%d",data->spc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"std:%d",data->std);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cdc:%d",data->cdc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
        free(data);
        data = NULL;
      } else {
          if(data!=NULL)
          {
              WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"%d,%d\r\n",timetamp,data->st);
+             // 打印data数据
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"src:%d",data->src);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"bt:%d",data->bt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ty:%d",data->ty);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"st:%d",data->st);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sp:%d",data->sp);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tgt:%d",data->tgt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tg:%d",data->tg);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"pg:%d",data->pg);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"du:%d",data->du);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ca:%d",data->ca);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"di:%d",data->di);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hr:%d",data->hr);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"stp:%d",data->stp);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ti:%d",data->ti);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cir:%d",data->cir);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"alt:%d",data->alt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"apc:%d",data->apc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"fpc:%d",data->fpc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"spc:%d",data->spc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"std:%d",data->std);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cdc:%d",data->cdc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
              int time_error= timetamp>data->st ? timetamp-data->st:data->st-timetamp;
              if(time_error<=2)
              {
index 728ca37..73d7219 100644 (file)
  * /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/traing/training_card/src/TraingCardPresenter.cpp\r
  */\r
 \r
-#include "AppViewIDs.h"\r
-#include "NativeAbility.h"\r
-#include "components/ui_label_ext.h"\r
-#include "ui_resource_string.h"\r
-\r
-#include "ConfigModel.h"\r
-#include "custom_utils.h"\r
-#include "graphic_service.h"\r
-#include "traing/include/TraingModel.h"\r
-#include "traing/training_card/include/TraingCardPresenter.h"\r
-#include "traing/training_card/include/TrainingControlView.h"\r
-#include "uicomponents/UIComponents.h"\r
-#include "vibrator_service.h"\r
-\r
-#include <chrono>\r
-#include <iomanip>\r
-#include <iostream>\r
-#include <sstream>\r
-#include <thread>\r
-#include <unordered_map>\r
-\r
-extern "C" void do_cywee_service_check_msg(int cmd, int data[]);\r
-\r
-#define MAXSPORTID 176\r
-\r
-#define DEFAULT_DASH "--"\r
-#define DATATEST 0\r
-\r
-extern "C" {\r
-void StartTimer();\r
-void StopAndResetTimer();\r
-void PauseTimer();\r
-void ResumeTimer();\r
-}\r
-#include "NativeRegisterManager.h"\r
-\r
-#ifdef SUPPORT_CYWEE_SERVICE\r
-#include "cywee_service.h"\r
-#endif\r
-namespace OHOS {\r
-\r
-REGIST_SLICE(VIEW_TRAININGCRAD, TraingCardView, TraingCardPresenter);\r
-\r
-// 当前Presenter属性实例化的内存指针\r
-static TraingCardPresenter *g_pTraingCardPresenter = nullptr;\r
-\r
-TraingCardPresenter::TraingCardPresenter() { g_pTraingCardPresenter = this; }\r
-\r
-TraingCardPresenter::~TraingCardPresenter() {\r
-  // tag_ = 0;\r
-  g_pTraingCardPresenter = nullptr;\r
-}\r
-\r
-TraingCardPresenter *TraingCardPresenter::GetInstance() {\r
-  static TraingCardPresenter instance;\r
-  return &instance;\r
-}\r
-\r
-void TraingCardPresenter::OnStart() {\r
-  Presenter<TraingCardView>::OnStart();\r
-  // ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); // 长亮屏\r
-}\r
-\r
-void TraingCardPresenter::OnPause(void) {\r
-\r
-  Presenter<TraingCardView>::OnPause();\r
-}\r
-\r
-void TraingCardPresenter::OnResume(void) {\r
-\r
-  Presenter<TraingCardView>::OnResume();\r
-  RootView::GetInstance()->SetOnKeyActListener(this);\r
-}\r
-\r
-void TraingCardPresenter::OnStop(void) {\r
-\r
-  Presenter<TraingCardView>::OnStop();\r
-  // ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON); // 长亮屏\r
-}\r
-\r
-bool TraingCardPresenter::OnDrag(UIView &view, const DragEvent &event) {\r
-  UNUSED(view);\r
-  return true;\r
-}\r
-\r
-// 计时器更新timer\r
-void TraingCardPresenter::ModifiesTime() {\r
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ModifiesTime begin");\r
-  std ::string TimeStr = TraingModel::GetInstance()->DisplayMotionDuration();\r
-\r
-  /*灭屏状态不刷新UI*/\r
-  if (uapi_get_screen_state() == 1) {\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "uapi_get_screen_state is off");\r
-    return;\r
-  }\r
-\r
-  if (TimeStr.empty()) {\r
-    WEARABLE_LOGE(\r
-        WEARABLE_LOG_MODULE_APP,\r
-        "TraingModel::GetInstance()->DisplayMotionDuration() nullptr");\r
-    return;\r
-  }\r
-  if (TrainingControlView::GetInstance() != nullptr &&\r
-      TrainingDataView::GetInstance() != nullptr) {\r
-    if (TrainingControlView::GetInstance()->GetTimeLabel() != nullptr) {\r
-      TrainingControlView::GetInstance()->GetTimeLabel()->SetText(\r
-          TimeStr.c_str());\r
-    }\r
-    if (TrainingDataView::GetInstance()->GetTimeLabel() != nullptr) {\r
-      TrainingDataView::GetInstance()->GetTimeLabel()->SetText(TimeStr.c_str());\r
-    }\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ModifiesTime end");\r
-  }\r
-}\r
-\r
-//计时器\r
-void TraingCardPresenter::UpdateTimeOfControl() {\r
-  std ::string TimeStr = TraingModel::GetInstance()->DisplayMotionDuration();\r
-  if (TimeStr.empty()) {\r
-    WEARABLE_LOGE(\r
-        WEARABLE_LOG_MODULE_APP,\r
-        "TraingModel::GetInstance()->DisplayMotionDuration() nullptr");\r
-    return;\r
-  }\r
-  if (TrainingControlView::GetInstance()->GetTimeLabel() != nullptr) {\r
-    TrainingControlView::GetInstance()->GetTimeLabel()->SetText(\r
-        TimeStr.c_str());\r
-  }\r
-#if defined(BOARD_W9) || defined(BOARD_N9)\r
-//需要判断是否需要运动是否需要gps\r
-  bool isNeedGPS = TraingModel::GetInstance()->IsNeedGPS(TraingModel::GetInstance()->GetSportEvent());\r
-  if(isNeedGPS == false)\r
-  {\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "该运动项不需要GPS");\r
-    return;\r
-  }\r
-  if (TrainingControlView::GetInstance()->GetGpsStatusLabel() != nullptr) {\r
-    //获取GPS状态\r
-    bool gpsStatus = TraingModel::GetInstance()->GetGPSConnectState();\r
-    std::string gpsStatusStr;\r
-    if (gpsStatus) {\r
-      gpsStatusStr = "GPS定位成功";\r
-      TrainingControlView::GetInstance()->GetGpsStatusLabel()->SetTextColor(\r
-          Color::Green());\r
-    } else {\r
-      gpsStatusStr = "GPS未定位成功";\r
-      TrainingControlView::GetInstance()->GetGpsStatusLabel()->SetTextColor(\r
-          Color::Red());\r
-    }\r
-    TrainingControlView::GetInstance()->GetGpsStatusLabel()->SetText(\r
-        gpsStatusStr.c_str());\r
-  }\r
-#endif\r
-}\r
-void TraingCardPresenter::UpdateTimeOfData() {\r
-  std ::string TimeStr = TraingModel::GetInstance()->DisplayMotionDuration();\r
-  if (TimeStr.empty()) {\r
-    WEARABLE_LOGE(\r
-        WEARABLE_LOG_MODULE_APP,\r
-        "TraingModel::GetInstance()->DisplayMotionDuration() nullptr");\r
-    return;\r
-  }\r
-  if (TrainingDataView::GetInstance()->GetTimeLabel() != nullptr) {\r
-    TrainingDataView::GetInstance()->GetTimeLabel()->SetText(TimeStr.c_str());\r
-  }\r
-}\r
-\r
-/* --------------------------------- cywee库操作\r
- * -------------------------------- */\r
-/*开启cywee*/\r
-bool TraingCardPresenter::OpenSensor(ExerciseClass type) {\r
-  // 防止重复开启\r
-  if (opensensorstuats) {\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OpenSensor is opening!!");\r
-    return false;\r
-  }\r
-  // 根据不同的运动项目进行不同的运动\r
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingCardPresenter::OpenSensor!!");\r
-#ifdef SUPPORT_CYWEE_SERVICE\r
-  switch (type) {\r
-  case ExerciseClass::NORMAL:\r
-    cywee_sport_mode_change(CYWEE_SERVICE_CMD_NORMAL_MODE);\r
-    break;\r
-  case ExerciseClass::TREADMILL:\r
-    cywee_sport_mode_change(CYWEE_SERVICE_CMD_TREADMILL_MODE);\r
-    break;\r
-  case ExerciseClass::OUTDOOR:\r
-    cywee_sport_mode_change(CYWEE_SERVICE_CMD_OUTDOOR_RUNNING_MODE);\r
-    break;\r
-  case ExerciseClass::INDOOR:\r
-    cywee_sport_mode_change(CYWEE_SERVICE_CMD_INDOOR_RUNNING_MODE);\r
-    break;\r
-  case ExerciseClass::FITNESS_PEDOMETER:\r
-    cywee_sport_mode_change(CYWEE_SERVICE_CMD_FITNESS_PEDOMETER_MODE);\r
-    break;\r
-  case ExerciseClass::FREE_TRAINING:\r
-    cywee_sport_mode_change(CYWEE_SERVICE_CMD_FREE_TRAINING_MODE);\r
-    break;\r
-  default:\r
-    break;\r
-  }\r
-#endif\r
-  opensensorstuats = true;\r
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OpenSensor--%d!!", type);\r
-  return true;\r
-}\r
-\r
-/*控制cywee*/\r
-bool TraingCardPresenter::ControlSensor(ExerciseState state) {\r
-#ifdef SUPPORT_PPG_SERVICE\r
-  switch (state) {\r
-  case ExerciseState::End:\r
-    // 退出进入普通模式\r
-    do_cywee_service_check_msg(CYWEE_SERVICE_CMD_NORMAL_MODE, NULL);\r
-    opensensorstuats = false; // 恢复标志位\r
-    StopAndResetTimer();      // 关闭计时器\r
-    break;\r
-  case ExerciseState::Pause:\r
-    do_cywee_service_check_msg(CYWEE_SERVICE_CMD_PAUSE, 0);\r
-    break;\r
-  case ExerciseState::Continue:\r
-    do_cywee_service_check_msg(CYWEE_SERVICE_CMD_RESUME, 0);\r
-    break;\r
-  default:\r
-    break;\r
-  }\r
-#endif\r
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ControlSensor[%d]!!", state);\r
-  return true;\r
-}\r
-\r
-void TraingCardPresenter::RefreshData(SportData *sportdata) {\r
-  if (sportdata == nullptr) {\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata is null");\r
-    return;\r
-  }\r
-\r
-  if (TrainingDetailView::GetInstance() == nullptr ||\r
-      TrainingDataView::GetInstance() == nullptr)\r
-    return;\r
-\r
-  std::string distanceStr;\r
-  if (sportdata->distance != 0) {\r
-    double distance_km =\r
-        sportdata->distance / 1000.0; // 转换为公里并保留两位小数\r
-    std::stringstream ss;\r
-    ss << std::fixed << std::setprecision(2) << distance_km;\r
-    distanceStr = ss.str();\r
-  } else {\r
-    distanceStr = DEFAULT_DASH;\r
-  }\r
-\r
-  std::string heartStr =\r
-      (sportdata->heart != 0) ? std::to_string(sportdata->heart) : DEFAULT_DASH;\r
-  std::string stepsStr =\r
-      (sportdata->steps != 0) ? std::to_string(sportdata->steps) : DEFAULT_DASH;\r
-  std::string calorieStr = (sportdata->calories != 0)\r
-                               ? std::to_string(sportdata->calories)\r
-                               : DEFAULT_DASH;\r
-  // 训练强度刷新\r
-  UIResourceTextId intensityid = TraingModel::GetInstance()->GetIntensity();\r
-  // printf("intensityid %d \r\n", intensityid);\r
-  TrainingDetailView::GetInstance()->Get_Intensity_Button()->SetTextId(\r
-      intensityid);\r
-\r
-  TrainingDataView::GetInstance()->GetProgress()->SetValue(\r
-      sportdata->goaldegree); // 目标完成度\r
-  TrainingDataView::GetInstance()->GetHeartLabel()->SetText(\r
-      heartStr.c_str()); // 心率\r
-  TrainingDetailView::GetInstance()->GetCalorieLabel()->SetText(\r
-      calorieStr.c_str()); // 卡路里\r
-  TrainingDetailView::GetInstance()->GetMileLabel()->SetText(\r
-      distanceStr.c_str()); // 距离\r
-  TrainingDetailView::GetInstance()->GetStepLabel()->SetText(\r
-      stepsStr.c_str()); // 步数\r
-\r
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
-                "[Calories: %s, Distance: %s, Steps: %s Intensityid: %d]",\r
-                calorieStr.c_str(), distanceStr.c_str(), stepsStr.c_str(),\r
-                intensityid);\r
-  // 释放sportdata内存\r
-}\r
-#if 1\r
-/*刷新 time 和 data */\r
-void TraingCardPresenter::updataview(void) {\r
-  // 如果未开启训练,直接退出\r
-  if (TraingModel::GetInstance()->GetSportState() == ExerciseState::General) {\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
-                  "TraingModel::GetInstance()->GetSportState() == "\r
-                  "ExerciseState::General ");\r
-    return;\r
-  }\r
-\r
-  if (TraingCardView::GetInstance() == nullptr) {\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "view_ == nullptr");\r
-    return;\r
-  }\r
-\r
-  Control_Card cardId = static_cast<Control_Card>(\r
-      TraingCardView::GetInstance()->GetCurrentPage());\r
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "cardId %d", (int)cardId);\r
-\r
-  switch (cardId) {\r
-  case Control_Card::CONTROL: {\r
-    UpdateTimeOfControl(); // 更新控制界面的时间\r
-    break;\r
-  }\r
-  case Control_Card::DATA: {\r
-    UpdateDataView(); // 更新训练数据视图\r
-    break;\r
-  }\r
-  default:\r
-    break; // 其他情况不处理\r
-  }\r
-}\r
-#else\r
-void TraingCardPresenter::Notify(void) {\r
-  // 如果未开启训练,直接退出\r
-  if (TraingModel::GetInstance()->GetSportState() == ExerciseState::General ||\r
-      view_ == nullptr) {\r
-    return;\r
-  }\r
-\r
-  Control_Card cardId = static_cast<Control_Card>(view_->GetCurrentPage());\r
-\r
-  switch (cardId) {\r
-  case Control_Card::CONTROL: {\r
-    UpdateTimeOfControl(); // 更新控制界面的时间\r
-    break;\r
-  }\r
-  case Control_Card::DATA: {\r
-    UpdateDataView(); // 更新训练数据视图\r
-    break;\r
-  }\r
-  default:\r
-    break; // 其他情况不处理\r
-  }\r
-}\r
-#endif\r
-void TraingCardPresenter::UpdateDataView() {\r
-  // 刷新计时\r
-  UpdateTimeOfData();\r
-\r
-  // 刷新训练数据视图,显示当前时间\r
-  GraphicService::GetInstance()->PostGraphicEvent(std::bind(\r
-      &TrainingDataView::UpdataTime, TrainingDataView::GetInstance()));\r
-\r
-  TraingModel::GetInstance()->updata_goal();\r
-\r
-  // 刷新训练数据:心率、卡路里、距离、步数、训练强度、目标完成度\r
-  SportData *sportdata = TraingModel::GetInstance()->GetSportdata();\r
-  RefreshData(sportdata);\r
-}\r
-/* --------------------------------- 点击事件处理\r
- * --------------------------------- */\r
-bool TraingCardPresenter::OnClick(UIView &view, const ClickEvent &event) {\r
-  const std::string viewId = view.GetViewId();\r
-\r
-  // 定义点击事件映射\r
-  static const std::unordered_map<std::string, std::function<void()>>\r
-      actionMap = {\r
-          // 暂停按键\r
-          {BUTTONSTOP,\r
-           [&]() {\r
-             auto currentState = TraingModel::GetInstance()->GetSportState();\r
-             if (currentState == ExerciseState::Continue ||\r
-                 currentState == ExerciseState::Start) {\r
-               handlePauseState();\r
-             } else if (currentState == ExerciseState::Pause) {\r
-               handleContinueState();\r
-             }\r
-           }},\r
-          // 结束按键\r
-          {BUTTONEND,\r
-           [&]() {\r
-             //  ControlSensor(ExerciseState::Pause);\r
-             TraingCardView::GetInstance()->SetPopupViewStatus(EndPopup, true);\r
-             TraingCardView::GetInstance()->RefreshEndView();\r
-           }},\r
-          // 确定结束\r
-          {BUTTONEXIT, [&]() { handleEndState(); }},\r
-          // 返回\r
-          {BUTTONBACK,\r
-           [&]() {\r
-             //  ControlSensor(ExerciseState::Continue);\r
-             TraingCardView::GetInstance()->SetPopupViewStatus(EndPopup, false);\r
-           }},\r
-          // 确定达到目标\r
-          {BUTTONWINOK,\r
-           [&]() {\r
-             TraingCardView::GetInstance()->GetAnimator()->Stop();\r
-             TraingCardView::GetInstance()->SetPopupViewStatus(GetTagPopup,\r
-                                                               false);\r
-           }},\r
-          // 确定心率提醒\r
-          {BUTTONNOTE,\r
-           [&]() {\r
-             TraingCardView::GetInstance()->SetPopupViewStatus(HeartPopup,\r
-                                                               false);\r
-           }},\r
-      };\r
-\r
-  // 查找并执行对应的操作\r
-  auto it = actionMap.find(viewId);\r
-  if (it != actionMap.end()) {\r
-    it->second(); // 执行操作\r
-    return true;\r
-  }\r
-\r
-  return false; // 没有匹配的操作\r
-}\r
-void TraingCardPresenter::OnSwipe(UISwipeView &view) {\r
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TempPresenter::OnSwipe ");\r
-  UNUSED(view);\r
-  return;\r
-}\r
-bool TraingCardPresenter::OnKeyAct(UIView &view, const KeyEvent &event) {\r
-  /*消耗按键事件*/\r
-  return true;\r
-}\r
-/* -------------------------------- 协议发起运动处理\r
- * -------------------------------- */\r
-#ifdef SUPPORT_BLE_SERVICE\r
-bool TraingCardPresenter::send_sport_cmd(training_ble *cmd) {\r
-  if (cmd == nullptr) {\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无效的运动命令 cmd 为空!");\r
-    return false;\r
-  }\r
-\r
-  // 获取当前的运动状态\r
-  ExerciseState currentState = TraingModel::GetInstance()->GetSportState();\r
-  ExerciseState cmdstate = static_cast<ExerciseState>(cmd->controlmd);\r
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cmdstate:%d currentState:%d",\r
-                cmdstate, currentState);\r
-  int m_sportTag = 0;\r
-  switch (cmd->controlmd) {\r
-  case SETGOAL:\r
-    // 仅在一般状态下允许设置目标\r
-    if (currentState == ExerciseState::General) {\r
-      if (cmd->sportTagType == 0) {\r
-        //训练目标->m 需要转换 km\r
-        m_sportTag = cmd->sportTag / 1000;\r
-      } else {\r
-        m_sportTag = cmd->sportTag;\r
-      }\r
-      TraingModel::GetInstance()->SetSportTag(\r
-          static_cast<ExerciseTag>(cmd->sportTagType), m_sportTag);\r
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "目标设置成功!\r\n");\r
-      return true;\r
-    }\r
-    break;\r
-\r
-  case SENDDATA:\r
-    // 随时允许发送实时数据\r
-    TraingModel::GetInstance()->SendLiveData();\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "实时数据发送成功!\r\n");\r
-    return true;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  // 仅在一般状态下允许开始运动\r
-  if (cmdstate == ExerciseState::Start) {\r
-    if ((currentState == ExerciseState::General)) {\r
-      if (TraingCardView::GetInstance() == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble 开启运动");\r
-        uapi_set_screen_on_api(); // 亮屏\r
-        NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGCRAD);\r
-        // 设置目标类型和项目有且只有一次\r
-        switch (cmd->sportType) {\r
-        case 0:\r
-          TraingModel::GetInstance()->SetSportEvent(\r
-              STR_EXERCISE_OUTDOORWALKING);\r
-          OpenSensor(ExerciseClass::OUTDOOR);\r
-          break;\r
-        case 1:\r
-          TraingModel::GetInstance()->SetSportEvent(\r
-              STR_EXERCISE_OUTDOORRUNNING);\r
-          OpenSensor(ExerciseClass::OUTDOOR);\r
-          break;\r
-        case 2:\r
-          TraingModel::GetInstance()->SetSportEvent(STR_EXERCISE_OUTDOORBIKING);\r
-          OpenSensor(ExerciseClass::FREE_TRAINING);\r
-          break;\r
-        default:\r
-          break;\r
-        }\r
-      }\r
-      reply_APP_OpenSportModeCmd(true);\r
-      handleStartState();\r
-      return true;\r
-    } else {\r
-\r
-      reply_APP_OpenSportModeCmd(false);\r
-      // return false;\r
-    }\r
-  }\r
-  // 仅在运动状态为开始或继续时允许暂停\r
-  if (cmdstate == ExerciseState::Pause) {\r
-    if (currentState == ExerciseState::Start ||\r
-        currentState == ExerciseState::Continue) {\r
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble 暂停运动");\r
-      reply_APP_SportPasueResetCmd(TraingModel::GetInstance()->GetSportTime());\r
-      handlePauseState();\r
-      return true;\r
-    }\r
-  }\r
-\r
-  // 仅在暂停状态下允许恢复运动\r
-  if (cmdstate == ExerciseState::Continue &&\r
-      currentState == ExerciseState::Pause) {\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble 恢复运动");\r
-    reply_APP_SportPasueResetCmd(TraingModel::GetInstance()->GetSportTime());\r
-    handleContinueState();\r
-    return true;\r
-  }\r
-\r
-  // 仅在运动状态为开始、继续或暂停时允许结束运动\r
-  if (cmdstate == ExerciseState::End &&\r
-      (currentState == ExerciseState::Start ||\r
-       currentState == ExerciseState::Continue ||\r
-       currentState == ExerciseState::Pause)) {\r
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble 结束运动");\r
-    uint32_t sport_time = TraingModel::GetInstance()->GetSportTime();\r
-    reply_APP_SportStopModeCmd(sport_time);\r
-    handleEndState();\r
-    return true;\r
-  }\r
-\r
-  // 如果到达这里,命令未执行\r
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
-                "cmd->sportType[%d],cmd->controlmd[%d],cmd->sportTagType[%d],"\r
-                "cmd->sportTag[%d]\r\n",\r
-                cmd->sportType, cmd->controlmd, cmd->sportTagType,\r
-                cmd->sportTag);\r
-\r
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
-                "由于状态限制,命令未执行 当前状态 %d。\r\n", currentState);\r
-  return false; // 没有执行任何命令\r
-}\r
-#endif\r
-/*训练结束*/\r
-void TraingCardPresenter::handleEndState() {\r
-  TraingModel::GetInstance()->SetSportState(ExerciseState::End);\r
-  ControlSensor(ExerciseState::End);\r
-  uapi_set_screen_on_api(); // 亮屏\r
-#if DATATEST\r
-  // NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGENDDATA);\r
-  // 回退\r
-  NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGNOMAL);\r
-  return;\r
-#endif\r
-  // 是否达到训练目标\r
-  if (TraingModel::GetInstance()->GetMomentum()) {\r
-    // 进入训练详情\r
-    NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGENDDATA);\r
-    NativeAbility::GetInstance().ClearSliceIdStack(); // 清空所有SLiceId栈元素\r
-  } else {\r
-    // 进入训练记录\r
-    // NativeAbility::GetInstance().ChangeSlice(VIEW_TRAINING_RECORD);\r
-    if (TraingModel::GetInstance()->GetEntryType() == APPLIST_ENTER)\r
-      NativeAbility::GetInstance().ChangeSlice(\r
-          VIEW_TRAINING, TransitionType::TRANSITION_BACK_TO_HEXAGONS);\r
-    else {\r
-      NativeAbility::GetInstance().ChangeSlice(\r
-          VIEW_MAIN, TransitionType::TRANSITION_BACK_TO_HEXAGONS);\r
-      NativeAbility::GetInstance().ClearSliceIdStack(); // 清空所有SLiceId栈元素\r
-    }\r
-    NativeAbility::GetInstance().ClearSliceIdStack(); // 清空所有SLiceId栈元素\r
-  }\r
-}\r
-\r
-/*训练暂停*/\r
-void TraingCardPresenter::handlePauseState() {\r
-  uapi_set_screen_on_api(); // 亮屏\r
-  TrainingControlView::GetInstance()->GetLabel()->SetTextId(STR_RESUME);\r
-  TrainingControlView::GetInstance()->GetButton()->SetImageSrc(\r
-      SPORT_CONTINUE_IMAGE, SPORT_CONTINUE_IMAGE);\r
-  TraingModel::GetInstance()->SetSportState(ExerciseState::Pause);\r
-  PauseTimer();\r
-  ControlSensor(ExerciseState::Pause);\r
-}\r
-\r
-/*训练继续*/\r
-void TraingCardPresenter::handleContinueState() {\r
-  uapi_set_screen_on_api(); // 亮屏\r
-  TrainingControlView::GetInstance()->GetLabel()->SetTextId(STR_PAUSE);\r
-  TrainingControlView::GetInstance()->GetButton()->SetImageSrc(\r
-      SPORT_PAUSE_IMAGE, SPORT_PAUSE_IMAGE);\r
-  TraingModel::GetInstance()->SetSportState(ExerciseState::Continue);\r
-  ResumeTimer();\r
-  ControlSensor(ExerciseState::Continue);\r
-}\r
-\r
-/*训练开始*/\r
-void TraingCardPresenter::handleStartState() {\r
-  ControlSensor(ExerciseState::Start);\r
-  TraingModel::GetInstance()->SetSportOpenWay(true);\r
-}\r
-\r
-} // namespace OHOS\r
+ #include "AppViewIDs.h"\r
+ #include "NativeAbility.h"\r
+ #include "components/ui_label_ext.h"\r
+ #include "ui_resource_string.h"\r
+ \r
+ #include "ConfigModel.h"\r
+ #include "custom_utils.h"\r
+ #include "graphic_service.h"\r
+ #include "traing/include/TraingModel.h"\r
+ #include "traing/training_card/include/TraingCardPresenter.h"\r
+ #include "traing/training_card/include/TrainingControlView.h"\r
+ #include "uicomponents/UIComponents.h"\r
+ #include "vibrator_service.h"\r
+ \r
+ #include <chrono>\r
+ #include <iomanip>\r
+ #include <iostream>\r
+ #include <sstream>\r
+ #include <thread>\r
+ #include <unordered_map>\r
+ \r
+ extern "C" void do_cywee_service_check_msg(int cmd, int data[]);\r
+ \r
+ #define MAXSPORTID 176\r
+ \r
+ #define DEFAULT_DASH "--"\r
+ #define DATATEST 0\r
+ \r
+ extern "C" {\r
+ void StartTimer();\r
+ void StopAndResetTimer();\r
+ void PauseTimer();\r
+ void ResumeTimer();\r
+ }\r
+ #include "NativeRegisterManager.h"\r
+ \r
+ #ifdef SUPPORT_CYWEE_SERVICE\r
+ #include "cywee_service.h"\r
+ #endif\r
+ namespace OHOS {\r
+ \r
+ REGIST_SLICE(VIEW_TRAININGCRAD, TraingCardView, TraingCardPresenter);\r
+ \r
+ // 当前Presenter属性实例化的内存指针\r
+ static TraingCardPresenter *g_pTraingCardPresenter = nullptr;\r
+ \r
+ TraingCardPresenter::TraingCardPresenter() { g_pTraingCardPresenter = this; }\r
+ \r
+ TraingCardPresenter::~TraingCardPresenter() {\r
+   // tag_ = 0;\r
+   g_pTraingCardPresenter = nullptr;\r
+ }\r
+ \r
+ TraingCardPresenter *TraingCardPresenter::GetInstance() {\r
+   static TraingCardPresenter instance;\r
+   return &instance;\r
+ }\r
+ \r
+ void TraingCardPresenter::OnStart() {\r
+   Presenter<TraingCardView>::OnStart();\r
+   // ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); // 长亮屏\r
+ }\r
+ \r
+ void TraingCardPresenter::OnPause(void) {\r
+ \r
+   Presenter<TraingCardView>::OnPause();\r
+ }\r
+ \r
+ void TraingCardPresenter::OnResume(void) {\r
+ \r
+   Presenter<TraingCardView>::OnResume();\r
+   RootView::GetInstance()->SetOnKeyActListener(this);\r
+ }\r
+ \r
+ void TraingCardPresenter::OnStop(void) {\r
+ \r
+   Presenter<TraingCardView>::OnStop();\r
+   // ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON); // 长亮屏\r
+ }\r
+ \r
+ bool TraingCardPresenter::OnDrag(UIView &view, const DragEvent &event) {\r
+   UNUSED(view);\r
+   return true;\r
+ }\r
+ \r
+ // 计时器更新timer\r
+ void TraingCardPresenter::ModifiesTime() {\r
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ModifiesTime begin");\r
+   std ::string TimeStr = TraingModel::GetInstance()->DisplayMotionDuration();\r
+ \r
+   /*灭屏状态不刷新UI*/\r
+   if (uapi_get_screen_state() == 1) {\r
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "uapi_get_screen_state is off");\r
+     return;\r
+   }\r
+ \r
+   if (TimeStr.empty()) {\r
+     WEARABLE_LOGE(\r
+         WEARABLE_LOG_MODULE_APP,\r
+         "TraingModel::GetInstance()->DisplayMotionDuration() nullptr");\r
+     return;\r
+   }\r
+   if (TrainingControlView::GetInstance() != nullptr &&\r
+       TrainingDataView::GetInstance() != nullptr) {\r
+     if (TrainingControlView::GetInstance()->GetTimeLabel() != nullptr) {\r
+       TrainingControlView::GetInstance()->GetTimeLabel()->SetText(\r
+           TimeStr.c_str());\r
+     }\r
+     if (TrainingDataView::GetInstance()->GetTimeLabel() != nullptr) {\r
+       TrainingDataView::GetInstance()->GetTimeLabel()->SetText(TimeStr.c_str());\r
+     }\r
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ModifiesTime end");\r
+   }\r
+ }\r
+ \r
+ //计时器\r
+ void TraingCardPresenter::UpdateTimeOfControl() {\r
+   std ::string TimeStr = TraingModel::GetInstance()->DisplayMotionDuration();\r
+   if (TimeStr.empty()) {\r
+     WEARABLE_LOGE(\r
+         WEARABLE_LOG_MODULE_APP,\r
+         "TraingModel::GetInstance()->DisplayMotionDuration() nullptr");\r
+     return;\r
+   }\r
+   if (TrainingControlView::GetInstance()->GetTimeLabel() != nullptr) {\r
+     TrainingControlView::GetInstance()->GetTimeLabel()->SetText(\r
+         TimeStr.c_str());\r
+   }\r
+   //需要判断是否需要运动是否需要gps\r
+   bool isNeedGPS = TraingModel::GetInstance()->IsNeedGPS(TraingModel::GetInstance()->GetSportEvent());\r
+   if(isNeedGPS == false)\r
+   {\r
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "该运动项不需要GPS");\r
+     return;\r
+   }\r
+   \r
+   if (TrainingControlView::GetInstance()->GetGpsStatusLabel() != nullptr) {\r
+     //获取GPS状态\r
+     bool gpsStatus = TraingModel::GetInstance()->GetGPSConnectState();\r
+     std::string gpsStatusStr;\r
+     if (gpsStatus) {\r
+       gpsStatusStr = "GPS定位成功";\r
+       TrainingControlView::GetInstance()->GetGpsStatusLabel()->SetTextColor(\r
+           Color::Green());\r
+     } else {\r
+       gpsStatusStr = "GPS未定位成功";\r
+       TrainingControlView::GetInstance()->GetGpsStatusLabel()->SetTextColor(\r
+           Color::Red());\r
+     }\r
+     TrainingControlView::GetInstance()->GetGpsStatusLabel()->SetText(\r
+         gpsStatusStr.c_str());\r
+   }\r
+ }\r
+ void TraingCardPresenter::UpdateTimeOfData() {\r
+   std ::string TimeStr = TraingModel::GetInstance()->DisplayMotionDuration();\r
+   if (TimeStr.empty()) {\r
+     WEARABLE_LOGE(\r
+         WEARABLE_LOG_MODULE_APP,\r
+         "TraingModel::GetInstance()->DisplayMotionDuration() nullptr");\r
+     return;\r
+   }\r
+   if (TrainingDataView::GetInstance()->GetTimeLabel() != nullptr) {\r
+     TrainingDataView::GetInstance()->GetTimeLabel()->SetText(TimeStr.c_str());\r
+   }\r
+ }\r
+ \r
+ /* --------------------------------- cywee库操作\r
+  * -------------------------------- */\r
+ /*开启cywee*/\r
+ bool TraingCardPresenter::OpenSensor(ExerciseClass type) {\r
+   // 防止重复开启\r
+   if (opensensorstuats) {\r
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OpenSensor is opening!!");\r
+     return false;\r
+   }\r
+   // 根据不同的运动项目进行不同的运动\r
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingCardPresenter::OpenSensor!!");\r
+ #ifdef SUPPORT_CYWEE_SERVICE\r
+   switch (type) {\r
+   case ExerciseClass::NORMAL:\r
+     cywee_sport_mode_change(CYWEE_SERVICE_CMD_NORMAL_MODE);\r
+     break;\r
+   case ExerciseClass::TREADMILL:\r
+     cywee_sport_mode_change(CYWEE_SERVICE_CMD_TREADMILL_MODE);\r
+     break;\r
+   case ExerciseClass::OUTDOOR:\r
+     cywee_sport_mode_change(CYWEE_SERVICE_CMD_OUTDOOR_RUNNING_MODE);\r
+     break;\r
+   case ExerciseClass::INDOOR:\r
+     cywee_sport_mode_change(CYWEE_SERVICE_CMD_INDOOR_RUNNING_MODE);\r
+     break;\r
+   case ExerciseClass::FITNESS_PEDOMETER:\r
+     cywee_sport_mode_change(CYWEE_SERVICE_CMD_FITNESS_PEDOMETER_MODE);\r
+     break;\r
+   case ExerciseClass::FREE_TRAINING:\r
+     cywee_sport_mode_change(CYWEE_SERVICE_CMD_FREE_TRAINING_MODE);\r
+     break;\r
+   default:\r
+     break;\r
+   }\r
+ #endif\r
+   opensensorstuats = true;\r
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OpenSensor--%d!!", type);\r
+   return true;\r
+ }\r
+ \r
+ /*控制cywee*/\r
+ bool TraingCardPresenter::ControlSensor(ExerciseState state) {\r
+ #ifdef SUPPORT_PPG_SERVICE\r
+   switch (state) {\r
+   case ExerciseState::End:\r
+     // 退出进入普通模式\r
+     do_cywee_service_check_msg(CYWEE_SERVICE_CMD_NORMAL_MODE, NULL);\r
+     opensensorstuats = false; // 恢复标志位\r
+     StopAndResetTimer();      // 关闭计时器\r
+     break;\r
+   case ExerciseState::Pause:\r
+     do_cywee_service_check_msg(CYWEE_SERVICE_CMD_PAUSE, 0);\r
+     break;\r
+   case ExerciseState::Continue:\r
+     do_cywee_service_check_msg(CYWEE_SERVICE_CMD_RESUME, 0);\r
+     break;\r
+   default:\r
+     break;\r
+   }\r
+ #endif\r
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ControlSensor[%d]!!", state);\r
+   return true;\r
+ }\r
+ \r
+ void TraingCardPresenter::RefreshData(SportData *sportdata) {\r
+   if (sportdata == nullptr) {\r
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata is null");\r
+     return;\r
+   }\r
+ \r
+   if (TrainingDetailView::GetInstance() == nullptr ||\r
+       TrainingDataView::GetInstance() == nullptr)\r
+     return;\r
+ \r
+   std::string distanceStr;\r
+   if (sportdata->distance != 0) {\r
+     double distance_km =\r
+         sportdata->distance / 1000.0; // 转换为公里并保留两位小数\r
+     std::stringstream ss;\r
+     ss << std::fixed << std::setprecision(2) << distance_km;\r
+     distanceStr = ss.str();\r
+   } else {\r
+     distanceStr = DEFAULT_DASH;\r
+   }\r
+ \r
+   std::string heartStr =\r
+       (sportdata->heart != 0) ? std::to_string(sportdata->heart) : DEFAULT_DASH;\r
+   std::string stepsStr =\r
+       (sportdata->steps != 0) ? std::to_string(sportdata->steps) : DEFAULT_DASH;\r
+   std::string calorieStr = (sportdata->calories != 0)\r
+                                ? std::to_string(sportdata->calories)\r
+                                : DEFAULT_DASH;\r
+   // 训练强度刷新\r
+   UIResourceTextId intensityid = TraingModel::GetInstance()->GetIntensity();\r
+   // printf("intensityid %d \r\n", intensityid);\r
+   TrainingDetailView::GetInstance()->Get_Intensity_Button()->SetTextId(\r
+       intensityid);\r
+ \r
+   TrainingDataView::GetInstance()->GetProgress()->SetValue(\r
+       sportdata->goaldegree); // 目标完成度\r
+   TrainingDataView::GetInstance()->GetHeartLabel()->SetText(\r
+       heartStr.c_str()); // 心率\r
+   TrainingDetailView::GetInstance()->GetCalorieLabel()->SetText(\r
+       calorieStr.c_str()); // 卡路里\r
+   TrainingDetailView::GetInstance()->GetMileLabel()->SetText(\r
+       distanceStr.c_str()); // 距离\r
+   TrainingDetailView::GetInstance()->GetStepLabel()->SetText(\r
+       stepsStr.c_str()); // 步数\r
+ \r
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                 "[Calories: %s, Distance: %s, Steps: %s Intensityid: %d]",\r
+                 calorieStr.c_str(), distanceStr.c_str(), stepsStr.c_str(),\r
+                 intensityid);\r
+   // 释放sportdata内存\r
+ }\r
+ #if 1\r
+ /*刷新 time 和 data */\r
+ void TraingCardPresenter::updataview(void) {\r
+   // 如果未开启训练,直接退出\r
+   if (TraingModel::GetInstance()->GetSportState() == ExerciseState::General) {\r
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                   "TraingModel::GetInstance()->GetSportState() == "\r
+                   "ExerciseState::General ");\r
+     return;\r
+   }\r
+ \r
+   if (TraingCardView::GetInstance() == nullptr) {\r
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "view_ == nullptr");\r
+     return;\r
+   }\r
+ \r
+   Control_Card cardId = static_cast<Control_Card>(\r
+       TraingCardView::GetInstance()->GetCurrentPage());\r
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "cardId %d", (int)cardId);\r
+ \r
+   switch (cardId) {\r
+   case Control_Card::CONTROL: {\r
+     UpdateTimeOfControl(); // 更新控制界面的时间\r
+     break;\r
+   }\r
+   case Control_Card::DATA: {\r
+     UpdateDataView(); // 更新训练数据视图\r
+     break;\r
+   }\r
+   default:\r
+     break; // 其他情况不处理\r
+   }\r
+ }\r
+ #else\r
+ void TraingCardPresenter::Notify(void) {\r
+   // 如果未开启训练,直接退出\r
+   if (TraingModel::GetInstance()->GetSportState() == ExerciseState::General ||\r
+       view_ == nullptr) {\r
+     return;\r
+   }\r
+ \r
+   Control_Card cardId = static_cast<Control_Card>(view_->GetCurrentPage());\r
+ \r
+   switch (cardId) {\r
+   case Control_Card::CONTROL: {\r
+     UpdateTimeOfControl(); // 更新控制界面的时间\r
+     break;\r
+   }\r
+   case Control_Card::DATA: {\r
+     UpdateDataView(); // 更新训练数据视图\r
+     break;\r
+   }\r
+   default:\r
+     break; // 其他情况不处理\r
+   }\r
+ }\r
+ #endif\r
+ void TraingCardPresenter::UpdateDataView() {\r
+   // 刷新计时\r
+   UpdateTimeOfData();\r
+ \r
+   // 刷新训练数据视图,显示当前时间\r
+   GraphicService::GetInstance()->PostGraphicEvent(std::bind(\r
+       &TrainingDataView::UpdataTime, TrainingDataView::GetInstance()));\r
+ \r
+   TraingModel::GetInstance()->updata_goal();\r
+ \r
+   // 刷新训练数据:心率、卡路里、距离、步数、训练强度、目标完成度\r
+   SportData *sportdata = TraingModel::GetInstance()->GetSportdata();\r
+   RefreshData(sportdata);\r
+ }\r
+ /* --------------------------------- 点击事件处理\r
+  * --------------------------------- */\r
+ bool TraingCardPresenter::OnClick(UIView &view, const ClickEvent &event) {\r
+   const std::string viewId = view.GetViewId();\r
+ \r
+   // 定义点击事件映射\r
+   static const std::unordered_map<std::string, std::function<void()>>\r
+       actionMap = {\r
+           // 暂停按键\r
+           {BUTTONSTOP,\r
+            [&]() {\r
+              auto currentState = TraingModel::GetInstance()->GetSportState();\r
+              if (currentState == ExerciseState::Continue ||\r
+                  currentState == ExerciseState::Start) {\r
+                handlePauseState();\r
+              } else if (currentState == ExerciseState::Pause) {\r
+                handleContinueState();\r
+              }\r
+            }},\r
+           // 结束按键\r
+           {BUTTONEND,\r
+            [&]() {\r
+              //  ControlSensor(ExerciseState::Pause);\r
+              TraingCardView::GetInstance()->SetPopupViewStatus(EndPopup, true);\r
+              TraingCardView::GetInstance()->RefreshEndView();\r
+            }},\r
+           // 确定结束\r
+           {BUTTONEXIT, [&]() { handleEndState(); }},\r
+           // 返回\r
+           {BUTTONBACK,\r
+            [&]() {\r
+              //  ControlSensor(ExerciseState::Continue);\r
+              TraingCardView::GetInstance()->SetPopupViewStatus(EndPopup, false);\r
+            }},\r
+           // 确定达到目标\r
+           {BUTTONWINOK,\r
+            [&]() {\r
+              TraingCardView::GetInstance()->GetAnimator()->Stop();\r
+              TraingCardView::GetInstance()->SetPopupViewStatus(GetTagPopup,\r
+                                                                false);\r
+            }},\r
+           // 确定心率提醒\r
+           {BUTTONNOTE,\r
+            [&]() {\r
+              TraingCardView::GetInstance()->SetPopupViewStatus(HeartPopup,\r
+                                                                false);\r
+            }},\r
+       };\r
+ \r
+   // 查找并执行对应的操作\r
+   auto it = actionMap.find(viewId);\r
+   if (it != actionMap.end()) {\r
+     it->second(); // 执行操作\r
+     return true;\r
+   }\r
+ \r
+   return false; // 没有匹配的操作\r
+ }\r
+ void TraingCardPresenter::OnSwipe(UISwipeView &view) {\r
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TempPresenter::OnSwipe ");\r
+   UNUSED(view);\r
+   return;\r
+ }\r
+ bool TraingCardPresenter::OnKeyAct(UIView &view, const KeyEvent &event) {\r
+   /*消耗按键事件*/\r
+   return true;\r
+ }\r
+ /* -------------------------------- 协议发起运动处理\r
+  * -------------------------------- */\r
+ #ifdef SUPPORT_BLE_SERVICE\r
+ bool TraingCardPresenter::send_sport_cmd(training_ble *cmd) {\r
+   if (cmd == nullptr) {\r
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无效的运动命令 cmd 为空!");\r
+     return false;\r
+   }\r
+ \r
+   // 获取当前的运动状态\r
+   ExerciseState currentState = TraingModel::GetInstance()->GetSportState();\r
+   ExerciseState cmdstate = static_cast<ExerciseState>(cmd->controlmd);\r
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cmdstate:%d currentState:%d",\r
+                 cmdstate, currentState);\r
+   int m_sportTag = 0;\r
+   switch (cmd->controlmd) {\r
+   case SETGOAL:\r
+     // 仅在一般状态下允许设置目标\r
+     if (currentState == ExerciseState::General) {\r
+       if (cmd->sportTagType == 0) {\r
+         //训练目标->m 需要转换 km\r
+         m_sportTag = cmd->sportTag / 1000;\r
+       } else {\r
+         m_sportTag = cmd->sportTag;\r
+       }\r
+       TraingModel::GetInstance()->SetSportTag(\r
+           static_cast<ExerciseTag>(cmd->sportTagType), m_sportTag);\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "目标设置成功!\r\n");\r
+       return true;\r
+     }\r
+     break;\r
+ \r
+   case SENDDATA:\r
+     // 随时允许发送实时数据\r
+     TraingModel::GetInstance()->SendLiveData();\r
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "实时数据发送成功!\r\n");\r
+     return true;\r
+ \r
+   default:\r
+     break;\r
+   }\r
+ \r
+   // 仅在一般状态下允许开始运动\r
+   if (cmdstate == ExerciseState::Start) {\r
+     if ((currentState == ExerciseState::General)) {\r
+       if (TraingCardView::GetInstance() == nullptr) {\r
+         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble 开启运动");\r
+         uapi_set_screen_on_api(); // 亮屏\r
+         NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGCRAD);\r
+         // 设置目标类型和项目有且只有一次\r
+         switch (cmd->sportType) {\r
+         case 0:\r
+           TraingModel::GetInstance()->SetSportEvent(\r
+               STR_EXERCISE_OUTDOORWALKING);\r
+           OpenSensor(ExerciseClass::OUTDOOR);\r
+           break;\r
+         case 1:\r
+           TraingModel::GetInstance()->SetSportEvent(\r
+               STR_EXERCISE_OUTDOORRUNNING);\r
+           OpenSensor(ExerciseClass::OUTDOOR);\r
+           break;\r
+         case 2:\r
+           TraingModel::GetInstance()->SetSportEvent(STR_EXERCISE_OUTDOORBIKING);\r
+           OpenSensor(ExerciseClass::FREE_TRAINING);\r
+           break;\r
+         default:\r
+           break;\r
+         }\r
+       }\r
+       reply_APP_OpenSportModeCmd(true);\r
+       // 打印app开启的运动的数据\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*************app开启运动******************");\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sportType:%d",cmd->sportType);\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sportTagType:%d",cmd->sportTagType);\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sportTag:%d",cmd->sportTag);\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");\r
+       handleStartState();\r
+       return true;\r
+     } else {\r
+ \r
+       reply_APP_OpenSportModeCmd(false);\r
+       // return false;\r
+     }\r
+   }\r
+   // 仅在运动状态为开始或继续时允许暂停\r
+   if (cmdstate == ExerciseState::Pause) {\r
+     if (currentState == ExerciseState::Start ||\r
+         currentState == ExerciseState::Continue) {\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble 暂停运动");\r
+       reply_APP_SportPasueResetCmd(TraingModel::GetInstance()->GetSportTime());\r
+       handlePauseState();\r
+       return true;\r
+     }\r
+   }\r
+ \r
+   // 仅在暂停状态下允许恢复运动\r
+   if (cmdstate == ExerciseState::Continue &&\r
+       currentState == ExerciseState::Pause) {\r
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble 恢复运动");\r
+     reply_APP_SportPasueResetCmd(TraingModel::GetInstance()->GetSportTime());\r
+     handleContinueState();\r
+     return true;\r
+   }\r
+ \r
+   // 仅在运动状态为开始、继续或暂停时允许结束运动\r
+   if (cmdstate == ExerciseState::End &&\r
+       (currentState == ExerciseState::Start ||\r
+        currentState == ExerciseState::Continue ||\r
+        currentState == ExerciseState::Pause)) {\r
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ble 结束运动");\r
+     uint32_t sport_time = TraingModel::GetInstance()->GetSportTime();\r
+     reply_APP_SportStopModeCmd(sport_time);\r
+     handleEndState();\r
+     return true;\r
+   }\r
+ \r
+   // 如果到达这里,命令未执行\r
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                 "cmd->sportType[%d],cmd->controlmd[%d],cmd->sportTagType[%d],"\r
+                 "cmd->sportTag[%d]\r\n",\r
+                 cmd->sportType, cmd->controlmd, cmd->sportTagType,\r
+                 cmd->sportTag);\r
+ \r
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                 "由于状态限制,命令未执行 当前状态 %d。\r\n", currentState);\r
+   return false; // 没有执行任何命令\r
+ }\r
+ #endif\r
+ /*训练结束*/\r
+ void TraingCardPresenter::handleEndState() {\r
+   TraingModel::GetInstance()->SetSportState(ExerciseState::End);\r
+   ControlSensor(ExerciseState::End);\r
+   uapi_set_screen_on_api(); // 亮屏\r
+ #if DATATEST\r
+   // NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGENDDATA);\r
+   // 回退\r
+   NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGNOMAL);\r
+   return;\r
+ #endif\r
+   // 是否达到训练目标\r
+   if (TraingModel::GetInstance()->GetMomentum()) {\r
+     // 进入训练详情\r
+     NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGENDDATA);\r
+     NativeAbility::GetInstance().ClearSliceIdStack(); // 清空所有SLiceId栈元素\r
+   } else {\r
+     // 进入训练记录\r
+     // NativeAbility::GetInstance().ChangeSlice(VIEW_TRAINING_RECORD);\r
+     if (TraingModel::GetInstance()->GetEntryType() == APPLIST_ENTER)\r
+       NativeAbility::GetInstance().ChangeSlice(\r
+           VIEW_TRAINING, TransitionType::TRANSITION_BACK_TO_HEXAGONS);\r
+     else {\r
+       NativeAbility::GetInstance().ChangeSlice(\r
+           VIEW_MAIN, TransitionType::TRANSITION_BACK_TO_HEXAGONS);\r
+       NativeAbility::GetInstance().ClearSliceIdStack(); // 清空所有SLiceId栈元素\r
+     }\r
+     NativeAbility::GetInstance().ClearSliceIdStack(); // 清空所有SLiceId栈元素\r
+   }\r
+ }\r
+ \r
+ /*训练暂停*/\r
+ void TraingCardPresenter::handlePauseState() {\r
+   uapi_set_screen_on_api(); // 亮屏\r
+   TrainingControlView::GetInstance()->GetLabel()->SetTextId(STR_RESUME);\r
+   TrainingControlView::GetInstance()->GetButton()->SetImageSrc(\r
+       SPORT_CONTINUE_IMAGE, SPORT_CONTINUE_IMAGE);\r
+   TraingModel::GetInstance()->SetSportState(ExerciseState::Pause);\r
+   PauseTimer();\r
+   ControlSensor(ExerciseState::Pause);\r
+ }\r
+ \r
+ /*训练继续*/\r
+ void TraingCardPresenter::handleContinueState() {\r
+   uapi_set_screen_on_api(); // 亮屏\r
+   TrainingControlView::GetInstance()->GetLabel()->SetTextId(STR_PAUSE);\r
+   TrainingControlView::GetInstance()->GetButton()->SetImageSrc(\r
+       SPORT_PAUSE_IMAGE, SPORT_PAUSE_IMAGE);\r
+   TraingModel::GetInstance()->SetSportState(ExerciseState::Continue);\r
+   ResumeTimer();\r
+   ControlSensor(ExerciseState::Continue);\r
+ }\r
+ \r
+ /*训练开始*/\r
+ void TraingCardPresenter::handleStartState() {\r
+   ControlSensor(ExerciseState::Start);\r
+   TraingModel::GetInstance()->SetSportOpenWay(true);\r
+   //开启心率\r
+   TraingModel::GetInstance()->start_training_heart();\r
+ #if defined(SUPPORT_GNSS)\r
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开启gps定时器");\r
+   TraingModel::GetInstance()->gnss_start_timer(1000);\r
+ #endif\r
+   // 快捷训练都属于健身类\r
+   TraingModel::GetInstance()->SetSportType(Exercisetype::FITNESS);\r
+ }\r
+ \r
+ } // namespace OHOS\r
+ 
\ No newline at end of file
index 4e8f79c..6b98910 100644 (file)
      offset = 0;
      break;
    }
-   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " offset %d id %d", offset, id);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "编译id offset %d id %d", offset, id);
    return id - offset;
  }
  
      Startstate = true;
      Endstate = false; // 确保"开始"和"结束"状态互斥
  
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始运动");
+      //打印目前运动配置项
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "*******************************");
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始运动");
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportType:%d", sportdata->sportType);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportId:%d", sportdata->sportId);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportTagType:%d", sportdata->sportTagType);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportTag:%d", sportdata->tag);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "*******************************");
+  
  
      sport_start_data_timer(300); //开启数据获取定时器 刷新频率是300ms
  
  }
  
  /*
-     uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练
-     uint32_t bt;  // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4
-    - 水上项目,5 - 冰上项目,6 - 极限运动,7 - 其他 uint32_t ty;  //
-    训练类型:自由训练 uint32_t st;  // 开始时间戳(单位:秒) uint32_t sp;  //
-    结束时间戳(单位:秒) uint32_t tgt; // 训练目标类型:0 - 距离,1 - 卡路里,2
-    - 时间,3 - 步数 uint32_t tg;  //
-    训练目标值:路程(单位:米),卡路里(单位:kcal),时间(单位:分钟),步数(单位:步)
-     uint32_t pg;  // 目标完成度(单位:%)
-     uint32_t du;  // 训练总时长(单位:秒)
-     uint32_t ca;  // 消耗卡路里(单位:kcal)
-     uint32_t di;  // 完成的距离(单位:米)
-     uint32_t hr;  // 平均心率
-     uint32_t stp; // 步数
-     uint32_t ti;  // 训练强度:0 - 较低强度,1 - 中等强度,2 - 高等强度,3 -
-    超高强度 uint32_t cir; // 圈数 uint32_t alt; // 最高海拔高度
+   uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练
+   uint32_t bt;  // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4 - 水上项目,5 - 冰上项目,6 - 极限运动,7 - 其他 
+   uint32_t  ty;  //训练类型:自由训练 
+   uint32_t st;  // 开始时间戳(单位:秒)
+   uint32_t sp;  // 结束时间戳(单位:秒) 
+   uint32_t tgt; // 训练目标类型:0 - 距离,1 - 卡路里,2- 时间,3 - 步数 
+   uint32_t tg;  //训练目标值:路程(单位:米),卡路里(单位:kcal),时间(单位:分钟),步数(单位:步)
+   uint32_t pg;  // 目标完成度(单位:%)
+   uint32_t du;  // 训练总时长(单位:秒)
+   uint32_t ca;  // 消耗卡路里(单位:kcal)
+   uint32_t di;  // 完成的距离(单位:米)
+   uint32_t hr;  // 平均心率
+   uint32_t stp; // 步数
+   uint32_t ti;  // 训练强度:0 - 较低强度,1 - 中等强度,2 - 高等强度,3 - 超高强度 
+   uint32_t cir; // 圈数 
+   uint32_t alt; // 最高海拔高度
  */
  /*保存数据*/
  bool TraingModel::SaveSportData() {
    Trainingdata data;
    data.src = Openingway;
    data.bt = static_cast<uint32_t>(sportdata->sportType);
-   data.ty = static_cast<uint32_t>(
-       GetBleSportId(sportdata->sportType, sportdata->sportId));
+   data.ty = static_cast<uint32_t>(GetBleSportId(sportdata->sportType, sportdata->sportId));
    data.st = static_cast<uint32_t>(sportdata->starttime);
    data.sp = static_cast<uint32_t>(sportdata->endtime);
    data.tgt = static_cast<uint32_t>(sportdata->sportTagType);
      // 保存GPS数据
      if (!SaveCanvasData()) {
        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveCanvasData is error!");
-       return false; //必须手表端存储成功
+       // return false; 
      }
      if (!SaveGPSData()) {
        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData is error!");
        cJSON_AddNumberToObject(itemJSON, "spc", data->spc);
        cJSON_AddNumberToObject(itemJSON, "std", data->std);
        cJSON_AddNumberToObject(itemJSON, "cdc", data->cdc);
- 
        cJSON_AddItemReferenceToArray(data_arryJSON, itemJSON);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"src:%d",data->src);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"bt:%d",data->bt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ty:%d",data->ty);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"st:%d",data->st);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sp:%d",data->sp);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tgt:%d",data->tgt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tg:%d",data->tg);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"pg:%d",data->pg);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"du:%d",data->du);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ca:%d",data->ca);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"di:%d",data->di);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hr:%d",data->hr);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"stp:%d",data->stp);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ti:%d",data->ti);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cir:%d",data->cir);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"alt:%d",data->alt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"apc:%d",data->apc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"fpc:%d",data->fpc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"spc:%d",data->spc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"std:%d",data->std);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cdc:%d",data->cdc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
        free(data);
        data = NULL;
      } else {
          if(data!=NULL)
          {
              WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"%d,%d\r\n",timetamp,data->st);
+             // 打印data数据
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"src:%d",data->src);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"bt:%d",data->bt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ty:%d",data->ty);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"st:%d",data->st);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sp:%d",data->sp);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tgt:%d",data->tgt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tg:%d",data->tg);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"pg:%d",data->pg);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"du:%d",data->du);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ca:%d",data->ca);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"di:%d",data->di);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hr:%d",data->hr);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"stp:%d",data->stp);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ti:%d",data->ti);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cir:%d",data->cir);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"alt:%d",data->alt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"apc:%d",data->apc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"fpc:%d",data->fpc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"spc:%d",data->spc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"std:%d",data->std);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cdc:%d",data->cdc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
              int time_error= timetamp>data->st ? timetamp-data->st:data->st-timetamp;
              if(time_error<=2)
              {
index 97d25a0..73d7219 100644 (file)
      TrainingControlView::GetInstance()->GetTimeLabel()->SetText(\r
          TimeStr.c_str());\r
    }\r
- #if defined(BOARD_W9) || defined(BOARD_N9)\r
- //需要判断是否需要运动是否需要gps\r
+   //需要判断是否需要运动是否需要gps\r
    bool isNeedGPS = TraingModel::GetInstance()->IsNeedGPS(TraingModel::GetInstance()->GetSportEvent());\r
    if(isNeedGPS == false)\r
    {\r
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "该运动项不需要GPS");\r
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "该运动项不需要GPS");\r
      return;\r
    }\r
+   \r
    if (TrainingControlView::GetInstance()->GetGpsStatusLabel() != nullptr) {\r
      //获取GPS状态\r
      bool gpsStatus = TraingModel::GetInstance()->GetGPSConnectState();\r
      TrainingControlView::GetInstance()->GetGpsStatusLabel()->SetText(\r
          gpsStatusStr.c_str());\r
    }\r
- #endif\r
  }\r
  void TraingCardPresenter::UpdateTimeOfData() {\r
    std ::string TimeStr = TraingModel::GetInstance()->DisplayMotionDuration();\r
          }\r
        }\r
        reply_APP_OpenSportModeCmd(true);\r
+       // 打印app开启的运动的数据\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*************app开启运动******************");\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sportType:%d",cmd->sportType);\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sportTagType:%d",cmd->sportTagType);\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sportTag:%d",cmd->sportTag);\r
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");\r
        handleStartState();\r
        return true;\r
      } else {\r
  void TraingCardPresenter::handleStartState() {\r
    ControlSensor(ExerciseState::Start);\r
    TraingModel::GetInstance()->SetSportOpenWay(true);\r
+   //开启心率\r
+   TraingModel::GetInstance()->start_training_heart();\r
+ #if defined(SUPPORT_GNSS)\r
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开启gps定时器");\r
+   TraingModel::GetInstance()->gnss_start_timer(1000);\r
+ #endif\r
+   // 快捷训练都属于健身类\r
+   TraingModel::GetInstance()->SetSportType(Exercisetype::FITNESS);\r
  }\r
  \r
  } // namespace OHOS\r
index 0fff18f..6b98910 100644 (file)
  * @FilePath:
  * /sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp
  */
-#include "traing/include/TraingModel.h"
-#include "cmsis_os.h"
-#include "custom_utils.h"
-#include "safemodemanager/include/SafeModeManagerModelC.h"
-#include "thread_adapter.h"
-#include "traing/training_card/include/TraingCardPresenter.h"
-#include "uicomponents/UIComponents.h"
-#include "wearable_log.h"
-#include <cmsis_os2.h>
-#include <cstdint>
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <service/graphic_service.h>
-#include <sstream>
-#include <string>
-
-#include "ConfigModel.h"
-
-#ifdef SUPPORT_BLE_SERVICE
-#include "bleEvent.h"
-#include "bleService.h"
-#endif
-
-#ifdef SUPPORT_PPG_SERVICE
-#include "ppg_hal.h"
-#include "ppg_service.h"
-#endif
-
-#ifdef SUPPORT_CYWEE_SERVICE
-#include "cywee_hal.h"
-#include "cywee_service.h"
-#endif
-
-#define SPORT_TIMER_DATA 1
-
-#include "broadcast_feature.h"
-#include "broadcast_service.h"
-#include "custom_runtime.h"
-#include "power_display_service.h"
-#include "samgr_lite.h"
-
-#include "traingrecord/include/TraingRecordModel.h"
-
-#include "vibrator_service.h"
-#include <algorithm>
-#include <cmath>
-#include <filesystem>
-#include <fstream>
-#include <limits.h>
-#include <list>
-#include <memory>
-#include <mutex>
-#include <numeric>
-#include <queue>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <vector>
-
-#include "chip_system_time.h"
-#include "cmath"
-#include "system/include/SystemLogModel.h"
-#include <custom_save_runtime.h>
-
-#include "graphic_service.h"
-
-#if defined(SUPPORT_GNSS)
-#include "NMEA0183.h"
-#include "gnss_ctl.h"
-#include "pgnss_sample.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-static void Training_Notify(void *args, const Topic topic, Request *request);
-
-using namespace OHOS;
-
-Subscriber TraingSubscirber = {
-    .identity = NULL,
-    .args = NULL,
-    .Notify = Training_Notify,
-};
-
-void TraingSubscribeTopic(Topic topic) {
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "stepsubscribeTopic, topic=%u", topic);
-  BroadcastApi *broadcastApi = NULL;
-  IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME,
-                                                     BROADCAST_FEATURE_NAME);
-  if (api == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "stepsubscribeTopic, GetFeatureApi failed");
-    return;
-  }
-  int result =
-      api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);
-  if (result != 0 || broadcastApi == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "stepsubscribeTopic, QueryInterface failed");
-    return;
-  }
-  broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic,
-                               &TraingSubscirber);
-  broadcastApi->Release((IUnknown *)broadcastApi);
-}
-
-void TraingUnsubscribeTopic(Topic topic) {
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingUnsubscribeTopic, topic=%u",
-                topic);
-  BroadcastApi *broadcastApi = NULL;
-  IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME,
-                                                     BROADCAST_FEATURE_NAME);
-  if (api == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "TraingUnsubscribeTopic, GetFeatureApi failed");
-    return;
-  }
-  int result =
-      api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);
-  if (result != 0 || broadcastApi == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "TraingUnsubscribeTopic, QueryInterface failed");
-    return;
-  }
-  broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic,
-                                 &TraingSubscirber);
-  broadcastApi->Release((IUnknown *)broadcastApi);
-}
-int flag = 0;
-static void Training_Notify(void *args, const Topic topic, Request *request) {
-#ifdef SUPPORT_CYWEE_SERVICE
-  UNUSED(args);
-  UNUSED(topic);
-  if (request == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "request is NULL");
-    return;
-  }
-  //蓝牙开启运动
-  if (request->msgId == TOPIC_EVENT_BLE_TRAINING) {
-    training_ble *traingbleInfo = new training_ble();
-    int rets = memcpy_s(traingbleInfo, sizeof(training_ble),
-                        (training_ble *)request->data, request->len);
-    if (rets != EOK) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "memcpy_s act_result_t fail  ret = %d", rets);
-      return;
-    }
-#ifdef SUPPORT_BLE_SERVICE
-    TraingCardPresenter::GetInstance()->send_sport_cmd(traingbleInfo);
-#endif
-    delete traingbleInfo;
-  }
-  //增加训练runtime控制
-  if (uapi_dev_runtime_get_train_status() == 0 ||
-      TraingModel::GetInstance()->GetSportState() == ExerciseState::End) {
-    return;
-  }
-  //训练基本信息更新
-  if (request->msgId == TOPIC_EVENT_ACTIVITY_UPDATE) {
-    act_result_t *cyweeInfo = new act_result_t();
-    int rets = memcpy_s(cyweeInfo, sizeof(act_result_t),
-                        (act_result_t *)request->data, request->len);
-    if (rets != EOK) {
-      delete cyweeInfo; // 处理内存分配失败的情况
-      cyweeInfo = NULL;
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "memcpy_s act_result_t fail ret = %d", rets);
-      return;
-    }
-    TraingModel::GetInstance()->AnalysisData(cyweeInfo);
-    // 更新其他目标完成度
-    TraingModel::GetInstance()->CheckSportTag();
-    delete cyweeInfo; // 释放内存
-  }
-  //训练额外信息
-  if (request->msgId == TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE) {
-    act_ext_result_t *cyweeInfo_ext = new act_ext_result_t();
-    int rets = memcpy_s(cyweeInfo_ext, sizeof(act_ext_result_t),
-                        (act_ext_result_t *)request->data, request->len);
-    if (rets != EOK) {
-      delete cyweeInfo_ext; // 处理内存分配失败的情况
-      cyweeInfo_ext = NULL;
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "memcpy_s act_ext_result_t fail ret = %d", rets);
-      return;
-    }
-    TraingModel::GetInstance()->AnalysisExtraData(cyweeInfo_ext);
-    delete cyweeInfo_ext; // 释放内存
-  }
-  //训练心率
-  if (request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA) {
-    uint8_t heart = *((u_int8_t *)(request->data)); // 进行类型转换
-    TraingModel::GetInstance()->AnalysisHeartData(heart);
-  }
-#endif
-}
-#ifdef __cplusplus
-}
-#endif
-
-void store_sport_data() {
-  // printf("运动数据存储!\r\n");
-  OHOS::TraingModel::GetInstance()->RecordSportData();
-  return;
-}
-
-namespace OHOS {
-#if TIMER
-// 声明定时器变量
-static osTimerId_t g_startCounting = NULL; // 定时器
-static constexpr uint64_t MS_ONE_SECONDS = 1000;
-static int g_motionTimes{0};
-static constexpr int32 NUM_TEN = 10;
-static constexpr int16 ERROR = 0;
-static constexpr int16 SUCCESS = 1;
-static constexpr int16 NUM_TIME_MIN = 60;
-static constexpr int16 NUM_TIME_HOUR = 3600;
-static constexpr int32 NUM_TIME_DAY = 86400;
-#endif
-
-// #define min(x, y)       (((x) < (y)) ? (x) : (y))
-// #define max(x, y)       (((x) > (y)) ? (x) : (y))
-
-SportData *sportdata = new SportData();
-int shock_count{0}; //震动提醒
-
-TraingModel ::TraingModel() {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::TraingModel()");
-  // sportdata->Initialize(); // 初始化结构体
-}
-TraingModel ::~TraingModel() {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::~TraingModel()");
-  // TraingUnsubscribeTopic(TOPIC_EVENT_ACTIVITY_UPDATE); // 取消订阅
-  TraingUnsubscribeTopic(TOPIC_EVENT_BLE_TRAINING);
-  // TraingUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);
-  // TraingUnsubscribeTopic(TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE);
-}
-TraingModel *TraingModel::GetInstance(void) {
-  static TraingModel instance;
-  return &instance;
-}
-
-void TraingModel ::Init() {
-  // TraingSubscribeTopic(TOPIC_EVENT_ACTIVITY_UPDATE); // 进行消息订阅
-  TraingSubscribeTopic(TOPIC_EVENT_BLE_TRAINING);
-  // TraingSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);
-  // TraingSubscribeTopic(TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE);
-}
-/*设置运动类型*/
-void TraingModel::SetSportType(Exercisetype type) { sportType_ = type; }
-/*获取训练Id->协议*/
-int TraingModel::GetBleSportId(Exercisetype sporttype, UIResourceTextId id) {
-  int offset = 0;
-
-  switch (sporttype) {
-  case Exercisetype::FITNESS: // 0~57
-    offset = 0;
-    break;
-  case Exercisetype::DANCE: // 0~9
-    offset = 58;
-    break;
-  case Exercisetype::LEISURE: // 0~23
-    offset = 58 + 10;
-    break;
-  case Exercisetype::BALL: // 0~28
-    offset = 58 + 10 + 24;
-    break;
-  case Exercisetype::WATER: // 0~23
-    offset = 58 + 10 + 24 + 29;
-    break;
-  case Exercisetype::ICE: // 0~11
-    offset = 58 + 10 + 24 + 29 + 24;
-    break;
-  case Exercisetype::EXTREME: // 0~9
-    offset = 58 + 10 + 24 + 29 + 24 + 12;
-    break;
-  case Exercisetype::OTHER: // 0~8
-    offset = 58 + 10 + 24 + 29 + 24 + 12 + 10;
-    break;
-  default:
-    offset = 0;
-    break;
-  }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "编译id offset %d id %d", offset, id);
-  return id - offset;
-}
-
-/*结束数据icon*/
-std::string sportImages[8] = {
-    FITNESS_54_IMAGE,  DANCE_54_IMAGE, REST_54_IMAGE,  BALL_54_IMAGE,
-    SWIMMING_54_IMAGE, ICE_54_IMAGE,   LIMIT_54_IMAGE, OTHER_54_IMAGE,
-};
-/*训练记录Icon*/
-std::string sportIcons[8] = {
-    FITNESS_IMAGE,  DANCE_IMAGE, REST_IMAGE,  BALL_IMAGE,
-    SWIMMING_IMAGE, ICE_IMAGE,   LIMIT_IMAGE, OTHER_IMAGE,
-};
-/*特殊运动icon*/
-std::string sportIcons_special[6] = {RUNNING_60_IMAGE_END, WALKING_60_IMAGE_END,
-                                     RIDING_60_IMAGE_END,  RUNNING_IMAGE,
-                                     WALKING_IMAGE,        RIDING_IMAGE};
-
-/*
-  type
-  0 是运动结束图标
-  1 是运动类型图标
-*/
-std::string TraingModel::GetSportIcon(Exercisetype sporttype,
-                                      UIResourceTextId id, uint8_t type) {
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                " GetSportIcon sporttype %d id %d type %d", sporttype, id,
-                type);
-  bool specialsport = false;
-  uint8_t specialindex = 0;
-  switch (id) {
-  case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING:
-  case UIResourceTextId::STR_EXERCISE_INDOORRUNNING:
-    specialsport = true;
-    specialindex = 0;
-    break;
-  case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING:
-  case UIResourceTextId::STR_EXERCISE_INDOORWALKING:
-    specialsport = true;
-    specialindex = 1;
-    break;
-  case UIResourceTextId::STR_EXERCISE_OUTDOORBIKING:
-    specialsport = true;
-    specialindex = 2;
-    break;
-  }
-  int index = static_cast<int>(sporttype);
-  if (specialsport) {
-    // 特殊运动
-    if (type == 0) {
-      return sportIcons_special[specialindex]; //返回特殊运动大图标
-    } else {
-      return sportIcons_special[specialindex + 3]; //返回特殊运动小图标
-    }
-  }
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetResource index %d", index);
-  if (type == 0) {
-    return sportImages[index]; //返回运动类大图标
-  } else {
-    return sportIcons[index]; //返回运动类小图标
-  }
-  return "";
-}
-/*设置运动Id*/
-void TraingModel::SetSportEvent(UIResourceTextId id) {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SetSportType %d", sportId_);
-  //需要是结束开启的运动才重新配置
-  if (sportState_ == ExerciseState::General) {
-    IsSpecialSport(id); // 设置特殊性
-    sportId_ = id;
-  }
-}
-/*获取运动Id*/
-UIResourceTextId TraingModel::GetSportEvent() {
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportEvent %d", sportId_);
-  return sportId_;
-}
-/*获取运动项目*/
-ExerciseClass TraingModel::GetSportId() {
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportType %d", sportId_);
-  // 设置结构体里面的运动类型
-  sportdata->sportId = sportId_;
-  sportdata->sportType = sportType_;
-
-  switch (sportId_) {
-    // 室外跑步 室外走路
-  case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING:
-  case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING:
-    // return ExerciseClass::OUTDOOR; 统一使用室内
-
-    // 室内跑步 室内走路
-  case UIResourceTextId::STR_EXERCISE_INDOORRUNNING:
-  case UIResourceTextId::STR_EXERCISE_INDOORWALKING:
-    return ExerciseClass::INDOOR;
-
-    // 跑步机
-  case UIResourceTextId::STR_EXERCISE_TREADMILL:
-  case UIResourceTextId::STR_EXERCISE_STROLLMACHINE:
-    return ExerciseClass::TREADMILL;
-
-    // 自由训练
-  default:
-    return ExerciseClass::FREE_TRAINING;
-  }
-}
-/*判断是否为需要Gps的运动*/
-bool TraingModel::IsNeedGPS(UIResourceTextId sportId_) {
-  //跑步 走路 骑行需要GPS
-  switch (sportId_) {
-  case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING:
-  case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING:
-  case UIResourceTextId::STR_EXERCISE_INDOORRUNNING:
-  case UIResourceTextId::STR_EXERCISE_INDOORWALKING:
-  case UIResourceTextId::STR_EXERCISE_TREADMILL:
-  case UIResourceTextId::STR_EXERCISE_STROLLMACHINE:
-    return true;
-  default:
-    return false;
-  }
-}
-/*判断是否为特殊运动*/
-void TraingModel::IsSpecialSport(UIResourceTextId sportId_) {
-  switch (sportId_) {
-  case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING: // 室外跑步 室外走路
-  case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING:
-  case UIResourceTextId::STR_EXERCISE_INDOORRUNNING: // 室内跑步 室内走路
-  case UIResourceTextId::STR_EXERCISE_INDOORWALKING:
-  case UIResourceTextId::STR_EXERCISE_TREADMILL: // 跑步机
-  case UIResourceTextId::STR_EXERCISE_STROLLMACHINE:
-    isspecialsport_ = true;
-    break;
-  default: // 自由训练
-    isspecialsport_ = false;
-    break;
-  }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " 特殊训练 %d 训练项 %d",
-                isspecialsport_, sportId_);
-}
-
-bool TraingModel::GetIsSpecial() { return isspecialsport_; }
-/*获取目标字符串*/
-std::string TraingModel::GetTagStr() {
-  /*
-      通用目标配置: 时长、卡路里
-      不通用目标配置: 步数、距离
-
-      如果配置项是特殊目标
-                          -> 普通训练: 无训练目标
-                          -> 特殊训练: 有训练目标
+ #include "traing/include/TraingModel.h"
+ #include "cmsis_os.h"
+ #include "custom_utils.h"
+ #include "safemodemanager/include/SafeModeManagerModelC.h"
+ #include "thread_adapter.h"
+ #include "traing/training_card/include/TraingCardPresenter.h"
+ #include "uicomponents/UIComponents.h"
+ #include "wearable_log.h"
+ #include <cmsis_os2.h>
+ #include <cstdint>
+ #include <fstream>
+ #include <iomanip>
+ #include <iostream>
+ #include <service/graphic_service.h>
+ #include <sstream>
+ #include <string>
+ 
+ #include "ConfigModel.h"
+ 
+ #ifdef SUPPORT_BLE_SERVICE
+ #include "bleEvent.h"
+ #include "bleService.h"
+ #endif
+ 
+ #ifdef SUPPORT_PPG_SERVICE
+ #include "ppg_hal.h"
+ #include "ppg_service.h"
+ #endif
+ 
+ #ifdef SUPPORT_CYWEE_SERVICE
+ #include "cywee_hal.h"
+ #include "cywee_service.h"
+ #endif
+ 
+ #define SPORT_TIMER_DATA 1
+ 
+ #include "broadcast_feature.h"
+ #include "broadcast_service.h"
+ #include "custom_runtime.h"
+ #include "power_display_service.h"
+ #include "samgr_lite.h"
+ 
+ #include "traingrecord/include/TraingRecordModel.h"
+ 
+ #include "vibrator_service.h"
+ #include <algorithm>
+ #include <cmath>
+ #include <filesystem>
+ #include <fstream>
+ #include <limits.h>
+ #include <list>
+ #include <memory>
+ #include <mutex>
+ #include <numeric>
+ #include <queue>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
+ #include <vector>
+ 
+ #include "chip_system_time.h"
+ #include "cmath"
+ #include "system/include/SystemLogModel.h"
+ #include <custom_save_runtime.h>
+ 
+ #include "graphic_service.h"
+ 
+ #if defined(SUPPORT_GNSS)
+ #include "NMEA0183.h"
+ #include "gnss_ctl.h"
+ #include "pgnss_sample.h"
+ #endif
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ static void Training_Notify(void *args, const Topic topic, Request *request);
+ 
+ using namespace OHOS;
+ 
+ Subscriber TraingSubscirber = {
+     .identity = NULL,
+     .args = NULL,
+     .Notify = Training_Notify,
+ };
+ 
+ void TraingSubscribeTopic(Topic topic) {
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "stepsubscribeTopic, topic=%u", topic);
+   BroadcastApi *broadcastApi = NULL;
+   IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME,
+                                                      BROADCAST_FEATURE_NAME);
+   if (api == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "stepsubscribeTopic, GetFeatureApi failed");
+     return;
+   }
+   int result =
+       api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);
+   if (result != 0 || broadcastApi == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "stepsubscribeTopic, QueryInterface failed");
+     return;
+   }
+   broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic,
+                                &TraingSubscirber);
+   broadcastApi->Release((IUnknown *)broadcastApi);
+ }
+ 
+ void TraingUnsubscribeTopic(Topic topic) {
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingUnsubscribeTopic, topic=%u",
+                 topic);
+   BroadcastApi *broadcastApi = NULL;
+   IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME,
+                                                      BROADCAST_FEATURE_NAME);
+   if (api == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "TraingUnsubscribeTopic, GetFeatureApi failed");
+     return;
+   }
+   int result =
+       api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);
+   if (result != 0 || broadcastApi == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "TraingUnsubscribeTopic, QueryInterface failed");
+     return;
+   }
+   broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic,
+                                  &TraingSubscirber);
+   broadcastApi->Release((IUnknown *)broadcastApi);
+ }
+ int flag = 0;
+ static void Training_Notify(void *args, const Topic topic, Request *request) {
+ #ifdef SUPPORT_CYWEE_SERVICE
+   UNUSED(args);
+   UNUSED(topic);
+   if (request == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "request is NULL");
+     return;
+   }
+   //蓝牙开启运动
+   if (request->msgId == TOPIC_EVENT_BLE_TRAINING) {
+     training_ble *traingbleInfo = new training_ble();
+     int rets = memcpy_s(traingbleInfo, sizeof(training_ble),
+                         (training_ble *)request->data, request->len);
+     if (rets != EOK) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "memcpy_s act_result_t fail  ret = %d", rets);
+       return;
+     }
+ #ifdef SUPPORT_BLE_SERVICE
+     TraingCardPresenter::GetInstance()->send_sport_cmd(traingbleInfo);
+ #endif
+     delete traingbleInfo;
+   }
+   //增加训练runtime控制
+   if (uapi_dev_runtime_get_train_status() == 0 ||
+       TraingModel::GetInstance()->GetSportState() == ExerciseState::End) {
+     return;
+   }
+   //训练基本信息更新
+   if (request->msgId == TOPIC_EVENT_ACTIVITY_UPDATE) {
+     act_result_t *cyweeInfo = new act_result_t();
+     int rets = memcpy_s(cyweeInfo, sizeof(act_result_t),
+                         (act_result_t *)request->data, request->len);
+     if (rets != EOK) {
+       delete cyweeInfo; // 处理内存分配失败的情况
+       cyweeInfo = NULL;
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "memcpy_s act_result_t fail ret = %d", rets);
+       return;
+     }
+     TraingModel::GetInstance()->AnalysisData(cyweeInfo);
+     // 更新其他目标完成度
+     TraingModel::GetInstance()->CheckSportTag();
+     delete cyweeInfo; // 释放内存
+   }
+   //训练额外信息
+   if (request->msgId == TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE) {
+     act_ext_result_t *cyweeInfo_ext = new act_ext_result_t();
+     int rets = memcpy_s(cyweeInfo_ext, sizeof(act_ext_result_t),
+                         (act_ext_result_t *)request->data, request->len);
+     if (rets != EOK) {
+       delete cyweeInfo_ext; // 处理内存分配失败的情况
+       cyweeInfo_ext = NULL;
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "memcpy_s act_ext_result_t fail ret = %d", rets);
+       return;
+     }
+     TraingModel::GetInstance()->AnalysisExtraData(cyweeInfo_ext);
+     delete cyweeInfo_ext; // 释放内存
+   }
+   //训练心率
+   if (request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA) {
+     uint8_t heart = *((u_int8_t *)(request->data)); // 进行类型转换
+     TraingModel::GetInstance()->AnalysisHeartData(heart);
+   }
+ #endif
+ }
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ void store_sport_data() {
+   // printf("运动数据存储!\r\n");
+   OHOS::TraingModel::GetInstance()->RecordSportData();
+   return;
+ }
+ 
+ namespace OHOS {
+ #if TIMER
+ // 声明定时器变量
+ static osTimerId_t g_startCounting = NULL; // 定时器
+ static constexpr uint64_t MS_ONE_SECONDS = 1000;
+ static int g_motionTimes{0};
+ static constexpr int32 NUM_TEN = 10;
+ static constexpr int16 ERROR = 0;
+ static constexpr int16 SUCCESS = 1;
+ static constexpr int16 NUM_TIME_MIN = 60;
+ static constexpr int16 NUM_TIME_HOUR = 3600;
+ static constexpr int32 NUM_TIME_DAY = 86400;
+ #endif
+ 
+ // #define min(x, y)       (((x) < (y)) ? (x) : (y))
+ // #define max(x, y)       (((x) > (y)) ? (x) : (y))
+ 
+ SportData *sportdata = new SportData();
+ int shock_count{0}; //震动提醒
+ 
+ TraingModel ::TraingModel() {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::TraingModel()");
+   // sportdata->Initialize(); // 初始化结构体
+ }
+ TraingModel ::~TraingModel() {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::~TraingModel()");
+   // TraingUnsubscribeTopic(TOPIC_EVENT_ACTIVITY_UPDATE); // 取消订阅
+   TraingUnsubscribeTopic(TOPIC_EVENT_BLE_TRAINING);
+   // TraingUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);
+   // TraingUnsubscribeTopic(TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE);
+ }
+ TraingModel *TraingModel::GetInstance(void) {
+   static TraingModel instance;
+   return &instance;
+ }
+ 
+ void TraingModel ::Init() {
+   // TraingSubscribeTopic(TOPIC_EVENT_ACTIVITY_UPDATE); // 进行消息订阅
+   TraingSubscribeTopic(TOPIC_EVENT_BLE_TRAINING);
+   // TraingSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);
+   // TraingSubscribeTopic(TOPIC_EVENT_ACTIVITY_EXTRA_INFO_UPDATE);
+ }
+ /*设置运动类型*/
+ void TraingModel::SetSportType(Exercisetype type) { sportType_ = type; }
+ /*获取训练Id->协议*/
+ int TraingModel::GetBleSportId(Exercisetype sporttype, UIResourceTextId id) {
+   int offset = 0;
+ 
+   switch (sporttype) {
+   case Exercisetype::FITNESS: // 0~57
+     offset = 0;
+     break;
+   case Exercisetype::DANCE: // 0~9
+     offset = 58;
+     break;
+   case Exercisetype::LEISURE: // 0~23
+     offset = 58 + 10;
+     break;
+   case Exercisetype::BALL: // 0~28
+     offset = 58 + 10 + 24;
+     break;
+   case Exercisetype::WATER: // 0~23
+     offset = 58 + 10 + 24 + 29;
+     break;
+   case Exercisetype::ICE: // 0~11
+     offset = 58 + 10 + 24 + 29 + 24;
+     break;
+   case Exercisetype::EXTREME: // 0~9
+     offset = 58 + 10 + 24 + 29 + 24 + 12;
+     break;
+   case Exercisetype::OTHER: // 0~8
+     offset = 58 + 10 + 24 + 29 + 24 + 12 + 10;
+     break;
+   default:
+     offset = 0;
+     break;
+   }
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "编译id offset %d id %d", offset, id);
+   return id - offset;
+ }
+ 
+ /*结束数据icon*/
+ std::string sportImages[8] = {
+     FITNESS_54_IMAGE,  DANCE_54_IMAGE, REST_54_IMAGE,  BALL_54_IMAGE,
+     SWIMMING_54_IMAGE, ICE_54_IMAGE,   LIMIT_54_IMAGE, OTHER_54_IMAGE,
+ };
+ /*训练记录Icon*/
+ std::string sportIcons[8] = {
+     FITNESS_IMAGE,  DANCE_IMAGE, REST_IMAGE,  BALL_IMAGE,
+     SWIMMING_IMAGE, ICE_IMAGE,   LIMIT_IMAGE, OTHER_IMAGE,
+ };
+ /*特殊运动icon*/
+ std::string sportIcons_special[6] = {RUNNING_60_IMAGE_END, WALKING_60_IMAGE_END,
+                                      RIDING_60_IMAGE_END,  RUNNING_IMAGE,
+                                      WALKING_IMAGE,        RIDING_IMAGE};
+ 
+ /*
+   type
+   0 是运动结束图标
+   1 是运动类型图标
+ */
+ std::string TraingModel::GetSportIcon(Exercisetype sporttype,
+                                       UIResourceTextId id, uint8_t type) {
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                 " GetSportIcon sporttype %d id %d type %d", sporttype, id,
+                 type);
+   bool specialsport = false;
+   uint8_t specialindex = 0;
+   switch (id) {
+   case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING:
+   case UIResourceTextId::STR_EXERCISE_INDOORRUNNING:
+     specialsport = true;
+     specialindex = 0;
+     break;
+   case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING:
+   case UIResourceTextId::STR_EXERCISE_INDOORWALKING:
+     specialsport = true;
+     specialindex = 1;
+     break;
+   case UIResourceTextId::STR_EXERCISE_OUTDOORBIKING:
+     specialsport = true;
+     specialindex = 2;
+     break;
+   }
+   int index = static_cast<int>(sporttype);
+   if (specialsport) {
+     // 特殊运动
+     if (type == 0) {
+       return sportIcons_special[specialindex]; //返回特殊运动大图标
+     } else {
+       return sportIcons_special[specialindex + 3]; //返回特殊运动小图标
+     }
+   }
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetResource index %d", index);
+   if (type == 0) {
+     return sportImages[index]; //返回运动类大图标
+   } else {
+     return sportIcons[index]; //返回运动类小图标
+   }
+   return "";
+ }
+ /*设置运动Id*/
+ void TraingModel::SetSportEvent(UIResourceTextId id) {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SetSportType %d", sportId_);
+   //需要是结束开启的运动才重新配置
+   if (sportState_ == ExerciseState::General) {
+     IsSpecialSport(id); // 设置特殊性
+     sportId_ = id;
+   }
+ }
+ /*获取运动Id*/
+ UIResourceTextId TraingModel::GetSportEvent() {
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportEvent %d", sportId_);
+   return sportId_;
+ }
+ /*获取运动项目*/
+ ExerciseClass TraingModel::GetSportId() {
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " GetSportType %d", sportId_);
+   // 设置结构体里面的运动类型
+   sportdata->sportId = sportId_;
+   sportdata->sportType = sportType_;
+ 
+   switch (sportId_) {
+     // 室外跑步 室外走路
+   case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING:
+   case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING:
+     // return ExerciseClass::OUTDOOR; 统一使用室内
+ 
+     // 室内跑步 室内走路
+   case UIResourceTextId::STR_EXERCISE_INDOORRUNNING:
+   case UIResourceTextId::STR_EXERCISE_INDOORWALKING:
+     return ExerciseClass::INDOOR;
+ 
+     // 跑步机
+   case UIResourceTextId::STR_EXERCISE_TREADMILL:
+   case UIResourceTextId::STR_EXERCISE_STROLLMACHINE:
+     return ExerciseClass::TREADMILL;
+ 
+     // 自由训练
+   default:
+     return ExerciseClass::FREE_TRAINING;
+   }
+ }
+ /*判断是否为需要Gps的运动*/
+ bool TraingModel::IsNeedGPS(UIResourceTextId sportId_) {
+   //跑步 走路 骑行需要GPS
+   switch (sportId_) {
+   case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING:
+   case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING:
+   case UIResourceTextId::STR_EXERCISE_INDOORRUNNING:
+   case UIResourceTextId::STR_EXERCISE_INDOORWALKING:
+   case UIResourceTextId::STR_EXERCISE_TREADMILL:
+   case UIResourceTextId::STR_EXERCISE_STROLLMACHINE:
+     return true;
+   default:
+     return false;
+   }
+ }
+ /*判断是否为特殊运动*/
+ void TraingModel::IsSpecialSport(UIResourceTextId sportId_) {
+   switch (sportId_) {
+   case UIResourceTextId::STR_EXERCISE_OUTDOORRUNNING: // 室外跑步 室外走路
+   case UIResourceTextId::STR_EXERCISE_OUTDOORWALKING:
+   case UIResourceTextId::STR_EXERCISE_INDOORRUNNING: // 室内跑步 室内走路
+   case UIResourceTextId::STR_EXERCISE_INDOORWALKING:
+   case UIResourceTextId::STR_EXERCISE_TREADMILL: // 跑步机
+   case UIResourceTextId::STR_EXERCISE_STROLLMACHINE:
+     isspecialsport_ = true;
+     break;
+   default: // 自由训练
+     isspecialsport_ = false;
+     break;
+   }
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " 特殊训练 %d 训练项 %d",
+                 isspecialsport_, sportId_);
+ }
+ 
+ bool TraingModel::GetIsSpecial() { return isspecialsport_; }
+ /*获取目标字符串*/
+ std::string TraingModel::GetTagStr() {
+   /*
+       通用目标配置: 时长、卡路里
+       不通用目标配置: 步数、距离
+ 
+       如果配置项是特殊目标
+                           -> 普通训练: 无训练目标
+                           -> 特殊训练: 有训练目标
+   */
+ 
+   std::string tagStr;
+ 
+   switch (sportTagType_) {
+   case ExerciseTag::Duration:
+     tagStr = std::to_string(sportTag_) + " min"; // 时长目标
+     break;
+ 
+   case ExerciseTag::Calories:
+     tagStr = std::to_string(sportTag_) + " kcal"; // 卡路里目标
+     break;
+ 
+   case ExerciseTag::Steps:
+   case ExerciseTag::Distance:
+     if (isspecialsport_) // 检查是否为特殊训练
+     {
+       // 只在特殊训练模式下使用步数和距离目标
+       if (sportTagType_ == ExerciseTag::Steps) {
+         tagStr = std::to_string(sportTag_) + " steps"; // 步数目标
+       } else {
+         tagStr = std::to_string(sportTag_) + " km"; // 距离目标
+       }
+     } else {
+       tagStr = ""; // 普通训练下不使用目标
+     }
+     break;
+ 
+   default:
+     tagStr = ""; // 未知目标类型
+     break;
+   }
+ 
+   return tagStr;
+ }
+ /*设置运动状态*/
+ void TraingModel::SetSportState(ExerciseState state) {
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " SetSportState %d", state);
+   if (state != ExerciseState::General) {
+     /*app发起的运动*/
+     if (Openingway == true) {
+       if (state == ExerciseState::Start) {
+         sportdata->duration = 0;
+       }
+ #ifdef SUPPORT_BLE_SERVICE
+       sendtraningstatedata(static_cast<uint8_t>(state), sportdata->duration);
+ #endif
+     }
+   }
+   sportState_ = state;
+ #ifdef SYSTEM_LOG_SERVICE
+   // 记录运动状态
+   if (state == ExerciseState::End) {
+     uapi_save_runtime_log(RUNTIME_LOG_SPORT_END);
+   } else if (state == ExerciseState::Continue) {
+     uapi_save_runtime_log(RUNTIME_LOG_SPORT_RESUME);
+   } else if (state == ExerciseState::Pause) {
+     uapi_save_runtime_log(RUNTIME_LOG_SPORT_PAUSE);
+   }
+ #endif
+ }
+ /*获取运动状态*/
+ ExerciseState TraingModel::GetSportState() { return sportState_; }
+ // 计算平均心率的函数
+ double CalculateAverageHeartRate(const std::vector<int> &heartRates) {
+   if (heartRates.size() <= 2) {
+     // 如果心率数据点少于等于2,无法去掉最高和最低值
+     return 0.0; // 或者返回心率的平均值
+   }
+ 
+   // 创建一个副本以避免修改原始数据
+   std::vector<int> sortedHeartRates = heartRates;
+ 
+   // 排序
+   std::sort(sortedHeartRates.begin(), sortedHeartRates.end());
+ 
+   // 去掉一个最高值和一个最低值
+   sortedHeartRates.erase(sortedHeartRates.begin()); // 去掉最低值
+   sortedHeartRates.pop_back();                      // 去掉最高值
+ 
+   // 计算剩余心率的平均值
+   double sum = 0;
+   for (int rate : sortedHeartRates) {
+     sum += rate;
+   }
+ 
+   return sum / sortedHeartRates.size(); // 返回平均值
+ }
+ #ifdef SUPPORT_CYWEE_SERVICE
+ /*分析数据*/
+ void TraingModel::AnalysisData(act_result_t *cyweeInfo) {
+   if (cyweeInfo == NULL)
+     return;
+ 
+   // 不同的运动类型解析不同的数据
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                 "AnalysisData:[steps %d, distance %d,calories %d, pace %d, "
+                 "step_frequency %d, step_length %d]",
+                 cyweeInfo->steps, cyweeInfo->distance, cyweeInfo->calories,
+                 cyweeInfo->pace, cyweeInfo->step_frequency,
+                 cyweeInfo->step_length);
+   // 通用数据
+   sportdata->steps = cyweeInfo->steps;
+   sportdata->distance = cyweeInfo->distance;
+   sportdata->calories = cyweeInfo->calories;
+ 
+   // sportdata->cdc = cyweeInfo->step_frequency;
+   // sportdata->std = cyweeInfo->step_length;
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " pace %d", sportdata->pc);
+ 
+   sportdata->pc = cyweeInfo->pace;
+ 
+   // 更新最慢配速
+   if (sportdata->spc < sportdata->pc && sportdata->pc != 0) {
+     sportdata->spc = sportdata->pc;
+   }
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "spc %d", sportdata->spc);
+ 
+   // 计算平均心率
+   if (sportdata->heart > 50) {
+     sportdata->avgheart = Averageheartrate(sportdata->heart);
+   }
+ 
+   // 心率提醒
+   if (sportdata->heart >= user_maxHeart && user_maxHeart != 0) {
+     uapi_set_screen_on_api(); // 亮屏检测
+     if (true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb() &&
+         (!uapi_sleep_mode_flag_get())) {
+       custom_VibratorFunc_int(0);
+     }
+     if (TraingCardView::GetInstance()) {
+       GraphicService::GetInstance()->PostGraphicEvent(
+           std::bind(&TraingCardView::SetPopupViewStatus,
+                     TraingCardView::GetInstance(), HeartPopup, true));
+       if (TraingCardView::GetInstance()->GetHeartMaxLabel()) {
+         GraphicService::GetInstance()->PostGraphicEvent(
+             std::bind(&TraingCardView::SetHeartMaxLabel,
+                       TraingCardView::GetInstance(), user_maxHeart));
+       }
+     }
+   }
+ }
+ #endif
+ 
+ #if 0
+      int avg_step_freq;//平均步频
+      int avg_step_len;//平均步长
+      int avg_pace;//平均配速
+      int max_step_freq;//最大步频
+      int max_pace;//最大配速
+      int activity_zone;//活动程度区间 0低度 1中度 2高度
+      int ativity_zone_moderate_duration;//中度活动时间
+      int ativity_zone_high_duration;//高度活动时间
+      int MHR_zone;//心率区间
+      int distance_motion;//体感距离
+ #endif
+ 
+ /*分析activity extra info数据*/
+ #ifdef SUPPORT_CYWEE_SERVICE
+ void TraingModel::AnalysisExtraData(act_ext_result_t *cyweeInfo) {
+ 
+   //判断是否为特殊训练
+   if (isspecialsport_ == false) {
+     return;
+   }
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[apc:%d fpc:%d cdc:%d std:%d]",
+                 cyweeInfo->avg_pace, cyweeInfo->max_pace,
+                 cyweeInfo->avg_step_freq, cyweeInfo->avg_step_len);
+   //平均配速
+   if (cyweeInfo->avg_pace != 0) {
+     sportdata->apc = cyweeInfo->avg_pace;
+   }
+   //最快配速
+   if (cyweeInfo->max_pace != 0) {
+     sportdata->fpc = cyweeInfo->max_pace;
+   }
+   //平均步频
+   if (cyweeInfo->avg_step_freq != 0) {
+     sportdata->cdc = cyweeInfo->avg_step_freq;
+   }
+   //平均步长
+   if (cyweeInfo->avg_step_len != 0) {
+     sportdata->std = cyweeInfo->avg_step_len * 100; // 前者cm 后者m
+   }
+ }
+ #endif
+ /*分析运动心率数据*/
+ void TraingModel::AnalysisHeartData(uint8_t hrs) {
+   sportdata->heart = hrs;
+   SetIntensity(sportdata->heart); // 设置训练强度
+ }
+ 
+ /*打印函数*/
+ void TraingModel::printf_data(SportData *data) {
+   /*打印测试一下数据*/
+   printf("\r\n****************************************\r\n");
+   printf("Sport type: %d\n", data->sportType);
+   printf("Sport ID: %d\n", data->sportId);
+   printf("Start date: %s\n", data->start_date.c_str());
+   printf("Start time: %s\n", data->start_time.c_str());
+   printf("End time: %s\n", data->end_time.c_str());
+   printf("Goal degree: %d\n", data->goaldegree);
+   printf("Duration: %d\n", data->duration);
+   printf("Distance: %d\n", data->distance);
+   printf("Average heart rate: %d\n", data->avgheart);
+   printf("Steps: %d\n", data->steps);
+   printf("Intensity: %d\n", data->intensity);
+   printf("\r\n****************************************\r\n");
+ }
+ /*获取数据*/
+ SportData *TraingModel::GetSportdata() {
+   // printf_data(sportdata);
+   return sportdata;
+ }
+ /* 设置训练数据[为训练记录准备] */
+ void TraingModel::SetSportdata(SportData *data) {
+   if (data != nullptr && sportdata != nullptr) {
+     sportdata->sportType = data->sportType;
+     sportdata->sportId = data->sportId;
+     sportdata->start_date = data->start_date;
+     sportdata->start_time = data->start_time;
+     sportdata->end_time = data->end_time;
+     sportdata->goaldegree = data->goaldegree;
+     sportdata->duration = data->duration;
+     sportdata->distance = data->distance;
+     sportdata->avgheart = data->avgheart;
+     sportdata->steps = data->steps;
+     sportdata->intensity = data->intensity;
+     sportdata->calories = data->calories;
+     sportdata->apc = data->apc;
+     sportdata->fpc = data->fpc;
+     sportdata->spc = data->spc;
+     sportdata->std = data->std;
+     sportdata->cdc = data->cdc;
+     sportdata->starttime = data->starttime; //更新开始时间
+     printf_data(data);                      //打印该运动数据
+     IsSpecialSport(sportdata->sportId);     // 配置训练特殊性
+   }
+ }
+ /*获取训练卡路里*/
+ int TraingModel::GetCal() { return sportdata->calories; }
+ /*获取训练目标*/
+ int TraingModel::GetSportTag() { return sportdata->tag; }
+ /*获取训练项目类型*/
+ ExerciseTag TraingModel::GetSportTagtype() { return sportdata->sportTagType; }
+ /*重置训练配置*/
+ void TraingModel::ResetSharedTrainingData() {
+   sportdata->Reset();    // 重置结构体
+   heartRateData.clear(); // 清空心率数据
+ 
+   ClearPaceTable();  //重置配速数据
+   ClearHeartTable(); // 清空心率数据
+ 
+   recentHeartRates.clear();
+   delayed.clear(); // 重置 delayed 字典
+ 
+   while (!maxHeap.empty()) { // 清空最大堆
+     maxHeap.pop();
+   }
+   while (!minHeap.empty()) { // 清空最小堆
+     minHeap.pop();
+   }
+ 
+   totalHeartRate = 0;
+   countHeartRate = 0;
+   heartcount = 0;
+ 
+   Gettagstuats = false; // 重置训练达标标志位
+   Openstate = true;     // 开启运动开始标志位
+ 
+   shock_count = 0; //重置震动计数
+ 
+   gpsData.clear();    // 清空gps数据
+   canvasData.clear(); // 清空画布数据
+ }
+ 
+ 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;
+   if (uapi_get_timestampe_ss(&time) != ERRCODE_SUCC) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp");
+     return;
+   }
+ 
+   ExerciseState currentState = GetSportState(); // 获取当前运动状态
+ 
+   // 增加标志位互斥保障"开始"和"结束"的唯一性操作
+   if (currentState == ExerciseState::Start && !Startstate) {
+     // 设置训练 runtime 为 1 训练中
+     uapi_dev_runtime_set_train_status(1);
+     if (Openingway) {
+       // uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_HIGH);
+     }
+ 
+     // 更新用户数据
+     SetUserSportdata();
+ 
+     ResetSharedTrainingData(); // 重置共享训练数据
+ 
+     // printf("SetTimestamp::time:%u  \r\n", time);
+     sportdata->starttime = time;
+ 
+     sportdata->sportType = sportType_; // 训练类型
+     sportdata->sportId = sportId_;
+ 
+     IsSpecialSport(sportdata->sportId); // 配置运动特殊性状态
+ 
+     if (sportTag_) // 有值才设置[训练目标]
+     {
+       sportdata->sportTagType = sportTagType_;
+       sportdata->tag = sportTag_;
+     }
+ 
+     current_goal = GetCurrentSportTag();
+ 
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "训练目标:类型: %d  值: %d 当前目标值:%d", sportTagType_,
+                   sportTag_, current_goal);
+ 
+     // 设置起始日期和时间
+     SetStartDateTime();
+ 
+     Startstate = true;
+     Endstate = false; // 确保"开始"和"结束"状态互斥
+ 
+      //打印目前运动配置项
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "*******************************");
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始运动");
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportType:%d", sportdata->sportType);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportId:%d", sportdata->sportId);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportTagType:%d", sportdata->sportTagType);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportTag:%d", sportdata->tag);
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "*******************************");
+  
+ 
+     sport_start_data_timer(300); //开启数据获取定时器 刷新频率是300ms
+ 
+ #ifdef SYSTEM_LOG_SERVICE
+     //日志记录
+     if (Openingway) {
+       uapi_save_runtime_log(RUNTIME_LOG_APP_SPORT_LAUNCH); // app发起运动
+     } else {
+       uapi_save_runtime_log(RUNTIME_LOG_DIAL_SPORT_LAUNCH); //手表发起运动
+     }
+     if (isspecialsport_) {
+       uapi_save_runtime_log(RUNTIME_LOG_SPORT_SPECIAL_START); //特殊运动
+     } else {
+       uapi_save_runtime_log(RUNTIME_LOG_SPORT_NORMAL_START); //普通运动
+     }
+ #endif
+ 
+   } else if (currentState == ExerciseState::End && !Endstate) {
+     sport_stop_data_timer(); //停止数据获取定时器
+ 
+     // 设置训练 runtime 为 0 训练结束
+     uapi_dev_runtime_set_train_status(0);
+     if (Openingway) {
+       // uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_SLOW);
+     }
+ 
+     sportdata->endtime = time;
+ 
+     SetEndTime();
+ 
+     sportState_ = ExerciseState::General;
+     Openstate = false; // 关闭运动标志位
+ 
+     // 记录运动数据
+     // RecordSportData();
+ 
+     //配置最后的训练强度(平均心率为标准)
+     SetIntensity(sportdata->avgheart);
+ 
+     //更新gps点位
+     GetPointData();
+ 
+     do_custom_fileoperate_service_check_msg(
+         CUSTOM_FILEOPERATE_MSG_TYPE_SPORTDATA_SAVE, nullptr, 0);
+ 
+     Startstate = false;
+     Endstate = true;
+ 
+     stop_heart_gps();  // 停止心率和gps数据采集
+     gnss_stop_timer(); // 停止gps定时器
+ 
+ #if 0
+        // 重置训练目标 [发生在训练前]
+        sportTag_ = 0;
+        sportTagType_ = ExerciseTag::UNKNOW;
+ #endif
+     /*运动结束并且是手表发起的运动*/
+     if (Openingway == false) {
+       sendtraningstateend();
+     }
+     /*运动结束并且是app发起的运动*/
+     else {
+       sendtraningstatedata(0, sportdata->duration);
+     }
+ 
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "结束运动");
+   }
+ }
+ /*设置开始时间*/
+ void TraingModel::SetStartDateTime() {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->[%d]\r\n",
+                 sportdata->duration);
+   std::string startDate, startTime;
+   if (!GetFormattedDate(startDate, "Failed to get start date"))
+     return;
+   if (!GetFormattedTime(startTime, "Failed to get start time"))
+     return;
+ 
+   sportdata->start_date = startDate;
+   sportdata->start_time = startTime;
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->start_time [%s]\r\n",
+                 sportdata->start_time.c_str());
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->[%d]\r\n",
+                 sportdata->duration);
+ }
+ /*设置结束时间*/
+ void TraingModel::SetEndTime() {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->[%d]\r\n",
+                 sportdata->duration);
+   std::string endTime;
+   if (GetFormattedTime(endTime, "Failed to get end time")) {
+     sportdata->end_time = endTime;
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->end_time [%s]\r\n",
+                 sportdata->end_time.c_str());
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->[%d]\r\n",
+                 sportdata->duration);
+ }
+ /*获取日期字符串*/
+ bool TraingModel::GetFormattedDate(std::string &dateOutput,
+                                    const char *errorMsg) {
+   char *date = (char *)malloc(9 * sizeof(char)); // 分配内存给start_date
+   if (uapi_get_YYMMDD_Time(date, '/') != ERRCODE_SUCC) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", errorMsg);
+     free(date);
+     return false;
+   }
+   dateOutput = std::string(date);
+   free(date); // 释放内存
+   return true;
+ }
+ /*获取时间字符串*/
+ bool TraingModel::GetFormattedTime(std::string &timeOutput,
+                                    const char *errorMsg) {
+   char *time = (char *)malloc(9 * sizeof(char)); // 分配内存给start_time
+   if (uapi_get_HHMMSS_Time(time, ':', true) != ERRCODE_SUCC) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", errorMsg);
+     free(time);
+     return false;
+   }
+   timeOutput = std::string(time);
+   free(time); // 释放内存
+   return true;
+ }
+ /*保存数据*/
+ void TraingModel::RecordSportData() {
+ #if READTEST
+   if (SaveSportData() == false) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData error!");
+   }
+ #else
+   if (MomentumFlag) {
+     // GetGoaldegree(); // 设置目标完成度
+     if (SaveSportData()) {
+       TraingRecordModel::GetInstance().SetJsonStatus(true);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData ok!");
+     } else {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData error!");
+     }
+   }
+ #endif
+ }
+ // 获取训练时长时间
+ std::string TraingModel::GetTrainingTime() {
+   int hour = sportdata->duration / NUM_TIME_HOUR;
+   int min = (sportdata->duration % NUM_TIME_HOUR) / NUM_TIME_MIN;
+   int sec = (sportdata->duration % NUM_TIME_HOUR) % NUM_TIME_MIN;
+ 
+   std::ostringstream oss;
+   oss << std::setfill('0') << std::setw(2) << hour << ":" << std::setw(2) << min
+       << ":" << std::setw(2) << sec;
+ 
+   std::string triningtime = oss.str();
+   return triningtime;
+ }
+ /*解析时间戳 返回例如:13:00:22*/
+ std::string TraingModel::AnalysisTimestamp(uint64_t timestamp) {
+   // 将时间戳转换为小时、分钟、秒
+   int hours = timestamp / 3600000;             // 1小时 = 3600000毫秒
+   int minutes = (timestamp % 3600000) / 60000; // 1分钟 = 60000毫秒
+   int seconds = (timestamp % 60000) / 1000;    // 1秒 = 1000毫秒
+ 
+   // 将小时、分钟、秒转换为字符串
+   std::string hoursStr = std::to_string(hours);
+   std::string minutesStr = std::to_string(minutes);
+   std::string secondsStr = std::to_string(seconds);
+ 
+   // 格式化输出为 HH:MM:SS
+   std::stringstream ss;
+   ss << std::setfill('0') << std::setw(2) << hoursStr << ":" << std::setw(2)
+      << minutesStr << ":" << std::setw(2) << secondsStr;
+ 
+   return ss.str();
+ }
+ int TraingModel::CalculateAverageHeartRate(int newHeartRate) {
+   // 将新的心率添加到数据列表
+   heartRateData.push_back(newHeartRate);
+   totalHeartRate += newHeartRate;
+   countHeartRate++;
+ 
+   // 将新的心率插入到堆中
+   maxHeap.push(newHeartRate);
+   minHeap.push(newHeartRate);
+ 
+   // 如果超过窗口大小,移除最早的心率
+   if (heartRateData.size() > windowSize) {
+     int oldestRate = heartRateData[0];
+     totalHeartRate -= oldestRate;
+     countHeartRate--;
+ 
+     // 将老旧值从列表中移除
+     heartRateData.erase(heartRateData.begin());
+ 
+     // 标记老旧值为待删除
+     delayed[oldestRate]++;
+   }
+ 
+   // 清理堆中的老旧值
+   while (!maxHeap.empty() && delayed[maxHeap.top()] > 0) {
+     delayed[maxHeap.top()]--;
+     maxHeap.pop();
+   }
+ 
+   while (!minHeap.empty() && delayed[minHeap.top()] > 0) {
+     delayed[minHeap.top()]--;
+     minHeap.pop();
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                 "新心率: %d, 当前心率总和: %d, 心率计数: %d", newHeartRate,
+                 totalHeartRate, countHeartRate);
+ 
+   // 如果心率数量少于 3,直接返回当前的平均值
+   if (countHeartRate < 3) {
+     return totalHeartRate / countHeartRate; // 无法去除最大最小值
+   }
+ 
+   // 取出当前未被删除的最大和最小的心率
+   int maxRate = maxHeap.top();
+   int minRate = minHeap.top();
+ 
+   // 进行去极值后的平均计算
+   int average = (totalHeartRate - maxRate - minRate) / (countHeartRate - 2);
+ 
+   // 打印计算结果
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                 "去极值后的平均心率: %d (去掉最大值: %d, 去掉最小值: %d)",
+                 average, maxRate, minRate);
+ 
+   return average;
+ }
+ // 显示心率
+ int TraingModel::CalculateFilteredHeartRate(int newHeartRate) {
+   // 将新的心率添加到最近心率列表
+   recentHeartRates.push_back(newHeartRate);
+ 
+   // 如果超过窗口大小,移除最早的心率
+   if (recentHeartRates.size() > windowSize) {
+     recentHeartRates.erase(recentHeartRates.begin());
+   }
+ 
+   // 计算当前窗口中的平均心率
+   int total =
+       std::accumulate(recentHeartRates.begin(), recentHeartRates.end(), 0);
+ 
+   // 打印当前窗口的平均心率
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "过滤后当前窗口的平均心率: %d",
+                 (total / recentHeartRates.size()));
+ 
+   return total / recentHeartRates.size(); // 返回计算后的平均值
+ }
+ int TraingModel::Averageheartrate(int newHeartRate) {
+   heartcount++;
+   totalHeartRate += newHeartRate;
+   return totalHeartRate / heartcount; // 返回计算的平均值
+ }
+ // 设置训练目标类型以及训练目标
+ void TraingModel::SetSportTag(ExerciseTag tagtpye, int tag) {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "设置目标 tagtpye[%d] tag[%d]",
+                 tagtpye, tag);
+   sportTagType_ = tagtpye;
+   sportTag_ = tag;
+ }
+ 
+ /* 设置训练强度 */
+ void TraingModel::SetIntensity(int heart) {
+   // sportdata->intensity = active_state;
+   /*
+       训练强度
+       220-年龄=最高心率
+ 
+       分为四个强度区间
+       较低强度=最高心率*59%以下
+       中等强度=最高心率*60%~69%
+       高等强度=最高心率*70%~79%
+       超高强度=最高心率*80%以上
+   */
+   // 确保最大心率为正值
+   if (user_Intensity <= 0) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "maxHeartRate %d is error",
+                   user_Intensity);
+     return;
+   }
+ 
+   // 将 heart 转换为 double 以避免整数除法
+   double heartRateAsDouble = static_cast<double>(heart);
+   double intensityPercentage =
+       (heartRateAsDouble / (double)user_Intensity) * 100;
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                 "heart: %d, maxHeartRate: %d, intensityPercentage: %.2f", heart,
+                 HeartModel, intensityPercentage);
+ 
+   if (intensityPercentage < LOW_INTENSITY_THRESHOLD) {
+     // 较低强度
+     sportdata->intensity = LOW_INTENSITY;
+   } else if (intensityPercentage >= MEDIUM_INTENSITY_LOWER_THRESHOLD &&
+              intensityPercentage <= MEDIUM_INTENSITY_UPPER_THRESHOLD) {
+     // 中等强度
+     sportdata->intensity = MEDIUM_INTENSITY;
+   } else if (intensityPercentage >= HIGH_INTENSITY_LOWER_THRESHOLD &&
+              intensityPercentage <= HIGH_INTENSITY_UPPER_THRESHOLD) {
+     // 高等强度
+     sportdata->intensity = HIGH_INTENSITY;
+   } else {
+     // 超高强度
+     sportdata->intensity = VERY_HIGH_INTENSITY;
+   }
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                 "maxHeartRate: %d, heartRate: %d, intensityPercentage: %.2f",
+                 maxHeartRate, heart, intensityPercentage);
+ }
+ /*获取训练强度STR*/
+ UIResourceTextId TraingModel::GetIntensity() {
+   switch (sportdata->intensity) {
+   case LOW_INTENSITY:
+     return UIResourceTextId::STR_LOWER_STRENGTH;
+     break;
+   case MEDIUM_INTENSITY:
+     return UIResourceTextId::STR_MEDIUM_STRENGTH;
+     break;
+   case HIGH_INTENSITY:
+     return UIResourceTextId::STR_HIGH_STRENGTH;
+     break;
+   case VERY_HIGH_INTENSITY:
+     return UIResourceTextId::STR_ULTRA_HIGH_STRENGTH;
+     break;
+   default:
+     return UIResourceTextId::STR_LOWER_STRENGTH;
+     break;
+   }
+ }
+ 
+ /*
+ 时长:10~600分钟 实际出值 秒
+ 距离:1~20km  实际出值 m
+ 步数:500~50000步 实际出值 步
+ 卡路里:100~1000kcal 实际出值 kcal
+ */
+ 
+ /* 获取当前的目标值 */
+ int TraingModel::GetSportTagData() {
+   if (sportdata->tag == 0 || current_goal == 0) {
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
+     return 0;
+   }
+ 
+   float goaldegree = 0.0f; // 初始化目标完成度
+ 
+   // 根据设置的训练目标类型去对应相对的数据
+   switch (sportdata->sportTagType) {
+   case ExerciseTag::Duration: {
+     // 计算完成度
+     goaldegree = (static_cast<float>(sportdata->duration) / current_goal) * 100;
+     break;
+   }
+   case ExerciseTag::Calories: {
+     // 计算目标完成度
+     goaldegree = (static_cast<float>(sportdata->calories) / current_goal) * 100;
+     break;
+   }
+   case ExerciseTag::Distance: {
+     // 计算目标完成度
+     goaldegree = (static_cast<float>(sportdata->distance) / current_goal) * 100;
+     break;
+   }
+   case ExerciseTag::Steps: {
+     // 计算目标完成度
+     goaldegree = (static_cast<float>(sportdata->steps) / current_goal) * 100;
+     break;
+   }
+   default:
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->sportTagType is error");
+     return 0;
+     break;
+   }
+ 
+   WEARABLE_LOGD(
+       WEARABLE_LOG_MODULE_APP,
+       " [goaldegree %d, sportdata->tag %d, sportdata->duration %d, "
+       "sportdata->calories %d,sportdata->distance %d, sportdata->steps %d]",
+       goaldegree, sportdata->tag, sportdata->duration, sportdata->calories,
+       sportdata->distance, sportdata->steps);
+ 
+   return static_cast<int>(round(goaldegree)); // 返回目标完成度
+ }
+ 
+ //获取目标值
+ uint32_t TraingModel::GetCurrentSportTag() {
+   if (sportdata->tag == 0) {
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
+     return 0;
+   }
+ 
+   float goaldegree = 0.0f; // 初始化目标完成度
+ 
+   // 根据设置的训练目标类型去对应相对的数据
+   switch (sportdata->sportTagType) {
+   case ExerciseTag::Duration: {
+     // 转换目标时长为秒
+     return static_cast<float>(sportdata->tag * 60);
+     break;
+   }
+   case ExerciseTag::Calories: {
+     // 计算目标完成度
+     return sportdata->tag;
+     break;
+   }
+   case ExerciseTag::Distance: {
+     return static_cast<float>(sportdata->tag * 1000);
+     break;
+   }
+   case ExerciseTag::Steps: {
+     return sportdata->tag;
+     break;
+   }
+   default:
+     return 0;
+     break;
+   }
+ }
+ //获取是否达到目标 使用比较
+ bool TraingModel::IsGetGoaldegree() {
+   if (sportdata->tag == 0) {
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
+     return false;
+   }
+ 
+   float goaldegree = 0.0f; // 初始化目标完成度
+ 
+   // 根据设置的训练目标类型去对应相对的数据
+   switch (sportdata->sportTagType) {
+   case ExerciseTag::Calories: {
+     // 计算目标完成度
+     if (sportdata->calories >= current_goal) {
+       return true;
+     }
+     return false;
+     break;
+   }
+   case ExerciseTag::Distance: {
+     if (sportdata->distance >= current_goal) {
+       return true;
+     }
+     return false;
+     break;
+   }
+   case ExerciseTag::Steps: {
+     if (sportdata->steps >= current_goal) {
+       return true;
+     }
+     return false;
+     break;
+   }
+   default:
+     return false;
+     break;
+   }
+ }
+ 
+ /* 获取训练目标完成百分比 */
+ int TraingModel::GetGoaldegree() {
+   if (sportdata->tag == 0) {
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
+     return 0; // 如果目标值为 0,返回 0%
+   }
+ 
+   int goaldegree = GetSportTagData();
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "goaldegree %d", goaldegree);
+   return goaldegree; // 直接返回目标完成度
+ }
+ 
+ void TraingModel::updata_goal() {
+   if (sportdata->tag == 0)
+     return;
+ 
+   sportdata->goaldegree = GetGoaldegree();
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->goaldegree %d",
+                 sportdata->goaldegree);
+ }
+ 
+ /* 训练目标校验 */
+ void TraingModel::CheckSportTag() {
+   // 运动开始才计算
+   if (sportdata->tag && sportdata->sportTagType != ExerciseTag::Duration) {
+     if (IsGetGoaldegree() && !Gettagstuats) {
+       WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "目标完成");
+       uapi_set_screen_on_api(); // 亮屏检测
+       if (!OHOS::ConfigModel::GetInstance()->GetDnotdisturb()) {
+         custom_VibratorFunc_int(0); // 震动提示
+       }
+       if (TraingCardView::GetInstance()) {
+         GraphicService::GetInstance()->PostGraphicEvent(
+             std::bind(&TraingCardView::SetPopupViewStatus,
+                       TraingCardView::GetInstance(), GetTagPopup, true));
+         auto animator = TraingCardView::GetInstance()->GetAnimator();
+         if (animator) {
+           animator->Start(); // 启动动画
+         }
+       }
+       Gettagstuats = true; // 更新状态
+     }
+   }
+ }
+ // 校验时间获取目标
+ void TraingModel::CheckTimeTag() {
+   if (sportdata->tag == 0 || sportdata->sportTagType != ExerciseTag::Duration) {
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
+     return;
+   }
+   if (sportdata->duration == current_goal && !Gettagstuats) {
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "目标完成");
+     uapi_set_screen_on_api(); // 亮屏检测
+     if (!OHOS::ConfigModel::GetInstance()->GetDnotdisturb()) {
+       custom_VibratorFunc_int(0); // 震动提示
+     }
+     if (TraingCardView::GetInstance()) {
+       GraphicService::GetInstance()->PostGraphicEvent(
+           std::bind(&TraingCardView::SetPopupViewStatus,
+                     TraingCardView::GetInstance(), GetTagPopup, true));
+       auto animator = TraingCardView::GetInstance()->GetAnimator();
+       if (animator) {
+         animator->Start(); // 启动动画
+       }
+     }
+     Gettagstuats = true; // 更新状态
+   }
+ }
+ 
+ //获取运动时长
+ int TraingModel::GetDuration() { return sportdata->duration; }
+ /*获取训练类型Id*/
+ UIResourceTextId TraingModel::GetSportTypeId(Exercisetype type) {
+   // 根据设置的训练类型去对应相对的数据
+   switch (type) {
+   // 健身类
+   case Exercisetype::FITNESS:
+     return STR_EXERCISE_LIST;
+   // 舞蹈类
+   case Exercisetype::DANCE:
+     return STR_DANCING_LIST;
+   // 休闲运动
+   case Exercisetype::LEISURE:
+     return STR_RECREATIONAL_LIST;
+   // 球类
+   case Exercisetype::BALL:
+     return STR_BALL_LIST;
+   // 水上运动
+   case Exercisetype::WATER:
+     return STR_WATER_LIST;
+   // 冰上运动
+   case Exercisetype::ICE:
+     return STR_ICE_LIST;
+   // 极限运动
+   case Exercisetype::EXTREME:
+     return STR_EXTREME_LIST;
+   // 其他
+   case Exercisetype::OTHER:
+     return STR_OTHER_LIST;
+   default:
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Not ExerciseClass type!");
+     break;
+   }
+ 
+   return STR_EXERCISE_LIST; // 添加默认返回值[健身类]
+ }
+ /*打印存储数据*/
+ void TraingModel::printTrainingData(const Trainingdata &data) {
+   printf("Trainingdata:\n");
+   printf("src: %d\n", data.src);
+   printf("bt: %u\n", data.bt);
+   printf("ty: %u\n", data.ty);
+   printf("st: %u\n", data.st);
+   printf("sp: %u\n", data.sp);
+   printf("tgt: %u\n", data.tgt);
+   printf("tg: %u\n", data.tg);
+   printf("pg: %u\n", data.pg);
+   printf("du: %u\n", data.du);
+   printf("ca: %u\n", data.ca);
+   printf("di: %u\n", data.di);
+   printf("hr: %u\n", data.hr);
+   printf("stp: %u\n", data.stp);
+   printf("ti: %u\n", data.ti);
+   printf("cir: %u\n", data.cir);
+   printf("alt: %u\n", data.alt);
+ }
+ 
+ /*
+   uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练
+   uint32_t bt;  // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4 - 水上项目,5 - 冰上项目,6 - 极限运动,7 - 其他 
+   uint32_t  ty;  //训练类型:自由训练 
+   uint32_t st;  // 开始时间戳(单位:秒)
+   uint32_t sp;  // 结束时间戳(单位:秒) 
+   uint32_t tgt; // 训练目标类型:0 - 距离,1 - 卡路里,2- 时间,3 - 步数 
+   uint32_t tg;  //训练目标值:路程(单位:米),卡路里(单位:kcal),时间(单位:分钟),步数(单位:步)
+   uint32_t pg;  // 目标完成度(单位:%)
+   uint32_t du;  // 训练总时长(单位:秒)
+   uint32_t ca;  // 消耗卡路里(单位:kcal)
+   uint32_t di;  // 完成的距离(单位:米)
+   uint32_t hr;  // 平均心率
+   uint32_t stp; // 步数
+   uint32_t ti;  // 训练强度:0 - 较低强度,1 - 中等强度,2 - 高等强度,3 - 超高强度 
+   uint32_t cir; // 圈数 
+   uint32_t alt; // 最高海拔高度
+ */
+ /*保存数据*/
+ bool TraingModel::SaveSportData() {
+ 
+   // 配置训练存储状态
+   uapi_dev_runtime_set_train_storage_status(1);
+ 
+   Trainingdata data;
+   data.src = Openingway;
+   data.bt = static_cast<uint32_t>(sportdata->sportType);
+   data.ty = static_cast<uint32_t>(GetBleSportId(sportdata->sportType, sportdata->sportId));
+   data.st = static_cast<uint32_t>(sportdata->starttime);
+   data.sp = static_cast<uint32_t>(sportdata->endtime);
+   data.tgt = static_cast<uint32_t>(sportdata->sportTagType);
+   if (sportdata->sportTagType == ExerciseTag::Distance) {
+     data.tg = static_cast<uint32_t>(sportdata->tag * 1000);
+   } else {
+     data.tg = static_cast<uint32_t>(sportdata->tag);
+   }
+   data.pg = static_cast<uint32_t>(sportdata->goaldegree);
+   data.du = static_cast<uint32_t>(sportdata->duration);
+   data.ca = static_cast<uint32_t>(sportdata->calories * 10);
+   data.di = static_cast<uint32_t>(sportdata->distance);
+   data.hr = static_cast<uint32_t>(sportdata->avgheart);
+   data.stp = static_cast<uint32_t>(sportdata->steps);
+   data.ti = static_cast<uint32_t>(sportdata->intensity);
+   /* 230 目前不支持【圈数】【最高海拔高度】 */
+   data.cir = 0;
+   data.alt = 0;
+   /* 配速相关 */
+   data.apc = static_cast<uint32_t>(sportdata->apc);
+   data.fpc = static_cast<uint32_t>(sportdata->fpc);
+   data.spc = static_cast<uint32_t>(sportdata->spc);
+   data.std = static_cast<uint32_t>(sportdata->std);
+   data.cdc = static_cast<uint32_t>(sportdata->cdc);
+ 
+   // 创建sport文件夹
+   CreateDirectoryIfNotExists(TRAINING_DATA_DIRECTORY);
+ 
+   // 保存数据到 bin
+   if (write_Trainingdata_data(data) != 1) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "write_Trainingdata_data is error!");
+     uapi_dev_runtime_set_train_storage_status(0); // 恢复状态
+     return false;
+   }
+ 
+   // 保存数据到 json
+   if (!SaveDataToJson(sportdata)) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDataToJson is error!");
+     uapi_dev_runtime_set_train_storage_status(0); // 恢复状态
+     return false;
+   }
+ 
+   if (isspecialsport_) {
+     // 保存心率表
+     if (!SaveHeartTable()) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveHeartRateData is error!");
+       // uapi_dev_runtime_set_train_storage_status(0); // 恢复状态
+       // return false;
+     }
+     // 保存速度表
+     if (!SavePaceTable()) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSpeedData is error!");
+       // return false;
+     }
+     // 保存GPS数据
+     if (!SaveCanvasData()) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveCanvasData is error!");
+       // return false; 
+     }
+     if (!SaveGPSData()) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData is error!");
+       // return false;
+     }
+   }
+ 
+   // 如果所有操作成功,则恢复训练存储状态
+   uapi_dev_runtime_set_train_storage_status(0);
+   return true;
+ }
+ /*设置进入方式*/
+ void TraingModel::SetEntryType(ENTEYTYPE type) { entey_type = type; }
+ /*获取进入方式*/
+ ENTEYTYPE TraingModel::GetEntryType() { return entey_type; }
+ /*设置开启方式*/
+ void TraingModel::SetSportOpenWay(bool way) { Openingway = way; }
+ /*设置运动是否开始*/
+ void TraingModel::SetSportOpenState(bool state) { Openstate = state; }
+ /*获取运动是否开始*/
+ bool TraingModel::GetSportOpenState() { return Openstate; }
+ /*获取运动时长*/
+ uint32_t TraingModel::GetSportTime() { return sportdata->duration; }
+ /*获取训练量是否达标*/
+ bool TraingModel::GetMomentum() {
+ #if 0
+          int caldata = TraingModel::GetInstance()->GetCal();
+          /*判断是否产生至少1Kcald的运动量*/
+          if (caldata >= 1)
+          {
+              MomentumFlag = true;
+          }
+          else
+          {
+              MomentumFlag = false;
+          }
+ #endif
+   int duration = sportdata->duration;
+   //判断运动时间是否大于1分钟
+   if (duration >= 60) {
+     MomentumFlag = true;
+   } else {
+     MomentumFlag = false;
+   }
+   return MomentumFlag;
+ }
+ 
+ //用户运动数据配置
+ void TraingModel::SetUserSportdata() {
+   // 获取用户的最高心率提醒
+   user_maxHeart = ConfigModel::GetInstance()->get_configData_int(
+       ConfigModel::CONFIGMODEL_ITEM_TRAINING_HEART_MAX);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "用户最高心率提醒: %d", user_maxHeart);
+ 
+   // 获取用户年龄
+   user_Age = ConfigModel::GetInstance()->GetUserAge();
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "用户年龄: %d", user_Age);
+ 
+   // 获取自动训练设置
+   user_autoget = ConfigModel::GetInstance()->get_configData_int(
+       ConfigModel::CONFIGMODEL_ITEM_TRANING_AUTO);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "自动获取设置: %d", user_autoget);
+ 
+   // 获取训练频率设置
+   user_freq = ConfigModel::GetInstance()->get_configData_int(
+       ConfigModel::CONFIGMODEL_ITEM_TRANING_FREQ);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "训练频率: %d", user_freq);
+ 
+   user_Intensity = MAX_HEART_RATE_TRAINING - user_Age;
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "用户运动强度心率: %d",
+                 user_Intensity);
+ }
+ //运动过程中更新心率配置
+ void TraingModel::SetMaxHeart(int maxheart) {
+   // 获取用户运动数据配置
+   user_maxHeart = maxheart;
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "用户最高心率: %d", user_maxHeart);
+ }
+ /*配速表与心率表相关*/
+ //清空心率表
+ void TraingModel::ClearHeartTable() {
+   heartRateTable.clear(); // 清空心率数据表
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Heart Rate Table Cleared.\r\n");
+ }
+ //清空配速表
+ void TraingModel::ClearPaceTable() {
+   paceTable.clear(); // 清空配速数据表
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Pace Table Cleared.\r\n");
+ }
+ // 添加心率数据
+ bool TraingModel::AddHeartRateData(uint32_t timestamp, uint8_t heartRate) {
+   // 检查重复时间戳
+   for (const auto &entry : heartRateTable) {
+     if (entry.timestamp == timestamp) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "时间戳重复无法添加数据 AddHeartRateData is error!");
+       return false; // 返回重复
+     }
+   }
+ 
+   if (heartRateTable.size() >= MAX_ENTRIES) {
+     WEARABLE_LOGE(
+         WEARABLE_LOG_MODULE_APP,
+         "达到最大心率数据条目限制 无法添加新的数据 AddHeartRateData is error!");
+     return false; // 返回条目满了
+   }
+ 
+   HeartRateEntry newEntry = {timestamp, heartRate};
+   heartRateTable.push_back(newEntry);
+   return true; // 返回成功
+ }
+ 
+ // 添加配速数据
+ bool TraingModel::AddPaceData(uint32_t timestamp, uint16_t pace) {
+   // 检查重复时间戳
+   for (const auto &entry : paceTable) {
+     if (entry.timestamp == timestamp) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "时间戳重复无法添加数据 AddPaceData is error!"); // 修正这里
+       return false; // 返回重复
+     }
+   }
+ 
+   if (paceTable.size() >= MAX_ENTRIES) {
+     WEARABLE_LOGE(
+         WEARABLE_LOG_MODULE_APP,
+         "达到配速数据条目限制 无法添加新的数据 AddPaceData is error!");
+     return false; // 返回条目满了
+   }
+ 
+   PaceEntry newEntry = {timestamp, pace};
+   paceTable.push_back(newEntry);
+   return true; // 返回成功
+ }
+ //心率表打印
+ void TraingModel::PrintHeartRateTable() {
+   size_t heartRateCount = heartRateTable.size();
+   if (heartRateCount == 0) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "心率表为空,无法打印。");
+     return;
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Heart Rate Table:");
+   for (const auto &entry : heartRateTable) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "时间戳: %u, 心率: %d",
+                   entry.timestamp, entry.heartRate);
+   }
+ }
+ //配速表打印
+ void TraingModel::PrintPaceTable() {
+   size_t paceCount = paceTable.size();
+   if (paceCount == 0) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配速表为空,无法打印。");
+     return;
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Pace Table:");
+   for (const auto &entry : paceTable) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "时间戳: %u, 配速: %d",
+                   entry.timestamp, entry.pace);
+   }
+ }
+ // 保存心率表
+ bool TraingModel::SaveHeartTable() {
+ 
+   //打印数组
+   PrintHeartRateTable();
+ 
+   CreateDirectoryIfNotExists(TRAINING_HEART_FILE);
+ 
+   size_t heartRateCount = heartRateTable.size();
+   if (heartRateCount == 0) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "心率表为空,无法保存。");
+     return false;
+   }
+ 
+   std::string filePath =
+       TRAINING_HEART_FILE + std::to_string(sportdata->starttime) + ".bin";
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveHeartTable filePath: %s",
+                 filePath.c_str());
+   std::ofstream heartRateFile(filePath, std::ios::binary);
+   if (!heartRateFile) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
+                   filePath.c_str());
+     return false; // 返回失败
+   }
+ 
+   // 存储表数据
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heartRateCount = %d", heartRateCount);
+   if (!heartRateFile.write(
+           reinterpret_cast<const char *>(heartRateTable.data()),
+           heartRateCount * sizeof(HeartRateEntry))) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入心率数据失败。");
+     return false; // 返回失败
+   }
+ 
+   heartRateFile.close();
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Heart Rate Table Saved.");
+   return true; // 返回成功
+ }
+ 
+ // 保存配速表
+ bool TraingModel::SavePaceTable() {
+ 
+   //打印数组
+   PrintPaceTable();
+ 
+   CreateDirectoryIfNotExists(TRAINING_PACE_FILE);
+ 
+   size_t paceCount = paceTable.size();
+   if (paceCount == 0) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配速表为空,无法保存。");
+     return false;
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "paceCount = %d", paceCount);
+ 
+   std::string filePath =
+       TRAINING_PACE_FILE + std::to_string(sportdata->starttime) + ".bin";
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SavePaceTable filePath: %s",
+                 filePath.c_str());
+ 
+   std::ofstream paceFile(filePath, std::ios::binary);
+   if (!paceFile) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
+                   filePath.c_str());
+     return false; // 返回失败
+   }
+   // 写入配速数据
+   if (!paceFile.write(reinterpret_cast<const char *>(paceTable.data()),
+                       paceCount * sizeof(PaceEntry))) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入配速数据失败。");
+     return false; // 返回失败
+   }
+ 
+   paceFile.close();
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SavePaceTable Success.");
+   return true; // 返回成功
+ }
+ // 返回心率表路径
+ std::string TraingModel::GetHeartTablePath(uint32_t timestamp) {
+   // 首先检查完全匹配的时间戳
+   std::string exactFilePath =
+       TRAINING_HEART_FILE + std::to_string(timestamp) + ".bin";
+   if (IsFileAccessibleAndNotEmpty(exactFilePath)) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到心率表: %s",
+                   exactFilePath.c_str());
+     return exactFilePath; // 返回完全匹配的文件路径
+   }
+ 
+   // 如果未找到,检查时间戳相差1到2秒的文件
+   for (int i = -2; i <= 2; ++i) {
+     uint32_t checkTimestamp = timestamp + i;
+     std::string filePath =
+         TRAINING_HEART_FILE + std::to_string(checkTimestamp) + ".bin";
+     if (IsFileAccessibleAndNotEmpty(filePath)) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到心率表: %s",
+                     filePath.c_str());
+       return filePath; // 返回找到的文件路径
+     }
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的心率表。");
+   return ""; // 未找到文件
+ }
+ 
+ // 返回配速表路径
+ std::string TraingModel::GetPaceTablePath(uint32_t timestamp) {
+   // 首先检查完全匹配的时间戳
+   std::string exactFilePath =
+       TRAINING_PACE_FILE + std::to_string(timestamp) + ".bin";
+   if (IsFileAccessibleAndNotEmpty(exactFilePath)) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到配速表: %s",
+                   exactFilePath.c_str());
+     return exactFilePath; // 返回完全匹配的文件路径
+   }
+ 
+   // 如果未找到,检查时间戳相差1到2秒的文件
+   for (int i = -2; i <= 2; ++i) {
+     uint32_t checkTimestamp = timestamp + i;
+     std::string filePath =
+         TRAINING_PACE_FILE + std::to_string(checkTimestamp) + ".bin";
+     if (IsFileAccessibleAndNotEmpty(filePath)) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到配速表: %s",
+                     filePath.c_str());
+       return filePath; // 返回找到的文件路径
+     }
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的配速表。");
+   return ""; // 未找到文件
+ }
+ /*发送实时数据*/
+ void TraingModel::SendLiveData() {
+ #ifdef SUPPORT_BLE_SERVICE
+   msg_get_train_data_info_t data;
+   memset(&data, 0, sizeof(msg_get_train_data_info_t));
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->starttime %d \r\n",
+                 sportdata->starttime);
+   data.st = sportdata->starttime;
+   data.hr = sportdata->heart;
+   data.ca = sportdata->calories * 10; // app端需要乘10
+   data.di = sportdata->distance;
+   data.stp = sportdata->steps;
+   data.ti = sportdata->intensity;
+   data.pc = sportdata->pc;
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SendLiveData Begin!");
+   sendtraningdata(&data); // 发送数据函数
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SendLiveData Stop!");
+ #endif
+ }
+ /* -------------------------------- 运动识别发起处理
+  * -------------------------------- */
+ void TraingModel::set_sport_config(UIResourceTextId id) {
+   if (id >= MAXSPORTID) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "id is error");
+     return;
+   }
+   // 开始训练 ->不返回
+   NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGCRAD);
+   // 配置运动项
+   SetSportEvent(id);
+   // 获取运动项目
+   ExerciseClass type = GetSportId();
+   // 开启对应的运动
+   TraingCardPresenter::GetInstance()->OpenSensor(type);
+   // 设置为手表开启运动
+   SetSportOpenWay(false);
+ }
+ 
+ /* -------------------------------------------------------------------------- */
+ 
+ #include <chrono>
+ #include <iomanip>
+ #include <sstream>
+ #include <string>
+ 
+ std::string TraingModel::DisplayMotionDuration() {
+   // 清空 motionDuration
+   motionDuration.clear();
+ 
+   // 重置运动次数
+   if (g_motionTimes >= NUM_TIME_DAY) {
+     g_motionTimes = 0;
+   }
+ 
+   // 计算和格式化运动时长
+   int hours = g_motionTimes / NUM_TIME_HOUR;
+   int minutes = (g_motionTimes % NUM_TIME_HOUR) / NUM_TIME_MIN;
+   int seconds = g_motionTimes % NUM_TIME_MIN;
+ 
+   std::ostringstream oss;
+   oss << std::setfill('0') << std::setw(2) << hours << ":" << std::setw(2)
+       << minutes << ":" << std::setw(2) << seconds;
+ 
+   motionDuration = oss.str();
+ 
+   // // 获取当前时间(以微秒为单位)
+   // uint32_t currentTime = static_cast<uint32_t>(
+   //     std::chrono::duration_cast<std::chrono::microseconds>(
+   //         std::chrono::system_clock::now().time_since_epoch())
+   //         .count());
+ 
+   // // 记录和检查上一次调用的时间
+   // static uint32_t lastCallTime = 0;
+   // if (currentTime - lastCallTime < 1000000) { // 小于1秒
+   //   return motionDuration;
+   // }
+   // lastCallTime = currentTime; // 更新最后调用时间
+ 
+   // 如果 g_motionTimes 不为零,进行计算和数据存储
+   if (g_motionTimes > 0) {
+     sportdata->duration = g_motionTimes; // 设置训练时长
+ 
+     // 每分钟进行配速和心率数据存储
+     // StoreDataIfMinutePassed();
+   }
+ 
+   return motionDuration; // 返回格式化的运动时长
+ }
+ 
+ // 检查并发送实时数据
+ void TraingModel::SendLiveDataIfNecessary() {
+   // 检查自动获取的配置 app发起
+   if (user_autoget && Openingway) {
+     // 发送实时数据
+     if (g_motionTimes % user_freq == 0) {
+       WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SendLiveData is OK\r\n");
+       SendLiveData(); // 发送实时数据
+     }
+   }
+ }
+ 
+ // 每5秒进行配速和心率数据存储
+ void TraingModel::StoreDataIfMinutePassed() {
+   if (sportdata->duration % 5 == 0) {
+     uint32_t timestamp;
+     //进行数据的筛选
+     if (uapi_get_timestampe_ss(&timestamp) == ERRCODE_SUCC) {
+       if (sportdata->heart != 0)
+         AddHeartRateData(timestamp, sportdata->heart);
+       if (sportdata->apc != 0)
+         AddPaceData(timestamp, sportdata->apc);
+     }
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "duration:[%d] g_motionTimes[%d]\r\n",
+                 sportdata->duration, g_motionTimes);
+ }
+ #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(void) {
+   // 只在活动状态下进行更新
+ 
+   if (pauseStartTimestamp == 0) {
+     //开始时将该值设置为运动开始值
+     pauseStartTimestamp = sportdata->starttime;
+   }
+ 
+   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++;
+     custom_VibratorFunc_int(0); // 触发振动反馈
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "触发了振动。振动计数: %d",
+                   shock_count);
+   }
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingTimerCallback 被执行。");
+ }
+ 
+ /* 启动定时器 */
+ void StartTimer(void) {
+   if (g_startCounting != NULL) {
+     LogError("定时器已经存在", osError);
+     return;
+   }
+ 
+   g_startCounting = osTimerNew((osTimerFunc_t)TraingTimerCallback,
+                                osTimerPeriodic, NULL, NULL);
+   if (g_startCounting == NULL) {
+     LogError("定时器创建失败", osError);
+     return;
+   }
+ 
+   int tick = osMs2Tick(MS_ONE_SECONDS);
+   osStatus_t retTimer = osTimerStart(g_startCounting, tick);
+   if (retTimer != osOK) {
+     LogError("定时器启动失败", retTimer);
+     osTimerDelete(g_startCounting);
+     g_startCounting = NULL;
+   }
+ }
+ 
+ /* 停止并重置定时器 */
+ void StopAndResetTimer(void) {
+   if (g_startCounting != NULL) {
+     osTimerStop(g_startCounting);
+     osStatus_t ret = osTimerDelete(g_startCounting);
+     if (ret != osOK) {
+       LogError("定时器删除失败", ret);
+     }
+     g_startCounting = NULL;
+     g_motionTimes = 0;
+     pauseStartTimestamp = 0;
+     totalPausedDuration = 0; // 重置总暂停时长
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已停止并重置。");
+   }
+ }
+ 
+ /* 暂停定时器 */
+ void PauseTimer(void) {
+   if (g_startCounting != NULL) {
+     osTimerStop(g_startCounting);
+ 
+     totalPausedDuration = sportdata->duration; //记录暂停前的时间;后续加上
+ 
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已暂停。暂停开始时间戳: %u",
+                   pauseStartTimestamp);
+   }
+ }
+ 
+ /* 恢复定时器 */
+ void ResumeTimer(void) {
+   if (g_startCounting != NULL) {
+ 
+     uint32_t currentTimestamp =
+         OHOS::TraingModel::GetInstance()->get_current_time(); // 获取当前时间戳
+     pauseStartTimestamp = currentTimestamp; // 保存暂停开始的时间戳 将这个更新
+ 
+     int tick = osMs2Tick(MS_ONE_SECONDS);
+     if (osTimerStart(g_startCounting, tick) != osOK) {
+       LogError("恢复定时器时启动失败", osError);
+     }
+ 
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已恢复。当前运动时间: %u %d",
+                   g_motionTimes, pauseStartTimestamp);
+   }
+ }
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ /* ---------------------------------- 数据存储
+  * ---------------------------------- */
+ static int32 SaveTraingDataToFile(void) {
+   time_t now = time(nullptr);
+   struct tm *timeinfo = localtime(&now);
+   char filename[20];
+   strftime(filename, sizeof(filename), "%Y%m%d.bin", timeinfo);
+ 
+   uint32 size = sizeof(Trainingdata);
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SaveTraingDataToFile !!");
+ 
+   char filePath[20];
+   sprintf(filePath, "%s%s", TRAINING_DATA_DIRECTORY, filename);
+ 
+   std::ofstream fd(filePath, std::ios::binary);
+   if (!fd.is_open()) {
+     if (mkdir(TRAINING_DATA_DIRECTORY, S_IRWXU) != 0) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create directory");
+       return 0;
+     }
+ 
+     fd.open(filePath, std::ios::binary);
+     if (!fd.is_open()) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for write");
+       return 0;
+     }
+ 
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory created successfully!!");
+   }
+ 
+   fd.write(reinterpret_cast<const char *>(&sportdata), size);
+   fd.close();
+   return 1;
+ }
+ static std::vector<Trainingdata> LoadTrainingDataFromTodayFile() {
+   std::vector<Trainingdata> trainingRecords;
+ 
+   time_t now = time(nullptr);
+   struct tm *timeinfo = localtime(&now);
+   char filename[20];
+   strftime(filename, sizeof(filename), "%Y%m%d.bin", timeinfo);
+   // 找到训练文件夹里面的当天文件
+   char filePath[20];
+   sprintf(filePath, "%s%s", TRAINING_DATA_DIRECTORY, filename);
+ 
+   std::ifstream fd(filePath, std::ios::binary);
+   if (!fd.is_open()) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open today's file");
+     return trainingRecords; // Return an empty vector if file open fails
+   }
+ 
+   // 读取训练信息
+   while (!fd.eof()) {
+     Trainingdata record;
+     fd.read(reinterpret_cast<char *>(&record), sizeof(Trainingdata));
+     if (fd.gcount() == sizeof(Trainingdata)) {
+       trainingRecords.push_back(record);
+     }
+   }
+ 
+   fd.close();
+ 
+   return trainingRecords;
+ }
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ 
+ #include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/stat.h>
+ 
+ // 获得数据个数
+ static int get_Trainingdata_data_num(FILE *fp) {
+   if (fp == NULL) {
+     return 0; // 如果文件指针为空,返回0
+   }
+ 
+   fseek(fp, 0, SEEK_END); // 将文件指针移动到文件末尾
+   long size = ftell(fp);  // 获取当前文件指针位置,即文件大小
+   fseek(fp, 0, SEEK_SET); // 将文件指针移回文件开头
+ 
+   return (size / sizeof(Trainingdata));
+ }
+ 
+ // 写训练bin文件
+ int write_Trainingdata_data(Trainingdata data) {
+   char file_path[MAX_FILE_PATH_LENGTH] = {0};
+   char timeday[12] = {0};
+   uapi_get_YYMMDD_Time(timeday, '_');
+   snprintf(file_path, sizeof(file_path), "%s%s.bin", TRAINING_PATH, timeday);
+ 
+   // 检查目录是否存在,如果不存在则创建
+   struct stat st = {0};
+   if (stat(TRAINING_PATH, &st) == -1) {
+     if (mkdir(TRAINING_PATH, 0700) != 0) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create directory: %s",
+                     strerror(errno));
+       return -1; // 返回错误码
+     }
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", file_path);
+   FILE *fp = fopen(file_path, "ab+");
+   if (fp == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for append: %s",
+                   strerror(errno));
+     fp = fopen(file_path, "wb+");
+     if (fp == NULL) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "Failed to open file for write: %s", strerror(errno));
+       return -1; // 返回错误码
+     }
+   }
+ 
+   int ret = fwrite((void *)&data, sizeof(Trainingdata), 1, fp);
+   if (ret != 1) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "fwrite_data error! %d", ret);
+     fclose(fp);
+     return -1; // 返回错误码
+   }
+ 
+   fclose(fp); // 关闭文件
+   return 1;   // 返回成功码
+ }
+ 
+ // 读数据
+ Trainingdata *read_Trainingdata_data(char *timedata, uint16_t offset) {
+   char file_path[128] = {0};
+   snprintf(file_path, sizeof(file_path), "%s%s.bin", TRAINING_PATH, timedata);
+ 
+   FILE *fp = fopen(file_path, "rb");
+   if (fp == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for read: %s",
+                   strerror(errno));
+     return NULL;
+   }
+ 
+   Trainingdata *data = (Trainingdata *)malloc(sizeof(Trainingdata));
+   if (data == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "Failed to allocate memory for Trainingdata");
+     fclose(fp);
+     return NULL;
+   }
+ 
+   int num_data = get_Trainingdata_data_num(fp);
+   if (num_data <= offset) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "Offset %d exceeds number of data %d", offset, num_data);
+     free(data); // 释放内存
+     fclose(fp);
+     return NULL;
+   }
+ 
+   fseek(fp, sizeof(Trainingdata) * offset, SEEK_SET);
+   fread(data, sizeof(Trainingdata), 1, fp);
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Data src: %d", data->src);
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Offset: %d, Size: %zu", offset,
+                 sizeof(Trainingdata));
+ 
+   fclose(fp);  // 关闭文件
+   return data; // 返回读取的数据
+ }
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ /* -------------------------------------------------------------------------- */
+ /*检查是否存在数据*/
+ bool TraingModel::CheckDataJson() {
+   // 读取record.json文件
+   std::ifstream file(TRAINING_RECORD_FILE);
+ 
+   // 检查文件是否打开成功
+   if (!file.is_open()) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unable to open file");
+     return false;
+   }
+ 
+   // 检查文件是否为空
+   file.seekg(0, std::ios::end);
+   if (file.tellg() == 0) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File is empty");
+     file.close();
+     return false;
+   }
+ 
+   // 解析json
+   std::vector<SportData> sportDataVector;
+   if (!LoadDataFormJson(sportDataVector)) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDataFormJson is error");
+     file.close();
+     return false;
+   }
+ 
+   // 关闭文件
+   file.close();
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckDataJson is ok");
+   return true;
+ }
+ 
+ bool TraingModel::SaveDataToJson(SportData *data) {
+   FILE *fp;
+   char *jsonStr = NULL;
+ 
+   // 读取现有的 JSON 数据
+   fp = fopen(TRAINING_RECORD_FILE, "r");
+   cJSON *data_root = NULL;
+   cJSON *dataArray = NULL;
+ 
+   if (fp != NULL) {
+     fseek(fp, 0, SEEK_END);
+     long fileSize = ftell(fp);
+     fseek(fp, 0, SEEK_SET);
+ 
+     jsonStr = (char *)malloc(fileSize + 1);
+     if (jsonStr != nullptr) {
+       if (fread(jsonStr, fileSize, 1, fp) == 1) {
+         data_root = cJSON_Parse(jsonStr);
+         if (data_root != NULL) {
+           dataArray = cJSON_GetObjectItem(data_root, "data");
+         }
+       }
+     }
+     fclose(fp);
+   }
+ 
+   if (dataArray == NULL) {
+     data_root = cJSON_CreateObject();
+     cJSON_AddItemToObject(data_root, "data", cJSON_CreateArray());
+     dataArray = cJSON_GetObjectItem(data_root, "data");
+   }
+ 
+   // 创建或更新数据节点
+   cJSON *sportData = cJSON_CreateObject();
+   cJSON_AddNumberToObject(sportData, "sportTypeId",
+                           int(data->sportType)); // 训练项目类 Id
+   cJSON_AddNumberToObject(sportData, "sportId", data->sportId); // 训练项目 Id
+   cJSON_AddStringToObject(sportData, "startDate",
+                           (data->start_date).c_str()); // 训练开始日期字符串
+   cJSON_AddStringToObject(sportData, "startTime",
+                           (data->start_time).c_str()); // 训练开始时间
+   cJSON_AddStringToObject(sportData, "endTime",
+                           (data->end_time).c_str()); // 训练结束时间
+   cJSON_AddNumberToObject(sportData, "goalDegree",
+                           data->goaldegree); // 训练目标完成度
+   cJSON_AddNumberToObject(sportData, "duration",
+                           data->duration); // 训练时长(秒)
+   cJSON_AddNumberToObject(sportData, "distance", data->distance); // 训练距离
+   cJSON_AddNumberToObject(sportData, "avgHeartRate",
+                           data->avgheart); // 训练平均心率
+   cJSON_AddNumberToObject(sportData, "steps", data->steps); // 训练步数
+   cJSON_AddNumberToObject(sportData, "intensity", data->intensity); // 训练强度
+   cJSON_AddNumberToObject(sportData, "apc", data->apc); // 训练平均配速
+   cJSON_AddNumberToObject(sportData, "cdc", data->cdc); // 训练步频
+   cJSON_AddNumberToObject(sportData, "std", data->std); // 训练步幅
+   cJSON_AddNumberToObject(sportData, "calories", data->calories); //卡路里
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "starttime is %d", data->starttime);
+   cJSON_AddNumberToObject(sportData, "start_time",
+                           data->starttime); // 开始时间戳
+ 
+   // 添加运动数据节点到数组并限制数量
+   cJSON_AddItemToArray(dataArray, sportData);
+   while (cJSON_GetArraySize(dataArray) > MAX_DATA_COUNT) {
+     cJSON_DeleteItemFromArray(dataArray, 0);
+   }
+ 
+   // 将更新后的 JSON 数据写入文件
+   char *jsonStrNew = cJSON_Print(data_root);
+   fp = fopen(TRAINING_RECORD_FILE, "w");
+   if (fp != NULL) {
+     fwrite(jsonStrNew, strlen(jsonStrNew), 1, fp);
+     fclose(fp);
+   }
+ 
+   // 释放资源
+   cJSON_Delete(data_root);
+   free(jsonStr);
+   cJSON_free(jsonStrNew);
+ 
+   return true;
+ }
+ 
+ /* 加载训练数据函数 */
+ /* 加载训练数据函数 */
+ bool TraingModel::LoadDataFormJson(std::vector<SportData> &sportDataVector) {
+   // 清空输出向量,避免旧数据干扰
+   sportDataVector.clear();
+ 
+   // 打开JSON文件
+   std::ifstream file(TRAINING_RECORD_FILE);
+   if (!file.is_open()) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file: %s",
+                   TRAINING_RECORD_FILE);
+     return false;
+   }
+ 
+   // 读取文件内容到字符串
+   std::string jsonData((std::istreambuf_iterator<char>(file)),
+                        std::istreambuf_iterator<char>());
+   file.close();
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Read %zu bytes from JSON file",
+                 jsonData.size());
+ 
+   // 解析JSON根对象
+   cJSON *root = cJSON_Parse(jsonData.c_str());
+   if (root == NULL) {
+     const char *errorPtr = cJSON_GetErrorPtr();
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse JSON: %s",
+                   errorPtr ? errorPtr : "Unknown error");
+     return false;
+   }
+ 
+   // 查找并验证data数组
+   cJSON *dataArray = cJSON_GetObjectItem(root, "data");
+   if (dataArray == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing 'data' array in JSON");
+     cJSON_Delete(root);
+     return false;
+   }
+   if (!cJSON_IsArray(dataArray)) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "'data' is not an array in JSON");
+     cJSON_Delete(root);
+     return false;
+   }
+ 
+   // 检查数组大小
+   int dataCount = cJSON_GetArraySize(dataArray);
+   if (dataCount == 0) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Empty 'data' array in JSON");
+     cJSON_Delete(root);
+     return false;
+   }
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Found %d items in 'data' array",
+                 dataCount);
+ 
+   // 遍历解析每个数据项
+   for (int i = 0; i < dataCount; i++) {
+     cJSON *item = cJSON_GetArrayItem(dataArray, i);
+     if (item == NULL) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "Null item at index %d in 'data' array", i);
+       continue; // 跳过无效项,继续处理其他项
+     }
+ 
+     SportData sportData;
+     bool isValid = true;
+     std::string missingFields; // 记录缺失的字段
+ 
+     // 解析sportTypeId字段
+     if (cJSON *sportTypeIdItem = cJSON_GetObjectItem(item, "sportTypeId")) {
+       if (cJSON_IsNumber(sportTypeIdItem)) {
+         sportData.sportType = (Exercisetype)sportTypeIdItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "sportTypeId ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "sportTypeId ";
+     }
+ 
+     // 解析sportId字段
+     if (cJSON *sportIdItem = cJSON_GetObjectItem(item, "sportId")) {
+       if (cJSON_IsNumber(sportIdItem)) {
+         sportData.sportId = (UIResourceTextId)sportIdItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "sportId ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "sportId ";
+     }
+ 
+     // 解析startDate字段
+     if (cJSON *startDateItem = cJSON_GetObjectItem(item, "startDate")) {
+       if (cJSON_IsString(startDateItem) && startDateItem->valuestring) {
+         sportData.start_date = startDateItem->valuestring;
+       } else {
+         isValid = false;
+         missingFields += "startDate ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "startDate ";
+     }
+ 
+     // 解析startTime字段
+     if (cJSON *startTimeItem = cJSON_GetObjectItem(item, "startTime")) {
+       if (cJSON_IsString(startTimeItem) && startTimeItem->valuestring) {
+         sportData.start_time = startTimeItem->valuestring;
+       } else {
+         isValid = false;
+         missingFields += "startTime ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "startTime ";
+     }
+ 
+     // 解析endTime字段
+     if (cJSON *endTimeItem = cJSON_GetObjectItem(item, "endTime")) {
+       if (cJSON_IsString(endTimeItem) && endTimeItem->valuestring) {
+         sportData.end_time = endTimeItem->valuestring;
+       } else {
+         isValid = false;
+         missingFields += "endTime ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "endTime ";
+     }
+ 
+     // 解析goalDegree字段
+     if (cJSON *goalDegreeItem = cJSON_GetObjectItem(item, "goalDegree")) {
+       if (cJSON_IsNumber(goalDegreeItem)) {
+         sportData.goaldegree = goalDegreeItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "goalDegree ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "goalDegree ";
+     }
+ 
+     // 解析duration字段
+     if (cJSON *durationItem = cJSON_GetObjectItem(item, "duration")) {
+       if (cJSON_IsNumber(durationItem)) {
+         sportData.duration = durationItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "duration ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "duration ";
+     }
+ 
+     // 解析distance字段
+     if (cJSON *distanceItem = cJSON_GetObjectItem(item, "distance")) {
+       if (cJSON_IsNumber(distanceItem)) {
+         sportData.distance = distanceItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "distance ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "distance ";
+     }
+ 
+     // 解析avgHeartRate字段
+     if (cJSON *avgHeartRateItem = cJSON_GetObjectItem(item, "avgHeartRate")) {
+       if (cJSON_IsNumber(avgHeartRateItem)) {
+         sportData.avgheart = avgHeartRateItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "avgHeartRate ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "avgHeartRate ";
+     }
+ 
+     // 解析steps字段
+     if (cJSON *stepsItem = cJSON_GetObjectItem(item, "steps")) {
+       if (cJSON_IsNumber(stepsItem)) {
+         sportData.steps = stepsItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "steps ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "steps ";
+     }
+ 
+     // 解析intensity字段
+     if (cJSON *intensityItem = cJSON_GetObjectItem(item, "intensity")) {
+       if (cJSON_IsNumber(intensityItem)) {
+         sportData.intensity = intensityItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "intensity ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "intensity ";
+     }
+ 
+     // 解析apc字段
+     if (cJSON *apcItem = cJSON_GetObjectItem(item, "apc")) {
+       if (cJSON_IsNumber(apcItem)) {
+         sportData.apc = apcItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "apc ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "apc ";
+     }
+ 
+     // 解析cdc字段
+     if (cJSON *cdcItem = cJSON_GetObjectItem(item, "cdc")) {
+       if (cJSON_IsNumber(cdcItem)) {
+         sportData.cdc = cdcItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "cdc ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "cdc ";
+     }
+ 
+     // 解析std字段
+     if (cJSON *stdItem = cJSON_GetObjectItem(item, "std")) {
+       if (cJSON_IsNumber(stdItem)) {
+         sportData.std = stdItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "std ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "std ";
+     }
+ 
+     // 解析calories字段
+     if (cJSON *caloriesItem = cJSON_GetObjectItem(item, "calories")) {
+       if (cJSON_IsNumber(caloriesItem)) {
+         sportData.calories = caloriesItem->valueint;
+       } else {
+         isValid = false;
+         missingFields += "calories ";
+       }
+     } else {
+       isValid = false;
+       missingFields += "calories ";
+     }
+ 
+     // 解析starttime字段(时间戳)
+     if (cJSON *starttimeItem = cJSON_GetObjectItem(item, "start_time")) {
+       WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Found starttime field. Type: %d",
+                     starttimeItem->type);
+       if (cJSON_IsNumber(starttimeItem)) {
+         sportData.starttime = starttimeItem->valueint;
+         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Parsed starttime: %d",
+                       sportData.starttime);
+       } else {
+         // 打印详细信息,帮助定位问题
+         const char *valueStr =
+             starttimeItem->valuestring ? starttimeItem->valuestring : "null";
+         WEARABLE_LOGE(
+             WEARABLE_LOG_MODULE_APP,
+             "Invalid starttime type. Expected number, got type %d (value: %s)",
+             starttimeItem->type, valueStr);
+         isValid = false;
+       }
+     } else {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing starttime field");
+       isValid = false;
+     }
+ 
+     // 处理解析结果
+     if (isValid) {
+       sportDataVector.push_back(sportData);
+       WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Successfully parsed item %d", i);
+     } else {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "Invalid data in item %d. Missing fields: %s", i,
+                     missingFields.c_str());
+     }
+   }
+ 
+   cJSON_Delete(root);
+ 
+   // 检查是否成功解析了任何数据
+   if (sportDataVector.empty()) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "No valid data items found in JSON");
+     return false;
+   }
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                 "Successfully loaded %zu valid data items",
+                 sportDataVector.size());
+   return true;
+ }
+ 
+ //////////////////////////////////////GPS///////////////////////////////////////////////
+ /*
+   Latitude(纬度):范围:-90° 至 +90°(或南纬 90° 至北纬 90°);
+   Longitude(经度):范围:-180° 至 +180°(或西经 180° 至东经 180°);
+ 
+   -画布数据集最多是100个定位坐标,超过按比例进行拿取100个点位;
+   -通过映射关系,将经纬度转换为400*400画布上的坐标;
+   -但是不能靠近400,以免显示不全等问题,350*350;
+   -如果处理负数,需要将其转换为正数,然后再进行映射?
+   -如果有正数又有负数,应该怎么处理?
+ */
+ 
+ static double getmin(double a, double b) { return a < b ? a : b; }
+ static double getmax(double a, double b) { return a > b ? a : b; }
+ // 计算点p到由p1和p2确定的线段的垂直距离(优化版)
+ static double perpendicularDistance(const Point &p, const Point &p1,
+                                     const Point &p2) {
+   // 计算向量 p1->p2
+   double dx = p2.x - p1.x;
+   double dy = p2.y - p1.y;
+ 
+   // 线段长度的平方
+   double len2 = dx * dx + dy * dy;
+ 
+   // 如果线段退化为一个点,直接计算点到点的距离
+   if (len2 == 0) {
+     return std::hypot(p.x - p1.x, p.y - p1.y);
+   }
+ 
+   // 计算投影比例 t
+   double t = ((p.x - p1.x) * dx + (p.y - p1.y) * dy) / len2;
+ 
+   if (t < 0) {
+     // 投影在p1之前,返回p到p1的距离
+     return std::hypot(p.x - p1.x, p.y - p1.y);
+   }
+ 
+   if (t > 1) {
+     // 投影在p2之后,返回p到p2的距离
+     return std::hypot(p.x - p2.x, p.y - p2.y);
+   }
+ 
+   // 投影在线段上,计算投影点并返回距离
+   double projX = p1.x + t * dx;
+   double projY = p1.y + t * dy;
+   return std::hypot(p.x - projX, p.y - projY);
+ }
+ 
+ // Douglas-Peucker算法实现(优化版)
+ static void douglasPeucker(const std::vector<Point> &points, double epsilon,
+                            std::vector<Point> &result) {
+   if (points.size() <= 2) {
+     // 点数量不足,直接返回
+     result = points;
+     return;
+   }
+ 
+   double dmax = 0;
+   int index = 0;
+   int end = points.size() - 1;
+ 
+   // 找到距离最大的点
+   for (int i = 1; i < end; i++) {
+     double d = perpendicularDistance(points[i], points[0], points[end]);
+     if (d > dmax) {
+       index = i;
+       dmax = d;
+     }
+   }
+ 
+   // 如果最大距离大于阈值,则递归处理
+   if (dmax > epsilon) {
+     std::vector<Point> recResults1, recResults2;
+ 
+     // 递归处理前半部分
+     douglasPeucker(
+         std::vector<Point>(points.begin(), points.begin() + index + 1), epsilon,
+         recResults1);
+ 
+     // 递归处理后半部分
+     douglasPeucker(std::vector<Point>(points.begin() + index, points.end()),
+                    epsilon, recResults2);
+ 
+     // 合并结果(避免重复添加端点)
+     result.assign(recResults1.begin(), recResults1.end() - 1);
+     result.insert(result.end(), recResults2.begin(), recResults2.end());
+   } else {
+     // 否则保留首尾点
+     result = {points[0], points[end]};
+   }
+ }
+ 
+ // 改进的GetPointData函数(优化版)
+ void TraingModel::GetPointData() {
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                 "Generating point data from %zu GPS points", gpsData.size());
+ 
+   std::vector<GPSData> sampledData;
+ 
+   // 处理GPS数据
+   if (gpsData.size() > 100) {
+     // 计算经纬度范围
+     double minLat = 90.0, maxLat = -90.0;
+     double minLon = 180.0, maxLon = -180.0;
+ 
+     // 同时计算平均值用于判断数据分布
+     double sumLat = 0, sumLon = 0;
+ 
+     for (const auto &point : gpsData) {
+       minLat = getmin(minLat, point.latitude);
+       maxLat = getmax(maxLat, point.latitude);
+       minLon = getmin(minLon, point.longitude);
+       maxLon = getmax(maxLon, point.longitude);
+       sumLat += point.latitude;
+       sumLon += point.longitude;
+     }
+ 
+     // 计算经纬度范围和平均值
+     double rangeLat = maxLat - minLat;
+     double rangeLon = maxLon - minLon;
+     double avgLat = sumLat / gpsData.size();
+     double avgLon = sumLon / gpsData.size();
+ 
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                   "GPS range: lat=[%.6f, %.6f], lon=[%.6f, %.6f]", minLat,
+                   maxLat, minLon, maxLon);
+ 
+     // 检查数据是否集中在极小区域或几乎相同
+     const double MIN_SIGNIFICANT_RANGE = 0.01; // 根据实际情况调整
+     bool isDataDegenerate =
+         (rangeLat < MIN_SIGNIFICANT_RANGE && rangeLon < MIN_SIGNIFICANT_RANGE);
+ 
+     if (isDataDegenerate) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "GPS data is degenerate (very small range)");
+       // 使用均匀采样,避免算法失效
+       double step = static_cast<double>(gpsData.size() - 1) / 99;
+       for (int i = 0; i < 100; i++) {
+         int index = static_cast<int>(i * step);
+         sampledData.push_back(gpsData[index]);
+       }
+     } else {
+       // 转换GPS坐标到屏幕坐标
+       std::vector<Point> screenPoints;
+       screenPoints.reserve(gpsData.size());
+ 
+       for (const auto &point : gpsData) {
+         double normLat = (point.latitude - minLat) / rangeLat;
+         double normLon = (point.longitude - minLon) / rangeLon;
+         screenPoints.push_back(
+             {normLon * 300 + 50, (1.0 - normLat) * 300 + 50});
+       }
+ 
+       // 使用Douglas-Peucker算法简化轨迹
+       std::vector<Point> simplifiedPoints;
+       douglasPeucker(screenPoints, 0.5, simplifiedPoints);
+ 
+       WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                     "After Douglas-Peucker: %zu points",
+                     simplifiedPoints.size());
+ 
+       // 处理简化结果
+       if (simplifiedPoints.size() <= 2) {
+         WEARABLE_LOGE(
+             WEARABLE_LOG_MODULE_APP,
+             "Trajectory over-simplified! Using uniform sampling instead.");
+         // 过度简化时回退到均匀采样
+         double step = static_cast<double>(gpsData.size() - 1) / 99;
+         for (int i = 0; i < 100; i++) {
+           int index = static_cast<int>(i * step);
+           sampledData.push_back(gpsData[index]);
+         }
+       } else if (simplifiedPoints.size() > 100) {
+         // 简化后仍超过100点,再次均匀采样
+         double step = static_cast<double>(simplifiedPoints.size() - 1) / 99;
+         for (int i = 0; i < 100; i++) {
+           int index = static_cast<int>(i * step);
+           // 屏幕坐标反推回GPS坐标
+           double normX = (simplifiedPoints[index].x - 50) / 300;
+           double normY = (simplifiedPoints[index].y - 50) / 300;
+           double lat = minLat + (1.0 - normY) * rangeLat;
+           double lon = minLon + normX * rangeLon;
+           sampledData.push_back({0, lat, lon});
+         }
+       } else {
+         // 简化后点数量合适,直接使用
+         for (const auto &point : simplifiedPoints) {
+           double normX = (point.x - 50) / 300;
+           double normY = (point.y - 50) / 300;
+           double lat = minLat + (1.0 - normY) * rangeLat;
+           double lon = minLon + normX * rangeLon;
+           sampledData.push_back({0, lat, lon});
+         }
+       }
+     }
+   } else {
+     // GPS点数不足100,直接使用全部数据
+     sampledData = gpsData;
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "Using all %zu GPS points (no sampling)", sampledData.size());
+   }
+ 
+   // 映射到画布坐标
+   canvasData.clear();
+   canvasData.reserve(sampledData.size());
+ 
+   // 如果没有采样数据,直接返回
+   if (sampledData.empty()) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "No sampled data to map!");
+     return;
+   }
+ 
+   // 基于采样数据重新计算经纬度范围
+   double minLat = 90.0, maxLat = -90.0;
+   double minLon = 180.0, maxLon = -180.0;
+ 
+   for (const auto &point : sampledData) {
+     minLat = getmin(minLat, point.latitude);
+     maxLat = getmax(maxLat, point.latitude);
+     minLon = getmin(minLon, point.longitude);
+     maxLon = getmax(maxLon, point.longitude);
+   }
+ 
+   double rangeLat = maxLat - minLat;
+   double rangeLon = maxLon - minLon;
+ 
+   // 避免除零错误
+   if (rangeLat == 0)
+     rangeLat = 1e-10;
+   if (rangeLon == 0)
+     rangeLon = 1e-10;
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                 "Sampled GPS range: lat=[%.6f, %.6f], lon=[%.6f, %.6f]", minLat,
+                 maxLat, minLon, maxLon);
+ 
+   // 映射每个点到画布
+   for (const auto &point : sampledData) {
+     double normLat = (point.latitude - minLat) / rangeLat;
+     double normLon = (point.longitude - minLon) / rangeLon;
+ 
+     // 转换到画布坐标
+     double x = normLon * 300 + 50;
+     double y = (1.0 - normLat) * 300 + 50;
+ 
+     canvasData.push_back({x, y});
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                   "Mapped point: (%.6f, %.6f) -> (%.2f, %.2f)", point.latitude,
+                   point.longitude, x, y);
+   }
+ 
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Generated %zu canvas points",
+                 canvasData.size());
+ }
+ 
+ // 添加经纬度数据集
+ void TraingModel::AddGPSData(uint32_t timestamp, double latitude,
+                              double longitude) {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== AddGPSData函数调用开始 ===");
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                 "输入参数: timestamp=%u, latitude=%.6f, longitude=%.6f",
+                 timestamp, latitude, longitude);
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "当前GPS数据点数量: %zu",
+                 gpsData.size());
+ 
+   // 判断数据是否合理
+   if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "错误: GPS数据无效 - 纬度=%.6f (范围: -90~90), 经度=%.6f "
+                   "(范围: -180~180)",
+                   latitude, longitude);
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "=== AddGPSData函数调用结束(数据无效) ===");
+     return;
+   }
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GPS数据有效性检查通过");
+ 
+   // 校验时间戳是否递增
+   if (!gpsData.empty() && timestamp <= gpsData.back().timestamp) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "错误: 时间戳未递增 - 当前=%u, 上一个=%u, 差值=%d", timestamp,
+                   gpsData.back().timestamp,
+                   (int)timestamp - (int)gpsData.back().timestamp);
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "=== AddGPSData函数调用结束(时间戳错误) ===");
+     return;
+   }
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "时间戳递增检查通过");
+ 
+   // 添加数据
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "准备添加GPS数据到容器...");
+   gpsData.push_back({timestamp, latitude, longitude});
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                 "成功添加GPS数据 #%zu: 时间戳=%u, 坐标=(%.6f, %.6f)",
+                 gpsData.size(), timestamp, latitude, longitude);
+ 
+   // 打印当前GPS数据统计信息
+   if (gpsData.size() > 1) {
+     double lat_diff = latitude - gpsData[gpsData.size() - 2].latitude;
+     double lon_diff = longitude - gpsData[gpsData.size() - 2].longitude;
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                   "与上一个点的距离差: 纬度差=%.6f, 经度差=%.6f", lat_diff,
+                   lon_diff);
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== AddGPSData函数调用结束 ===");
+ }
+ 
+ //保存canvas数据
+ bool TraingModel::SaveCanvasData() {
+ 
+   //打印一下gps的数据
+   for (const auto &point : gpsData) {
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                   "GPS Data: Latitude = %f, Longitude = %f", point.latitude,
+                   point.longitude);
+   }
+ 
+   if (canvasData.size() == 0) {
+     WEARABLE_LOGE(WEARING_LOG_MODULE_APP, "canvasData is empty");
+     return false;
+   }
+ 
+   CreateDirectoryIfNotExists(TRAINING_CANVAS_FILE);
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "canvasData.size() = %zu",
+                 canvasData.size());
+ 
+   std::string filePath =
+       TRAINING_CANVAS_FILE + std::to_string(sportdata->starttime) + ".bin";
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveCanvasData filePath: %s",
+                 filePath.c_str());
+ 
+   std::ofstream gpsFile(filePath, std::ios::binary);
+   if (!gpsFile) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
+                   filePath.c_str());
+     return false; // 返回失败
+   }
+   // 写入gps数据
+   if (!gpsFile.write(reinterpret_cast<const char *>(canvasData.data()),
+                      canvasData.size() * sizeof(Point))) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入GPS数据失败。");
+     return false; // 返回失败
+   }
+ 
+   gpsFile.close();
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData Success.");
+   return true; // 返回成功
+ }
+ // 清除canvas数据
+ void TraingModel::ClearCanvasData() { canvasData.clear(); }
+ // 获取轨迹点集
+ std::vector<Point> TraingModel::GetCanvasData() const { return canvasData; }
+ // 获取canvas数据
+ std::string TraingModel::GetCanvasDataPath(uint32_t timestamp) {
+   // 首先检查完全匹配的时间戳
+   std::string exactFilePath =
+       TRAINING_CANVAS_FILE + std::to_string(timestamp) + ".bin";
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "canvas表: %s", exactFilePath.c_str());
+   if (IsFileAccessibleAndNotEmpty(exactFilePath)) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到canvas表: %s",
+                   exactFilePath.c_str());
+     return exactFilePath; // 返回完全匹配的文件路径
+   }
+ 
+   // 如果未找到,检查时间戳相差1到2秒的文件
+   for (int i = -2; i <= 2; ++i) {
+     uint32_t checkTimestamp = timestamp + i;
+     std::string filePath =
+         TRAINING_CANVAS_FILE + std::to_string(checkTimestamp) + ".bin";
+     if (IsFileAccessibleAndNotEmpty(filePath)) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到canvas表: %s",
+                     filePath.c_str());
+       return filePath; // 返回找到的文件路径
+     }
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的找到canvas表。");
+   return ""; // 未找到文件
+ }
+ // 加载GPS数据
+ bool TraingModel::LoadCanvasData(const std::string &filePath) {
+   std::ifstream gpsFile(filePath, std::ios::binary);
+   if (!gpsFile) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
+                   filePath.c_str());
+     return false;
+   }
+ 
+   // 清空现有数据
+   canvasData.clear();
+ 
+   // 动态读取数据(假设文件格式允许逐点读取)
+   Point point;
+   while (gpsFile.read(reinterpret_cast<char *>(&point), sizeof(Point))) {
+     canvasData.push_back(point);
+   }
+ 
+   gpsFile.close();
+ 
+   if (canvasData.empty()) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未读取到有效数据: %s",
+                   filePath.c_str());
+     return false;
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                 "LoadCanvasData Success. 加载了 %zu 个点", canvasData.size());
+   return true;
+ }
+ //////////////////////////////////////gps存储///////////////////////////////////////
+ //存储gps数据
+ bool TraingModel::SaveGPSData() {
+   //打印gps数据
+   for (const auto &point : gpsData) {
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                   "GPS Data: Latitude = %f, Longitude = %f", point.`latitude,
+                   point.longitude);
+   }
+   CreateDirectoryIfNotExists(TRAINING_GPS_FILE);
+   std::string filePath =
+       TRAINING_GPS_FILE + std::to_string(sportdata->starttime) + ".bin";
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData filePath: %s",
+                 filePath.c_str());
+ 
+   std::ofstream gpsFile(filePath, std::ios::binary);
+   if (!gpsFile) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
+                   filePath.c_str());
+     return false; // 返回失败
+   }
+   // 写入gps数据
+   if (!gpsFile.write(reinterpret_cast<const char *>(gpsData.data()),
+                      gpsData.size() * sizeof(GPSData))) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入GPS数据失败。");
+     return false; // 返回失败
+   }
+   gpsFile.close();
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData Success.");
+   return true;
+ }
+ std::string TraingModel::GetGPSDataPath(uint32_t timestamp) {
+   // 首先检查完全匹配的时间戳
+   std::string exactFilePath =
+       TRAINING_GPS_FILE + std::to_string(timestamp) + ".bin";
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gps表: %s", exactFilePath.c_str());
+   if (IsFileAccessibleAndNotEmpty(exactFilePath)) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到gps表: %s",
+                   exactFilePath.c_str());
+     return exactFilePath; // 返回完全匹配的文件路径
+   }
+ 
+   // 如果未找到,检查时间戳相差1到2秒的文件
+   for (int i = -2; i <= 2; ++i) {
+     uint32_t checkTimestamp = timestamp + i;
+     std::string filePath =
+         TRAINING_GPS_FILE + std::to_string(checkTimestamp) + ".bin";
+     if (IsFileAccessibleAndNotEmpty(filePath)) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到gps表: %s", filePath.c_str());
+       return filePath; // 返回找到的文件路径
+     }
+   }
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的找到gps表。");
+   return "";
+ }
+ 
+ //获取GPS连接状态
+ bool TraingModel::GetGPSConnectState() { return gpsconnect; }
+ //设置GPS连接状态
+ void TraingModel::SetGPSConnectState(bool state) {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS连接状态设置 ===");
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前GPS连接状态: %d, 新状态: %d",
+                 gpsconnect, state);
+ 
+   if (gpsconnect != state) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS连接状态发生变化: %d -> %d",
+                   gpsconnect, state);
+     gpsconnect = state;
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS连接状态已更新为: %d",
+                   gpsconnect);
+ 
+     //状态改变记录
+     // SystemLogModel::GetInstance()->save_gps_status_log_type(gpsconnect);
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS状态变化记录完成");
+   } else {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS连接状态未发生变化,保持: %d",
+                   gpsconnect);
+   }
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS连接状态设置完成 ===");
+ }
+ //运动心率、gps开启准备
+ void TraingModel::start_training_heart() {
+   if (gpsopen == false) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始启动GPS定位服务...");
+     //开启心率检测
+ #ifdef SUPPORT_PPG_SERVICE
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "启动心率检测服务");
+     ppg_hr_start();
+ #endif
+     gpsopen = true;
+   }
+ }
+ //运动心率、gps关闭
+ void TraingModel::stop_heart_gps() {
+   if (gpsopen == true) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始关闭GPS定位服务...");
+     // 关闭gps
+ #if defined(SUPPORT_GNSS)
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "调用gnss_stop()关闭GPS服务");
+     gnss_stop();
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gnss_stop()调用完成");
+ #endif
+ 
+     //关闭心率检测
+ #ifdef SUPPORT_PPG_SERVICE
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "关闭心率检测服务");
+     ppg_hr_stop();
+ #endif
+ 
+     gpsopen = false;
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "GPS定位服务关闭完成,gpsopen设置为false");
+   }
+ }
+ 
+ /////////////////////////////////////位置服务定时器/////////////////////////////////////
+ /*
+  * 位置服务定时器说明:
+  * - 功能:负责获取GPS定位数据,更新GPS连接状态,添加经纬度数据
+  * - 频率:1秒间隔,保证位置数据的实时性
+  * - 触发条件:仅在训练进行中且训练状态非结束时执行
+  */
+ static osTimerId_t g_location_timer = nullptr;
+ static int location_timer_interval = 1; // 位置数据获取间隔,单位秒
+ static int gps_timer_count = 0;
+ 
+ /*位置服务定时器到期时的处理*/
+ static void gnss_timer_callbackProc(int data) {
+   /*
+       GPS数据获取处理
+       1、目前gps注册有问题 ;需要延迟2s 去开启gps;
+   */
+   gps_timer_count++;
+   if (gps_timer_count < 2) {
+     return;
+   }
+   if (gps_timer_count == 2) {
+ #if defined(SUPPORT_GNSS)
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开启gps");
+     gnss_start();
+ #endif
+   }
+ #if defined(SUPPORT_GNSS)
+   gps_data_t send_gps_data = {0};
+   gps_data_t *gps_data = getPGPSGlobaldata();
+ 
+   if (gps_data == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "错误: gps_data == NULL,GPS全局数据获取失败");
+     return;
+   }
+ 
+   if (gps_data->last_gps_time_ms > 0) {
+     memcpy_s(&send_gps_data, sizeof(gps_data_t), gps_data, sizeof(gps_data_t));
+   } else {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS时间戳无效,跳过本次处理");
+     return;
+   }
+ 
+   // 判断是否定位成功并设置连接状态
+   bool isGpsConnected = (send_gps_data.status > 1);
+   TraingModel::GetInstance()->SetGPSConnectState(isGpsConnected);
+ 
+   // 判断是否在运动或训练已结束
+   int train_status = uapi_dev_runtime_get_train_status();
+   ExerciseState sport_state = TraingModel::GetInstance()->GetSportState();
+ 
+   if (train_status == 0 || sport_state == ExerciseState::End) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "运动已结束或未开始,跳过GPS数据添加");
+     return;
+   }
+ 
+   // 如果定位成功,添加经纬度数据
+   if (isGpsConnected) {
+     uint32_t time = TraingModel::GetInstance()->get_current_time();
+     TraingModel::GetInstance()->AddGPSData(time, send_gps_data.location.lat,
+                                            send_gps_data.location.lng);
+   } else {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定位失败,跳过数据添加");
+   }
+ #endif
+ }
+ 
+ /*
+  * @brief 位置服务定时器回调函数
+  */
+ static void gnss_timer_callback(int data) {
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "gnss_timer_callback %d", data);
+   GraphicService::GetInstance()->PostGraphicEvent(
+       std::bind(gnss_timer_callbackProc, data));
+ }
+ 
+ /*
+  *  @brief 开启位置服务定时器函数
+  *  @param interval 时间间隔,单位ms
+  */
+ void TraingModel::gnss_start_timer(uint32_t interval) {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS定时器启动流程开始 ===");
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器间隔: %u ms", interval);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前定时器状态: %p",
+                 g_location_timer);
+ 
+   /* -------------------------- 1.检查位置服务定时器是否已经存在,如果存在则返回
+    * ------------------------- */
+   if (g_location_timer != nullptr) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "错误: GPS定时器已存在,跳过创建");
+     return;
+   }
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器不存在,开始创建...");
+ 
+   /* --------------------------------- 2.创建位置服务定时器
+    * -------------------------------- */
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "调用osTimerNew创建GPS定时器...");
+   g_location_timer = osTimerNew((osTimerFunc_t)gnss_timer_callback,
+                                 osTimerPeriodic, nullptr, nullptr);
+   // 检查定时器创建是否成功
+   if (g_location_timer == nullptr) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "错误: GPS定时器创建失败!!");
+     return;
+   }
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器创建成功: %p",
+                 g_location_timer);
+ 
+   /* ----------------------------- 3.将毫秒转换为系统时钟节拍数
+    * ---------------------------- */
+   int tick = osMs2Tick(interval);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "时间转换: %u ms -> %d ticks",
+                 interval, tick);
+ 
+   /* --------------------------------- 4.启动位置服务定时器
+    * -------------------------------- */
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "启动GPS定时器...");
+   osStatus_t ret = osTimerStart(g_location_timer, tick);
+   /* -------------------- 5.检查位置服务定时器启动是否成功,如果启动失败,删除定时器并置为
+    * nullptr -------------------- */
+   if (ret != osOK) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "错误: GPS定时器启动失败, ret = %lx!!", ret);
+     if (g_location_timer != nullptr) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "删除失败的GPS定时器...");
+       ret = osTimerDelete(g_location_timer);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器删除结果: %lx", ret);
+     }
+     g_location_timer = nullptr;
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "=== GPS定时器启动流程结束(失败) ===");
+     return;
+   }
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器启动成功");
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS定时器启动流程结束(成功) ===");
+ }
+ 
+ /*
+  * @brief 停止位置服务定时器
+  */
+ void TraingModel::gnss_stop_timer(void) {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS定时器停止流程开始 ===");
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前定时器状态: %p",
+                 g_location_timer);
+ 
+   // 检查位置服务定时器是否存在
+   if (g_location_timer != nullptr) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器存在,开始停止流程...");
+ 
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "停止GPS定时器...");
+     osTimerStop(g_location_timer);
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器已停止");
+ 
+     // 删除定时器并置为 nullptr
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "删除GPS定时器...");
+     osStatus_t ret = osTimerDelete(g_location_timer);
+     if (ret != osOK) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "错误: GPS定时器删除失败, ret = %lx!!", ret);
+     } else {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器删除成功");
+     }
+     g_location_timer = nullptr;
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器指针已置空");
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS定时器停止流程结束 ===");
+   } else {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器不存在,跳过停止流程");
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "=== GPS定时器停止流程结束(无需停止) ===");
+   }
+   gps_timer_count = 0;
+ }
+ 
+ ///////////////////////////////////////运动数据采集定时器//////////////////////////////////
+ /*
+  * 运动数据采集定时器说明:
+  * - 功能:负责获取运动数据(步数、距离、卡路里、心率等),更新训练目标完成度
+  * - 频率:300ms间隔,保证运动数据的实时性和准确性
+  * - 触发条件:仅在训练进行中且训练状态非结束时执行
+  * - 包含服务:CYWEE运动数据、PPG心率数据、训练目标检查、UI更新
+  */
+ #if SPORT_TIMER_DATA
+ // 声明运动数据采集定时器变量
+ static osTimerId_t g_sport_start_data_timer = nullptr;
+ static int sport_start_data_timer_interval = 300; // 运动数据获取间隔,单位毫秒
+ 
+ /*
+  * @brief 获取运动基础数据
+  * @return 是否成功获取数据
+  */
+ bool TraingModel::GetSportActivityData(void) {
+ #ifdef SUPPORT_CYWEE_SERVICE
+   act_result_t cyweeInfo;
+   cywee_get_act_data(&cyweeInfo);
+   // 更新运动基础数据
+   TraingModel::GetInstance()->AnalysisData(&cyweeInfo);
+   // 更新其他目标完成度
+   TraingModel::GetInstance()->CheckSportTag();
+ #endif
+   return true;
+ }
+ 
+ /*
+  * @brief 获取运动额外数据
+  * @return 是否成功获取数据
   */
-
-  std::string tagStr;
-
-  switch (sportTagType_) {
-  case ExerciseTag::Duration:
-    tagStr = std::to_string(sportTag_) + " min"; // 时长目标
-    break;
-
-  case ExerciseTag::Calories:
-    tagStr = std::to_string(sportTag_) + " kcal"; // 卡路里目标
-    break;
-
-  case ExerciseTag::Steps:
-  case ExerciseTag::Distance:
-    if (isspecialsport_) // 检查是否为特殊训练
-    {
-      // 只在特殊训练模式下使用步数和距离目标
-      if (sportTagType_ == ExerciseTag::Steps) {
-        tagStr = std::to_string(sportTag_) + " steps"; // 步数目标
-      } else {
-        tagStr = std::to_string(sportTag_) + " km"; // 距离目标
-      }
-    } else {
-      tagStr = ""; // 普通训练下不使用目标
-    }
-    break;
-
-  default:
-    tagStr = ""; // 未知目标类型
-    break;
-  }
-
-  return tagStr;
-}
-/*设置运动状态*/
-void TraingModel::SetSportState(ExerciseState state) {
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " SetSportState %d", state);
-  if (state != ExerciseState::General) {
-    /*app发起的运动*/
-    if (Openingway == true) {
-      if (state == ExerciseState::Start) {
-        sportdata->duration = 0;
-      }
-#ifdef SUPPORT_BLE_SERVICE
-      sendtraningstatedata(static_cast<uint8_t>(state), sportdata->duration);
-#endif
-    }
-  }
-  sportState_ = state;
-#ifdef SYSTEM_LOG_SERVICE
-  // 记录运动状态
-  if (state == ExerciseState::End) {
-    uapi_save_runtime_log(RUNTIME_LOG_SPORT_END);
-  } else if (state == ExerciseState::Continue) {
-    uapi_save_runtime_log(RUNTIME_LOG_SPORT_RESUME);
-  } else if (state == ExerciseState::Pause) {
-    uapi_save_runtime_log(RUNTIME_LOG_SPORT_PAUSE);
-  }
-#endif
-}
-/*获取运动状态*/
-ExerciseState TraingModel::GetSportState() { return sportState_; }
-// 计算平均心率的函数
-double CalculateAverageHeartRate(const std::vector<int> &heartRates) {
-  if (heartRates.size() <= 2) {
-    // 如果心率数据点少于等于2,无法去掉最高和最低值
-    return 0.0; // 或者返回心率的平均值
-  }
-
-  // 创建一个副本以避免修改原始数据
-  std::vector<int> sortedHeartRates = heartRates;
-
-  // 排序
-  std::sort(sortedHeartRates.begin(), sortedHeartRates.end());
-
-  // 去掉一个最高值和一个最低值
-  sortedHeartRates.erase(sortedHeartRates.begin()); // 去掉最低值
-  sortedHeartRates.pop_back();                      // 去掉最高值
-
-  // 计算剩余心率的平均值
-  double sum = 0;
-  for (int rate : sortedHeartRates) {
-    sum += rate;
-  }
-
-  return sum / sortedHeartRates.size(); // 返回平均值
-}
-#ifdef SUPPORT_CYWEE_SERVICE
-/*分析数据*/
-void TraingModel::AnalysisData(act_result_t *cyweeInfo) {
-  if (cyweeInfo == NULL)
-    return;
-
-  // 不同的运动类型解析不同的数据
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                "AnalysisData:[steps %d, distance %d,calories %d, pace %d, "
-                "step_frequency %d, step_length %d]",
-                cyweeInfo->steps, cyweeInfo->distance, cyweeInfo->calories,
-                cyweeInfo->pace, cyweeInfo->step_frequency,
-                cyweeInfo->step_length);
-  // 通用数据
-  sportdata->steps = cyweeInfo->steps;
-  sportdata->distance = cyweeInfo->distance;
-  sportdata->calories = cyweeInfo->calories;
-
-  // sportdata->cdc = cyweeInfo->step_frequency;
-  // sportdata->std = cyweeInfo->step_length;
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " pace %d", sportdata->pc);
-
-  sportdata->pc = cyweeInfo->pace;
-
-  // 更新最慢配速
-  if (sportdata->spc < sportdata->pc && sportdata->pc != 0) {
-    sportdata->spc = sportdata->pc;
-  }
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "spc %d", sportdata->spc);
-
-  // 计算平均心率
-  if (sportdata->heart > 50) {
-    sportdata->avgheart = Averageheartrate(sportdata->heart);
-  }
-
-  // 心率提醒
-  if (sportdata->heart >= user_maxHeart && user_maxHeart != 0) {
-    uapi_set_screen_on_api(); // 亮屏检测
-    if (true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb() &&
-        (!uapi_sleep_mode_flag_get())) {
-      custom_VibratorFunc_int(0);
-    }
-    if (TraingCardView::GetInstance()) {
-      GraphicService::GetInstance()->PostGraphicEvent(
-          std::bind(&TraingCardView::SetPopupViewStatus,
-                    TraingCardView::GetInstance(), HeartPopup, true));
-      if (TraingCardView::GetInstance()->GetHeartMaxLabel()) {
-        GraphicService::GetInstance()->PostGraphicEvent(
-            std::bind(&TraingCardView::SetHeartMaxLabel,
-                      TraingCardView::GetInstance(), user_maxHeart));
-      }
-    }
-  }
-}
-#endif
-
-#if 0
-     int avg_step_freq;//平均步频
-     int avg_step_len;//平均步长
-     int avg_pace;//平均配速
-     int max_step_freq;//最大步频
-     int max_pace;//最大配速
-     int activity_zone;//活动程度区间 0低度 1中度 2高度
-     int ativity_zone_moderate_duration;//中度活动时间
-     int ativity_zone_high_duration;//高度活动时间
-     int MHR_zone;//心率区间
-     int distance_motion;//体感距离
-#endif
-
-/*分析activity extra info数据*/
-#ifdef SUPPORT_CYWEE_SERVICE
-void TraingModel::AnalysisExtraData(act_ext_result_t *cyweeInfo) {
-
-  //判断是否为特殊训练
-  if (isspecialsport_ == false) {
-    return;
-  }
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[apc:%d fpc:%d cdc:%d std:%d]",
-                cyweeInfo->avg_pace, cyweeInfo->max_pace,
-                cyweeInfo->avg_step_freq, cyweeInfo->avg_step_len);
-  //平均配速
-  if (cyweeInfo->avg_pace != 0) {
-    sportdata->apc = cyweeInfo->avg_pace;
-  }
-  //最快配速
-  if (cyweeInfo->max_pace != 0) {
-    sportdata->fpc = cyweeInfo->max_pace;
-  }
-  //平均步频
-  if (cyweeInfo->avg_step_freq != 0) {
-    sportdata->cdc = cyweeInfo->avg_step_freq;
-  }
-  //平均步长
-  if (cyweeInfo->avg_step_len != 0) {
-    sportdata->std = cyweeInfo->avg_step_len * 100; // 前者cm 后者m
-  }
-}
-#endif
-/*分析运动心率数据*/
-void TraingModel::AnalysisHeartData(uint8_t hrs) {
-  sportdata->heart = hrs;
-  SetIntensity(sportdata->heart); // 设置训练强度
-}
-
-/*打印函数*/
-void TraingModel::printf_data(SportData *data) {
-  /*打印测试一下数据*/
-  printf("\r\n****************************************\r\n");
-  printf("Sport type: %d\n", data->sportType);
-  printf("Sport ID: %d\n", data->sportId);
-  printf("Start date: %s\n", data->start_date.c_str());
-  printf("Start time: %s\n", data->start_time.c_str());
-  printf("End time: %s\n", data->end_time.c_str());
-  printf("Goal degree: %d\n", data->goaldegree);
-  printf("Duration: %d\n", data->duration);
-  printf("Distance: %d\n", data->distance);
-  printf("Average heart rate: %d\n", data->avgheart);
-  printf("Steps: %d\n", data->steps);
-  printf("Intensity: %d\n", data->intensity);
-  printf("\r\n****************************************\r\n");
-}
-/*获取数据*/
-SportData *TraingModel::GetSportdata() {
-  // printf_data(sportdata);
-  return sportdata;
-}
-/* 设置训练数据[为训练记录准备] */
-void TraingModel::SetSportdata(SportData *data) {
-  if (data != nullptr && sportdata != nullptr) {
-    sportdata->sportType = data->sportType;
-    sportdata->sportId = data->sportId;
-    sportdata->start_date = data->start_date;
-    sportdata->start_time = data->start_time;
-    sportdata->end_time = data->end_time;
-    sportdata->goaldegree = data->goaldegree;
-    sportdata->duration = data->duration;
-    sportdata->distance = data->distance;
-    sportdata->avgheart = data->avgheart;
-    sportdata->steps = data->steps;
-    sportdata->intensity = data->intensity;
-    sportdata->calories = data->calories;
-    sportdata->apc = data->apc;
-    sportdata->fpc = data->fpc;
-    sportdata->spc = data->spc;
-    sportdata->std = data->std;
-    sportdata->cdc = data->cdc;
-    sportdata->starttime = data->starttime; //更新开始时间
-    printf_data(data);                      //打印该运动数据
-    IsSpecialSport(sportdata->sportId);     // 配置训练特殊性
-  }
-}
-/*获取训练卡路里*/
-int TraingModel::GetCal() { return sportdata->calories; }
-/*获取训练目标*/
-int TraingModel::GetSportTag() { return sportdata->tag; }
-/*获取训练项目类型*/
-ExerciseTag TraingModel::GetSportTagtype() { return sportdata->sportTagType; }
-/*重置训练配置*/
-void TraingModel::ResetSharedTrainingData() {
-  sportdata->Reset();    // 重置结构体
-  heartRateData.clear(); // 清空心率数据
-
-  ClearPaceTable();  //重置配速数据
-  ClearHeartTable(); // 清空心率数据
-
-  recentHeartRates.clear();
-  delayed.clear(); // 重置 delayed 字典
-
-  while (!maxHeap.empty()) { // 清空最大堆
-    maxHeap.pop();
-  }
-  while (!minHeap.empty()) { // 清空最小堆
-    minHeap.pop();
-  }
-
-  totalHeartRate = 0;
-  countHeartRate = 0;
-  heartcount = 0;
-
-  Gettagstuats = false; // 重置训练达标标志位
-  Openstate = true;     // 开启运动开始标志位
-
-  shock_count = 0; //重置震动计数
-
-  gpsData.clear();    // 清空gps数据
-  canvasData.clear(); // 清空画布数据
-}
-
-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;
-  if (uapi_get_timestampe_ss(&time) != ERRCODE_SUCC) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp");
-    return;
-  }
-
-  ExerciseState currentState = GetSportState(); // 获取当前运动状态
-
-  // 增加标志位互斥保障"开始"和"结束"的唯一性操作
-  if (currentState == ExerciseState::Start && !Startstate) {
-    // 设置训练 runtime 为 1 训练中
-    uapi_dev_runtime_set_train_status(1);
-    if (Openingway) {
-      // uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_HIGH);
-    }
-
-    // 更新用户数据
-    SetUserSportdata();
-
-    ResetSharedTrainingData(); // 重置共享训练数据
-
-    // printf("SetTimestamp::time:%u  \r\n", time);
-    sportdata->starttime = time;
-
-    sportdata->sportType = sportType_; // 训练类型
-    sportdata->sportId = sportId_;
-
-    IsSpecialSport(sportdata->sportId); // 配置运动特殊性状态
-
-    if (sportTag_) // 有值才设置[训练目标]
-    {
-      sportdata->sportTagType = sportTagType_;
-      sportdata->tag = sportTag_;
-    }
-
-    current_goal = GetCurrentSportTag();
-
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "训练目标:类型: %d  值: %d 当前目标值:%d", sportTagType_,
-                  sportTag_, current_goal);
-
-    // 设置起始日期和时间
-    SetStartDateTime();
-
-    Startstate = true;
-    Endstate = false; // 确保"开始"和"结束"状态互斥
-
-     //打印目前运动配置项
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "*******************************");
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始运动");
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportType:%d", sportdata->sportType);
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportId:%d", sportdata->sportId);
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportTagType:%d", sportdata->sportTagType);
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportTag:%d", sportdata->tag);
-     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "*******************************");
- 
-
-    sport_start_data_timer(300); //开启数据获取定时器 刷新频率是300ms
-
-#ifdef SYSTEM_LOG_SERVICE
-    //日志记录
-    if (Openingway) {
-      uapi_save_runtime_log(RUNTIME_LOG_APP_SPORT_LAUNCH); // app发起运动
-    } else {
-      uapi_save_runtime_log(RUNTIME_LOG_DIAL_SPORT_LAUNCH); //手表发起运动
-    }
-    if (isspecialsport_) {
-      uapi_save_runtime_log(RUNTIME_LOG_SPORT_SPECIAL_START); //特殊运动
-    } else {
-      uapi_save_runtime_log(RUNTIME_LOG_SPORT_NORMAL_START); //普通运动
-    }
-#endif
-
-  } else if (currentState == ExerciseState::End && !Endstate) {
-    sport_stop_data_timer(); //停止数据获取定时器
-
-    // 设置训练 runtime 为 0 训练结束
-    uapi_dev_runtime_set_train_status(0);
-    if (Openingway) {
-      // uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_SLOW);
-    }
-
-    sportdata->endtime = time;
-
-    SetEndTime();
-
-    sportState_ = ExerciseState::General;
-    Openstate = false; // 关闭运动标志位
-
-    // 记录运动数据
-    // RecordSportData();
-
-    //配置最后的训练强度(平均心率为标准)
-    SetIntensity(sportdata->avgheart);
-
-    //更新gps点位
-    GetPointData();
-
-    do_custom_fileoperate_service_check_msg(
-        CUSTOM_FILEOPERATE_MSG_TYPE_SPORTDATA_SAVE, nullptr, 0);
-
-    Startstate = false;
-    Endstate = true;
-
-    stop_heart_gps();  // 停止心率和gps数据采集
-    gnss_stop_timer(); // 停止gps定时器
-
-#if 0
-       // 重置训练目标 [发生在训练前]
-       sportTag_ = 0;
-       sportTagType_ = ExerciseTag::UNKNOW;
-#endif
-    /*运动结束并且是手表发起的运动*/
-    if (Openingway == false) {
-      sendtraningstateend();
-    }
-    /*运动结束并且是app发起的运动*/
-    else {
-      sendtraningstatedata(0, sportdata->duration);
-    }
-
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "结束运动");
-  }
-}
-/*设置开始时间*/
-void TraingModel::SetStartDateTime() {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->[%d]\r\n",
-                sportdata->duration);
-  std::string startDate, startTime;
-  if (!GetFormattedDate(startDate, "Failed to get start date"))
-    return;
-  if (!GetFormattedTime(startTime, "Failed to get start time"))
-    return;
-
-  sportdata->start_date = startDate;
-  sportdata->start_time = startTime;
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->start_time [%s]\r\n",
-                sportdata->start_time.c_str());
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->[%d]\r\n",
-                sportdata->duration);
-}
-/*设置结束时间*/
-void TraingModel::SetEndTime() {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->[%d]\r\n",
-                sportdata->duration);
-  std::string endTime;
-  if (GetFormattedTime(endTime, "Failed to get end time")) {
-    sportdata->end_time = endTime;
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->end_time [%s]\r\n",
-                sportdata->end_time.c_str());
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->[%d]\r\n",
-                sportdata->duration);
-}
-/*获取日期字符串*/
-bool TraingModel::GetFormattedDate(std::string &dateOutput,
-                                   const char *errorMsg) {
-  char *date = (char *)malloc(9 * sizeof(char)); // 分配内存给start_date
-  if (uapi_get_YYMMDD_Time(date, '/') != ERRCODE_SUCC) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", errorMsg);
-    free(date);
-    return false;
-  }
-  dateOutput = std::string(date);
-  free(date); // 释放内存
-  return true;
-}
-/*获取时间字符串*/
-bool TraingModel::GetFormattedTime(std::string &timeOutput,
-                                   const char *errorMsg) {
-  char *time = (char *)malloc(9 * sizeof(char)); // 分配内存给start_time
-  if (uapi_get_HHMMSS_Time(time, ':', true) != ERRCODE_SUCC) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", errorMsg);
-    free(time);
-    return false;
-  }
-  timeOutput = std::string(time);
-  free(time); // 释放内存
-  return true;
-}
-/*保存数据*/
-void TraingModel::RecordSportData() {
-#if READTEST
-  if (SaveSportData() == false) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData error!");
-  }
-#else
-  if (MomentumFlag) {
-    // GetGoaldegree(); // 设置目标完成度
-    if (SaveSportData()) {
-      TraingRecordModel::GetInstance().SetJsonStatus(true);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData ok!");
-    } else {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSportData error!");
-    }
-  }
-#endif
-}
-// 获取训练时长时间
-std::string TraingModel::GetTrainingTime() {
-  int hour = sportdata->duration / NUM_TIME_HOUR;
-  int min = (sportdata->duration % NUM_TIME_HOUR) / NUM_TIME_MIN;
-  int sec = (sportdata->duration % NUM_TIME_HOUR) % NUM_TIME_MIN;
-
-  std::ostringstream oss;
-  oss << std::setfill('0') << std::setw(2) << hour << ":" << std::setw(2) << min
-      << ":" << std::setw(2) << sec;
-
-  std::string triningtime = oss.str();
-  return triningtime;
-}
-/*解析时间戳 返回例如:13:00:22*/
-std::string TraingModel::AnalysisTimestamp(uint64_t timestamp) {
-  // 将时间戳转换为小时、分钟、秒
-  int hours = timestamp / 3600000;             // 1小时 = 3600000毫秒
-  int minutes = (timestamp % 3600000) / 60000; // 1分钟 = 60000毫秒
-  int seconds = (timestamp % 60000) / 1000;    // 1秒 = 1000毫秒
-
-  // 将小时、分钟、秒转换为字符串
-  std::string hoursStr = std::to_string(hours);
-  std::string minutesStr = std::to_string(minutes);
-  std::string secondsStr = std::to_string(seconds);
-
-  // 格式化输出为 HH:MM:SS
-  std::stringstream ss;
-  ss << std::setfill('0') << std::setw(2) << hoursStr << ":" << std::setw(2)
-     << minutesStr << ":" << std::setw(2) << secondsStr;
-
-  return ss.str();
-}
-int TraingModel::CalculateAverageHeartRate(int newHeartRate) {
-  // 将新的心率添加到数据列表
-  heartRateData.push_back(newHeartRate);
-  totalHeartRate += newHeartRate;
-  countHeartRate++;
-
-  // 将新的心率插入到堆中
-  maxHeap.push(newHeartRate);
-  minHeap.push(newHeartRate);
-
-  // 如果超过窗口大小,移除最早的心率
-  if (heartRateData.size() > windowSize) {
-    int oldestRate = heartRateData[0];
-    totalHeartRate -= oldestRate;
-    countHeartRate--;
-
-    // 将老旧值从列表中移除
-    heartRateData.erase(heartRateData.begin());
-
-    // 标记老旧值为待删除
-    delayed[oldestRate]++;
-  }
-
-  // 清理堆中的老旧值
-  while (!maxHeap.empty() && delayed[maxHeap.top()] > 0) {
-    delayed[maxHeap.top()]--;
-    maxHeap.pop();
-  }
-
-  while (!minHeap.empty() && delayed[minHeap.top()] > 0) {
-    delayed[minHeap.top()]--;
-    minHeap.pop();
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                "新心率: %d, 当前心率总和: %d, 心率计数: %d", newHeartRate,
-                totalHeartRate, countHeartRate);
-
-  // 如果心率数量少于 3,直接返回当前的平均值
-  if (countHeartRate < 3) {
-    return totalHeartRate / countHeartRate; // 无法去除最大最小值
-  }
-
-  // 取出当前未被删除的最大和最小的心率
-  int maxRate = maxHeap.top();
-  int minRate = minHeap.top();
-
-  // 进行去极值后的平均计算
-  int average = (totalHeartRate - maxRate - minRate) / (countHeartRate - 2);
-
-  // 打印计算结果
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                "去极值后的平均心率: %d (去掉最大值: %d, 去掉最小值: %d)",
-                average, maxRate, minRate);
-
-  return average;
-}
-// 显示心率
-int TraingModel::CalculateFilteredHeartRate(int newHeartRate) {
-  // 将新的心率添加到最近心率列表
-  recentHeartRates.push_back(newHeartRate);
-
-  // 如果超过窗口大小,移除最早的心率
-  if (recentHeartRates.size() > windowSize) {
-    recentHeartRates.erase(recentHeartRates.begin());
-  }
-
-  // 计算当前窗口中的平均心率
-  int total =
-      std::accumulate(recentHeartRates.begin(), recentHeartRates.end(), 0);
-
-  // 打印当前窗口的平均心率
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "过滤后当前窗口的平均心率: %d",
-                (total / recentHeartRates.size()));
-
-  return total / recentHeartRates.size(); // 返回计算后的平均值
-}
-int TraingModel::Averageheartrate(int newHeartRate) {
-  heartcount++;
-  totalHeartRate += newHeartRate;
-  return totalHeartRate / heartcount; // 返回计算的平均值
-}
-// 设置训练目标类型以及训练目标
-void TraingModel::SetSportTag(ExerciseTag tagtpye, int tag) {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "设置目标 tagtpye[%d] tag[%d]",
-                tagtpye, tag);
-  sportTagType_ = tagtpye;
-  sportTag_ = tag;
-}
-
-/* 设置训练强度 */
-void TraingModel::SetIntensity(int heart) {
-  // sportdata->intensity = active_state;
-  /*
-      训练强度
-      220-年龄=最高心率
-
-      分为四个强度区间
-      较低强度=最高心率*59%以下
-      中等强度=最高心率*60%~69%
-      高等强度=最高心率*70%~79%
-      超高强度=最高心率*80%以上
+ bool TraingModel::GetSportExtraData(void) {
+ #ifdef SUPPORT_CYWEE_SERVICE
+   act_ext_result_t cyweeInfo_ext;
+   cywee_get_act_ext_data(&cyweeInfo_ext);
+   TraingModel::GetInstance()->AnalysisExtraData(&cyweeInfo_ext);
+ #endif
+   return true;
+ }
+ 
+ /*
+  * @brief 获取心率数据
+  * @return 获取到的心率值,如果服务不支持则返回0
   */
-  // 确保最大心率为正值
-  if (user_Intensity <= 0) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "maxHeartRate %d is error",
-                  user_Intensity);
-    return;
-  }
-
-  // 将 heart 转换为 double 以避免整数除法
-  double heartRateAsDouble = static_cast<double>(heart);
-  double intensityPercentage =
-      (heartRateAsDouble / (double)user_Intensity) * 100;
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                "heart: %d, maxHeartRate: %d, intensityPercentage: %.2f", heart,
-                HeartModel, intensityPercentage);
-
-  if (intensityPercentage < LOW_INTENSITY_THRESHOLD) {
-    // 较低强度
-    sportdata->intensity = LOW_INTENSITY;
-  } else if (intensityPercentage >= MEDIUM_INTENSITY_LOWER_THRESHOLD &&
-             intensityPercentage <= MEDIUM_INTENSITY_UPPER_THRESHOLD) {
-    // 中等强度
-    sportdata->intensity = MEDIUM_INTENSITY;
-  } else if (intensityPercentage >= HIGH_INTENSITY_LOWER_THRESHOLD &&
-             intensityPercentage <= HIGH_INTENSITY_UPPER_THRESHOLD) {
-    // 高等强度
-    sportdata->intensity = HIGH_INTENSITY;
-  } else {
-    // 超高强度
-    sportdata->intensity = VERY_HIGH_INTENSITY;
-  }
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                "maxHeartRate: %d, heartRate: %d, intensityPercentage: %.2f",
-                maxHeartRate, heart, intensityPercentage);
-}
-/*获取训练强度STR*/
-UIResourceTextId TraingModel::GetIntensity() {
-  switch (sportdata->intensity) {
-  case LOW_INTENSITY:
-    return UIResourceTextId::STR_LOWER_STRENGTH;
-    break;
-  case MEDIUM_INTENSITY:
-    return UIResourceTextId::STR_MEDIUM_STRENGTH;
-    break;
-  case HIGH_INTENSITY:
-    return UIResourceTextId::STR_HIGH_STRENGTH;
-    break;
-  case VERY_HIGH_INTENSITY:
-    return UIResourceTextId::STR_ULTRA_HIGH_STRENGTH;
-    break;
-  default:
-    return UIResourceTextId::STR_LOWER_STRENGTH;
-    break;
-  }
-}
-
-/*
-时长:10~600分钟 实际出值 秒
-距离:1~20km  实际出值 m
-步数:500~50000步 实际出值 步
-卡路里:100~1000kcal 实际出值 kcal
-*/
-
-/* 获取当前的目标值 */
-int TraingModel::GetSportTagData() {
-  if (sportdata->tag == 0 || current_goal == 0) {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
-    return 0;
-  }
-
-  float goaldegree = 0.0f; // 初始化目标完成度
-
-  // 根据设置的训练目标类型去对应相对的数据
-  switch (sportdata->sportTagType) {
-  case ExerciseTag::Duration: {
-    // 计算完成度
-    goaldegree = (static_cast<float>(sportdata->duration) / current_goal) * 100;
-    break;
-  }
-  case ExerciseTag::Calories: {
-    // 计算目标完成度
-    goaldegree = (static_cast<float>(sportdata->calories) / current_goal) * 100;
-    break;
-  }
-  case ExerciseTag::Distance: {
-    // 计算目标完成度
-    goaldegree = (static_cast<float>(sportdata->distance) / current_goal) * 100;
-    break;
-  }
-  case ExerciseTag::Steps: {
-    // 计算目标完成度
-    goaldegree = (static_cast<float>(sportdata->steps) / current_goal) * 100;
-    break;
-  }
-  default:
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->sportTagType is error");
-    return 0;
-    break;
-  }
-
-  WEARABLE_LOGD(
-      WEARABLE_LOG_MODULE_APP,
-      " [goaldegree %d, sportdata->tag %d, sportdata->duration %d, "
-      "sportdata->calories %d,sportdata->distance %d, sportdata->steps %d]",
-      goaldegree, sportdata->tag, sportdata->duration, sportdata->calories,
-      sportdata->distance, sportdata->steps);
-
-  return static_cast<int>(round(goaldegree)); // 返回目标完成度
-}
-
-//获取目标值
-uint32_t TraingModel::GetCurrentSportTag() {
-  if (sportdata->tag == 0) {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
-    return 0;
-  }
-
-  float goaldegree = 0.0f; // 初始化目标完成度
-
-  // 根据设置的训练目标类型去对应相对的数据
-  switch (sportdata->sportTagType) {
-  case ExerciseTag::Duration: {
-    // 转换目标时长为秒
-    return static_cast<float>(sportdata->tag * 60);
-    break;
-  }
-  case ExerciseTag::Calories: {
-    // 计算目标完成度
-    return sportdata->tag;
-    break;
-  }
-  case ExerciseTag::Distance: {
-    return static_cast<float>(sportdata->tag * 1000);
-    break;
-  }
-  case ExerciseTag::Steps: {
-    return sportdata->tag;
-    break;
-  }
-  default:
-    return 0;
-    break;
-  }
-}
-//获取是否达到目标 使用比较
-bool TraingModel::IsGetGoaldegree() {
-  if (sportdata->tag == 0) {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
-    return false;
-  }
-
-  float goaldegree = 0.0f; // 初始化目标完成度
-
-  // 根据设置的训练目标类型去对应相对的数据
-  switch (sportdata->sportTagType) {
-  case ExerciseTag::Calories: {
-    // 计算目标完成度
-    if (sportdata->calories >= current_goal) {
-      return true;
-    }
-    return false;
-    break;
-  }
-  case ExerciseTag::Distance: {
-    if (sportdata->distance >= current_goal) {
-      return true;
-    }
-    return false;
-    break;
-  }
-  case ExerciseTag::Steps: {
-    if (sportdata->steps >= current_goal) {
-      return true;
-    }
-    return false;
-    break;
-  }
-  default:
-    return false;
-    break;
-  }
-}
-
-/* 获取训练目标完成百分比 */
-int TraingModel::GetGoaldegree() {
-  if (sportdata->tag == 0) {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
-    return 0; // 如果目标值为 0,返回 0%
-  }
-
-  int goaldegree = GetSportTagData();
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "goaldegree %d", goaldegree);
-  return goaldegree; // 直接返回目标完成度
-}
-
-void TraingModel::updata_goal() {
-  if (sportdata->tag == 0)
-    return;
-
-  sportdata->goaldegree = GetGoaldegree();
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->goaldegree %d",
-                sportdata->goaldegree);
-}
-
-/* 训练目标校验 */
-void TraingModel::CheckSportTag() {
-  // 运动开始才计算
-  if (sportdata->tag && sportdata->sportTagType != ExerciseTag::Duration) {
-    if (IsGetGoaldegree() && !Gettagstuats) {
-      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "目标完成");
-      uapi_set_screen_on_api(); // 亮屏检测
-      if (!OHOS::ConfigModel::GetInstance()->GetDnotdisturb()) {
-        custom_VibratorFunc_int(0); // 震动提示
-      }
-      if (TraingCardView::GetInstance()) {
-        GraphicService::GetInstance()->PostGraphicEvent(
-            std::bind(&TraingCardView::SetPopupViewStatus,
-                      TraingCardView::GetInstance(), GetTagPopup, true));
-        auto animator = TraingCardView::GetInstance()->GetAnimator();
-        if (animator) {
-          animator->Start(); // 启动动画
-        }
-      }
-      Gettagstuats = true; // 更新状态
-    }
-  }
-}
-// 校验时间获取目标
-void TraingModel::CheckTimeTag() {
-  if (sportdata->tag == 0 || sportdata->sportTagType != ExerciseTag::Duration) {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->tag is 0");
-    return;
-  }
-  if (sportdata->duration == current_goal && !Gettagstuats) {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "目标完成");
-    uapi_set_screen_on_api(); // 亮屏检测
-    if (!OHOS::ConfigModel::GetInstance()->GetDnotdisturb()) {
-      custom_VibratorFunc_int(0); // 震动提示
-    }
-    if (TraingCardView::GetInstance()) {
-      GraphicService::GetInstance()->PostGraphicEvent(
-          std::bind(&TraingCardView::SetPopupViewStatus,
-                    TraingCardView::GetInstance(), GetTagPopup, true));
-      auto animator = TraingCardView::GetInstance()->GetAnimator();
-      if (animator) {
-        animator->Start(); // 启动动画
-      }
-    }
-    Gettagstuats = true; // 更新状态
-  }
-}
-
-//获取运动时长
-int TraingModel::GetDuration() { return sportdata->duration; }
-/*获取训练类型Id*/
-UIResourceTextId TraingModel::GetSportTypeId(Exercisetype type) {
-  // 根据设置的训练类型去对应相对的数据
-  switch (type) {
-  // 健身类
-  case Exercisetype::FITNESS:
-    return STR_EXERCISE_LIST;
-  // 舞蹈类
-  case Exercisetype::DANCE:
-    return STR_DANCING_LIST;
-  // 休闲运动
-  case Exercisetype::LEISURE:
-    return STR_RECREATIONAL_LIST;
-  // 球类
-  case Exercisetype::BALL:
-    return STR_BALL_LIST;
-  // 水上运动
-  case Exercisetype::WATER:
-    return STR_WATER_LIST;
-  // 冰上运动
-  case Exercisetype::ICE:
-    return STR_ICE_LIST;
-  // 极限运动
-  case Exercisetype::EXTREME:
-    return STR_EXTREME_LIST;
-  // 其他
-  case Exercisetype::OTHER:
-    return STR_OTHER_LIST;
-  default:
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Not ExerciseClass type!");
-    break;
-  }
-
-  return STR_EXERCISE_LIST; // 添加默认返回值[健身类]
-}
-/*打印存储数据*/
-void TraingModel::printTrainingData(const Trainingdata &data) {
-  printf("Trainingdata:\n");
-  printf("src: %d\n", data.src);
-  printf("bt: %u\n", data.bt);
-  printf("ty: %u\n", data.ty);
-  printf("st: %u\n", data.st);
-  printf("sp: %u\n", data.sp);
-  printf("tgt: %u\n", data.tgt);
-  printf("tg: %u\n", data.tg);
-  printf("pg: %u\n", data.pg);
-  printf("du: %u\n", data.du);
-  printf("ca: %u\n", data.ca);
-  printf("di: %u\n", data.di);
-  printf("hr: %u\n", data.hr);
-  printf("stp: %u\n", data.stp);
-  printf("ti: %u\n", data.ti);
-  printf("cir: %u\n", data.cir);
-  printf("alt: %u\n", data.alt);
-}
-
-/*
-    uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练
-    uint32_t bt;  // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4
-   - 水上项目,5 - 冰上项目,6 - 极限运动,7 - 其他 uint32_t ty;  //
-   训练类型:自由训练 uint32_t st;  // 开始时间戳(单位:秒) uint32_t sp;  //
-   结束时间戳(单位:秒) uint32_t tgt; // 训练目标类型:0 - 距离,1 - 卡路里,2
-   - 时间,3 - 步数 uint32_t tg;  //
-   训练目标值:路程(单位:米),卡路里(单位:kcal),时间(单位:分钟),步数(单位:步)
-    uint32_t pg;  // 目标完成度(单位:%)
-    uint32_t du;  // 训练总时长(单位:秒)
-    uint32_t ca;  // 消耗卡路里(单位:kcal)
-    uint32_t di;  // 完成的距离(单位:米)
-    uint32_t hr;  // 平均心率
-    uint32_t stp; // 步数
-    uint32_t ti;  // 训练强度:0 - 较低强度,1 - 中等强度,2 - 高等强度,3 -
-   超高强度 uint32_t cir; // 圈数 uint32_t alt; // 最高海拔高度
-*/
-/*保存数据*/
-bool TraingModel::SaveSportData() {
-
-  // 配置训练存储状态
-  uapi_dev_runtime_set_train_storage_status(1);
-
-  Trainingdata data;
-  data.src = Openingway;
-  data.bt = static_cast<uint32_t>(sportdata->sportType);
-  data.ty = static_cast<uint32_t>(GetBleSportId(sportdata->sportType, sportdata->sportId));
-  data.st = static_cast<uint32_t>(sportdata->starttime);
-  data.sp = static_cast<uint32_t>(sportdata->endtime);
-  data.tgt = static_cast<uint32_t>(sportdata->sportTagType);
-  if (sportdata->sportTagType == ExerciseTag::Distance) {
-    data.tg = static_cast<uint32_t>(sportdata->tag * 1000);
-  } else {
-    data.tg = static_cast<uint32_t>(sportdata->tag);
-  }
-  data.pg = static_cast<uint32_t>(sportdata->goaldegree);
-  data.du = static_cast<uint32_t>(sportdata->duration);
-  data.ca = static_cast<uint32_t>(sportdata->calories * 10);
-  data.di = static_cast<uint32_t>(sportdata->distance);
-  data.hr = static_cast<uint32_t>(sportdata->avgheart);
-  data.stp = static_cast<uint32_t>(sportdata->steps);
-  data.ti = static_cast<uint32_t>(sportdata->intensity);
-  /* 230 目前不支持【圈数】【最高海拔高度】 */
-  data.cir = 0;
-  data.alt = 0;
-  /* 配速相关 */
-  data.apc = static_cast<uint32_t>(sportdata->apc);
-  data.fpc = static_cast<uint32_t>(sportdata->fpc);
-  data.spc = static_cast<uint32_t>(sportdata->spc);
-  data.std = static_cast<uint32_t>(sportdata->std);
-  data.cdc = static_cast<uint32_t>(sportdata->cdc);
-
-  // 创建sport文件夹
-  CreateDirectoryIfNotExists(TRAINING_DATA_DIRECTORY);
-
-  // 保存数据到 bin
-  if (write_Trainingdata_data(data) != 1) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "write_Trainingdata_data is error!");
-    uapi_dev_runtime_set_train_storage_status(0); // 恢复状态
-    return false;
-  }
-
-  // 保存数据到 json
-  if (!SaveDataToJson(sportdata)) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDataToJson is error!");
-    uapi_dev_runtime_set_train_storage_status(0); // 恢复状态
-    return false;
-  }
-
-  if (isspecialsport_) {
-    // 保存心率表
-    if (!SaveHeartTable()) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveHeartRateData is error!");
-      // uapi_dev_runtime_set_train_storage_status(0); // 恢复状态
-      // return false;
-    }
-    // 保存速度表
-    if (!SavePaceTable()) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveSpeedData is error!");
-      // return false;
-    }
-    // 保存GPS数据
-    if (!SaveCanvasData()) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveCanvasData is error!");
-      return false; //必须手表端存储成功
-    }
-    if (!SaveGPSData()) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData is error!");
-      // return false;
-    }
-  }
-
-  // 如果所有操作成功,则恢复训练存储状态
-  uapi_dev_runtime_set_train_storage_status(0);
-  return true;
-}
-/*设置进入方式*/
-void TraingModel::SetEntryType(ENTEYTYPE type) { entey_type = type; }
-/*获取进入方式*/
-ENTEYTYPE TraingModel::GetEntryType() { return entey_type; }
-/*设置开启方式*/
-void TraingModel::SetSportOpenWay(bool way) { Openingway = way; }
-/*设置运动是否开始*/
-void TraingModel::SetSportOpenState(bool state) { Openstate = state; }
-/*获取运动是否开始*/
-bool TraingModel::GetSportOpenState() { return Openstate; }
-/*获取运动时长*/
-uint32_t TraingModel::GetSportTime() { return sportdata->duration; }
-/*获取训练量是否达标*/
-bool TraingModel::GetMomentum() {
-#if 0
-         int caldata = TraingModel::GetInstance()->GetCal();
-         /*判断是否产生至少1Kcald的运动量*/
-         if (caldata >= 1)
+ uint8_t TraingModel::GetHeartRateData(void) {
+   uint8_t hrs = 0;
+ #ifdef SUPPORT_PPG_SERVICE
+   hrs = ppg_get_hrs();
+ #endif
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Heart rate data: %d", hrs);
+   return hrs;
+ }
+ 
+ static void sport_data_time_proc(int data) {
+   //增加训练runtime控制
+   if (uapi_dev_runtime_get_train_status() == 0 ||
+       TraingModel::GetInstance()->GetSportState() == ExerciseState::End) {
+     return;
+   }
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sport_data_time_proc");
+ 
+   // 获取并处理运动基础数据
+   TraingModel::GetInstance()->GetSportActivityData();
+ 
+   // 获取并处理运动额外数据 前提是特殊运动
+   if (TraingModel::GetInstance()->GetIsSpecial()) {
+     TraingModel::GetInstance()->GetSportExtraData();
+   }
+ 
+   // 获取并处理心率数据
+   uint8_t heartRate = TraingModel::GetInstance()->GetHeartRateData();
+   TraingModel::GetInstance()->AnalysisHeartData(heartRate);
+ 
+   // 更新UI
+   if (TraingCardPresenter::GetInstance()) {
+     TraingCardPresenter::GetInstance()->updataview();
+   }
+ }
+ 
+ static void sport_data_time_callback(int data) {
+   GraphicService::GetInstance()->PostGraphicEvent(
+       std::bind(sport_data_time_proc, data));
+ }
+ 
+ void TraingModel::sport_start_data_timer(uint32_t interval) {
+   WEARABLE_LOGE(
+       WEARABLE_LOG_MODULE_APP,
+       "TraingModel::sport_start_data_timer - Starting sport data timer");
+   if (g_sport_start_data_timer != nullptr) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sport Data Timer already exists!!");
+     return;
+   }
+   g_sport_start_data_timer = osTimerNew((osTimerFunc_t)sport_data_time_callback,
+                                         osTimerPeriodic, nullptr, nullptr);
+   if (g_sport_start_data_timer == nullptr) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sport Data Timer create failed!!");
+     return;
+   }
+   int tick = osMs2Tick(interval);
+   osStatus_t ret = osTimerStart(g_sport_start_data_timer, tick);
+   if (ret != osOK) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                   "Sport Data Timer start failed, ret = %lx!!", ret);
+     if (g_sport_start_data_timer != nullptr) {
+       ret = osTimerDelete(g_sport_start_data_timer);
+     }
+     g_sport_start_data_timer = nullptr;
+     return;
+   }
+ }
+ 
+ void TraingModel::sport_stop_data_timer(void) {
+   // 检查运动数据采集定时器是否存在
+   if (g_sport_start_data_timer != nullptr) {
+     WEARABLE_LOGE(
+         WEARABLE_LOG_MODULE_APP,
+         "TraingModel::sport_stop_data_timer - Stopping sport data timer");
+     osTimerStop(g_sport_start_data_timer);
+     // 删除定时器并置为 nullptr
+     osStatus_t ret = osTimerDelete(g_sport_start_data_timer);
+     if (ret != osOK) {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "Sport Data Timer delete failed, ret = %lx!!", ret);
+     }
+     g_sport_start_data_timer = nullptr;
+   }
+ }
+ #endif
+ 
+ #ifdef BLE_INSTRUCT
+ 
+ #include "bleEvent.h"
+ #include "bleInstruct.h"
+ 
+ //////////////////////////////ble////////////////////////////////////////////
+ #ifdef __cplusplus
+ #if __cplusplus
+ extern "C" {
+ #endif /* __cplusplus */
+ #endif /* __cplusplus */
+ 
+ bool get_training_spead_path_(char *path, uint32_t time, uint32_t max_len) {
+   std::string str = OHOS::TraingModel::GetInstance()->GetPaceTablePath(time);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "get_training_spead:%s\r\n",
+                 str.c_str());
+   if (str.length() <= 3) {
+     return false;
+   }
+   memcpy_s(path, max_len, str.c_str(), str.length());
+   return true;
+ }
+ 
+ bool get_training_heart_path_(char *path, uint32_t time, uint32_t max_len) {
+   std::string str = OHOS::TraingModel::GetInstance()->GetHeartTablePath(time);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "get_training_heart:%s\r\n",
+                 str.c_str());
+   if (str.length() <= 3) {
+     return false;
+   }
+   memcpy_s(path, max_len, str.c_str(), str.length());
+   return true;
+ }
+ 
+ //获取gps轨迹路径
+ bool get_training_gps_path_(char *path, uint32_t time, uint32_t max_len) {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 获取GPS轨迹路径开始 ===");
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "请求时间戳: %u, 最大路径长度: %u",
+                 time, max_len);
+ 
+   std::string str = OHOS::TraingModel::GetInstance()->GetGPSDataPath(time);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "获取到的GPS路径: %s", str.c_str());
+ 
+   if (str.length() <= 3) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "错误: GPS路径长度不足,长度: %zu",
+                   str.length());
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 获取GPS轨迹路径结束(失败) ===");
+     return false;
+   }
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS路径长度: %zu", str.length());
+   memcpy_s(path, max_len, str.c_str(), str.length());
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS路径复制完成");
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 获取GPS轨迹路径结束(成功) ===");
+   return true;
+ }
+ 
+ char *struct_to_json_buf_malloc_(uint8_t day) {
+   cJSON *dataJSON = cJSON_CreateObject();
+   cJSON *data_arryJSON = cJSON_CreateArray();
+   struct Trainingdata *data = NULL;
+   int i = 0;
+   // char file_path[128] = {0};
+   char timeday[12] = {0};
+   uapi_get_YYMMDD_Time_extend(timeday, '_', day);
+   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%s\r\n", timeday);
+   // sprintf(file_path, "%s%s.bin", TRAINING_PATH_BLE, timeday);
+ 
+   while (data = read_Trainingdata_data(timeday, i)) {
+     cJSON *itemJSON = cJSON_CreateObject();
+     if (data != NULL) {
+       cJSON_AddNumberToObject(itemJSON, "src", data->src);
+       cJSON_AddNumberToObject(itemJSON, "bt", data->bt);
+       cJSON_AddNumberToObject(itemJSON, "ty", data->ty);
+       cJSON_AddNumberToObject(itemJSON, "st", data->st);
+       cJSON_AddNumberToObject(itemJSON, "sp", data->sp);
+       cJSON_AddNumberToObject(itemJSON, "tgt", data->tgt);
+       cJSON_AddNumberToObject(itemJSON, "tg", data->tg);
+       cJSON_AddNumberToObject(itemJSON, "pg", data->pg);
+       cJSON_AddNumberToObject(itemJSON, "du", data->du);
+       cJSON_AddNumberToObject(itemJSON, "ca", data->ca);
+       cJSON_AddNumberToObject(itemJSON, "di", data->di);
+       cJSON_AddNumberToObject(itemJSON, "hr", data->hr);
+       cJSON_AddNumberToObject(itemJSON, "stp", data->stp);
+       cJSON_AddNumberToObject(itemJSON, "ti", data->ti);
+       cJSON_AddNumberToObject(itemJSON, "cir", data->cir);
+       cJSON_AddNumberToObject(itemJSON, "alt", data->alt);
+       cJSON_AddNumberToObject(itemJSON, "apc", data->apc);
+       cJSON_AddNumberToObject(itemJSON, "fpc", data->fpc);
+       cJSON_AddNumberToObject(itemJSON, "spc", data->spc);
+       cJSON_AddNumberToObject(itemJSON, "std", data->std);
+       cJSON_AddNumberToObject(itemJSON, "cdc", data->cdc);
+       cJSON_AddItemReferenceToArray(data_arryJSON, itemJSON);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"src:%d",data->src);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"bt:%d",data->bt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ty:%d",data->ty);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"st:%d",data->st);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sp:%d",data->sp);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tgt:%d",data->tgt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tg:%d",data->tg);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"pg:%d",data->pg);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"du:%d",data->du);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ca:%d",data->ca);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"di:%d",data->di);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hr:%d",data->hr);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"stp:%d",data->stp);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ti:%d",data->ti);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cir:%d",data->cir);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"alt:%d",data->alt);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"apc:%d",data->apc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"fpc:%d",data->fpc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"spc:%d",data->spc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"std:%d",data->std);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cdc:%d",data->cdc);
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
+       free(data);
+       data = NULL;
+     } else {
+       break;
+     }
+     i++;
+   }
+   cJSON_AddItemToObject(dataJSON, "recs", data_arryJSON);
+ 
+   char *json_format = cJSON_PrintUnformatted(dataJSON);
+ 
+   int pSize = cJSON_GetArraySize(dataJSON);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "训练历史数据:%s\r\n", json_format);
+   cJSON_Delete(dataJSON);
+   return json_format;
+ }
+ 
+ int read_gps_data_(char *path, uint8_t *out_buf) {
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 读取GPS数据开始 ===");
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件路径: %s", path);
+ 
+   FILE *fp = fopen(path, "rb+");
+   if (fp == NULL) {
+     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "错误: 无法打开GPS文件");
+     return 0;
+   }
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件打开成功");
+ 
+   uint32_t file_size = 0;
+   fseek(fp, 0, SEEK_END);
+   file_size = ftell(fp);
+   fseek(fp, 0, SEEK_SET);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件大小: %u 字节", file_size);
+ 
+   int len = 0;
+   int point_count = 0;
+   OHOS::GPSData_t data = {0};
+ 
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始读取GPS轨迹点...");
+   while (1) {
+     int read_size = fread(&data, 1, sizeof(data), fp);
+     if (read_size == sizeof(data)) {
+       point_count++;
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "读取GPS点 #%d: 时间戳=%u, 纬度=%.6f, 经度=%.6f",
+                     point_count, data.timestamp, data.latitude, data.longitude);
+ 
+       int temp_data = data.timestamp;
+       memcpy_s(out_buf + len, 4, &temp_data, sizeof(data.timestamp));
+       len += 4;
+ 
+       int temp_latitude = (int)(data.latitude * 10000000);
+       memcpy_s(out_buf + len, 4, &temp_latitude, sizeof(temp_latitude));
+       len += 4;
+ 
+       int temp_longitude = (int)(data.longitude * 10000000);
+       memcpy_s(out_buf + len, 4, &temp_longitude, sizeof(temp_longitude));
+       len += 4;
+ 
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                     "GPS点数据转换: 时间戳=%u, 纬度=%d, 经度=%d", temp_data,
+                     temp_latitude, temp_longitude);
+     } else {
+       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件读取结束,读取大小: %d",
+                     read_size);
+       break;
+     }
+   }
+ 
+   fclose(fp);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件关闭");
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                 "总共读取 %d 个GPS点,输出数据长度: %d 字节", point_count, len);
+   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 读取GPS数据结束 ===");
+ 
+   return len;
+ }
+ 
+ //通过时间戳获取训练数据
+ cJSON* ble_get_Trainingdata_by_timetamp_(uint32_t timetamp)
+ {
+     struct Trainingdata * data=NULL;
+     int i=0;
+   
+     time_t currtime=timetamp;
+     struct tm *timeinfo;
+     timeinfo = localtime(&currtime);
+     int y=timeinfo->tm_year+ 1900;
+     int m=timeinfo->tm_mon+1;
+     int d=timeinfo->tm_mday;
+     int h=timeinfo->tm_hour;
+     int min=timeinfo->tm_min;
+ 
+     char timeday[24]={0};
+     sprintf_s(timeday,24,"%d_%02d_%02d",y,m,d);
+ 
+     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"%s\r\n",timeday);
+ 
+     while(data=read_Trainingdata_data(timeday, i))
+     {
+         if(data!=NULL)
          {
-             MomentumFlag = true;
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"%d,%d\r\n",timetamp,data->st);
+             // 打印data数据
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"src:%d",data->src);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"bt:%d",data->bt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ty:%d",data->ty);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"st:%d",data->st);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sp:%d",data->sp);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tgt:%d",data->tgt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tg:%d",data->tg);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"pg:%d",data->pg);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"du:%d",data->du);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ca:%d",data->ca);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"di:%d",data->di);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hr:%d",data->hr);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"stp:%d",data->stp);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ti:%d",data->ti);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cir:%d",data->cir);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"alt:%d",data->alt);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"apc:%d",data->apc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"fpc:%d",data->fpc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"spc:%d",data->spc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"std:%d",data->std);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cdc:%d",data->cdc);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
+             int time_error= timetamp>data->st ? timetamp-data->st:data->st-timetamp;
+             if(time_error<=2)
+             {
+                 cJSON* itemJSON = cJSON_CreateObject();
+                 cJSON_AddNumberToObject(itemJSON, "src", data->src);
+                 cJSON_AddNumberToObject(itemJSON,"bt",data->bt);
+                 cJSON_AddNumberToObject(itemJSON,"ty",data->ty);
+                 cJSON_AddNumberToObject(itemJSON,"st",data->st);
+                 cJSON_AddNumberToObject(itemJSON,"sp",data->sp);
+                 cJSON_AddNumberToObject(itemJSON,"tgt",data->tgt);
+                 cJSON_AddNumberToObject(itemJSON,"tg",data->tg);
+                 cJSON_AddNumberToObject(itemJSON,"pg",data->pg);
+                 cJSON_AddNumberToObject(itemJSON,"du",data->du);
+                 cJSON_AddNumberToObject(itemJSON,"ca",data->ca);
+                 cJSON_AddNumberToObject(itemJSON,"di",data->di);
+                 cJSON_AddNumberToObject(itemJSON,"hr",data->hr);
+                 cJSON_AddNumberToObject(itemJSON,"stp",data->stp);
+                 cJSON_AddNumberToObject(itemJSON,"ti",data->ti);
+                 cJSON_AddNumberToObject(itemJSON,"cir",data->cir);
+                 cJSON_AddNumberToObject(itemJSON, "alt", data->alt);
+                 cJSON_AddNumberToObject(itemJSON,"apc",data->apc);
+                 cJSON_AddNumberToObject(itemJSON,"fpc",data->fpc);
+                 cJSON_AddNumberToObject(itemJSON,"spc",data->spc);
+                 cJSON_AddNumberToObject(itemJSON,"std",data->std);
+                 cJSON_AddNumberToObject(itemJSON,"cdc",data->cdc);
+                 free(data);
+                 return itemJSON;
+             }
+ 
+             free(data);
+             data=NULL;
          }
-         else
-         {
-             MomentumFlag = false;
+         else{
+             break;
          }
-#endif
-  int duration = sportdata->duration;
-  //判断运动时间是否大于1分钟
-  if (duration >= 60) {
-    MomentumFlag = true;
-  } else {
-    MomentumFlag = false;
-  }
-  return MomentumFlag;
-}
-
-//用户运动数据配置
-void TraingModel::SetUserSportdata() {
-  // 获取用户的最高心率提醒
-  user_maxHeart = ConfigModel::GetInstance()->get_configData_int(
-      ConfigModel::CONFIGMODEL_ITEM_TRAINING_HEART_MAX);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "用户最高心率提醒: %d", user_maxHeart);
-
-  // 获取用户年龄
-  user_Age = ConfigModel::GetInstance()->GetUserAge();
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "用户年龄: %d", user_Age);
-
-  // 获取自动训练设置
-  user_autoget = ConfigModel::GetInstance()->get_configData_int(
-      ConfigModel::CONFIGMODEL_ITEM_TRANING_AUTO);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "自动获取设置: %d", user_autoget);
-
-  // 获取训练频率设置
-  user_freq = ConfigModel::GetInstance()->get_configData_int(
-      ConfigModel::CONFIGMODEL_ITEM_TRANING_FREQ);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "训练频率: %d", user_freq);
-
-  user_Intensity = MAX_HEART_RATE_TRAINING - user_Age;
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "用户运动强度心率: %d",
-                user_Intensity);
-}
-//运动过程中更新心率配置
-void TraingModel::SetMaxHeart(int maxheart) {
-  // 获取用户运动数据配置
-  user_maxHeart = maxheart;
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "用户最高心率: %d", user_maxHeart);
-}
-/*配速表与心率表相关*/
-//清空心率表
-void TraingModel::ClearHeartTable() {
-  heartRateTable.clear(); // 清空心率数据表
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Heart Rate Table Cleared.\r\n");
-}
-//清空配速表
-void TraingModel::ClearPaceTable() {
-  paceTable.clear(); // 清空配速数据表
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Pace Table Cleared.\r\n");
-}
-// 添加心率数据
-bool TraingModel::AddHeartRateData(uint32_t timestamp, uint8_t heartRate) {
-  // 检查重复时间戳
-  for (const auto &entry : heartRateTable) {
-    if (entry.timestamp == timestamp) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "时间戳重复无法添加数据 AddHeartRateData is error!");
-      return false; // 返回重复
-    }
-  }
-
-  if (heartRateTable.size() >= MAX_ENTRIES) {
-    WEARABLE_LOGE(
-        WEARABLE_LOG_MODULE_APP,
-        "达到最大心率数据条目限制 无法添加新的数据 AddHeartRateData is error!");
-    return false; // 返回条目满了
-  }
-
-  HeartRateEntry newEntry = {timestamp, heartRate};
-  heartRateTable.push_back(newEntry);
-  return true; // 返回成功
-}
-
-// 添加配速数据
-bool TraingModel::AddPaceData(uint32_t timestamp, uint16_t pace) {
-  // 检查重复时间戳
-  for (const auto &entry : paceTable) {
-    if (entry.timestamp == timestamp) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "时间戳重复无法添加数据 AddPaceData is error!"); // 修正这里
-      return false; // 返回重复
-    }
-  }
-
-  if (paceTable.size() >= MAX_ENTRIES) {
-    WEARABLE_LOGE(
-        WEARABLE_LOG_MODULE_APP,
-        "达到配速数据条目限制 无法添加新的数据 AddPaceData is error!");
-    return false; // 返回条目满了
-  }
-
-  PaceEntry newEntry = {timestamp, pace};
-  paceTable.push_back(newEntry);
-  return true; // 返回成功
-}
-//心率表打印
-void TraingModel::PrintHeartRateTable() {
-  size_t heartRateCount = heartRateTable.size();
-  if (heartRateCount == 0) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "心率表为空,无法打印。");
-    return;
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Heart Rate Table:");
-  for (const auto &entry : heartRateTable) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "时间戳: %u, 心率: %d",
-                  entry.timestamp, entry.heartRate);
-  }
-}
-//配速表打印
-void TraingModel::PrintPaceTable() {
-  size_t paceCount = paceTable.size();
-  if (paceCount == 0) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配速表为空,无法打印。");
-    return;
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Pace Table:");
-  for (const auto &entry : paceTable) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "时间戳: %u, 配速: %d",
-                  entry.timestamp, entry.pace);
-  }
-}
-// 保存心率表
-bool TraingModel::SaveHeartTable() {
-
-  //打印数组
-  PrintHeartRateTable();
-
-  CreateDirectoryIfNotExists(TRAINING_HEART_FILE);
-
-  size_t heartRateCount = heartRateTable.size();
-  if (heartRateCount == 0) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "心率表为空,无法保存。");
-    return false;
-  }
-
-  std::string filePath =
-      TRAINING_HEART_FILE + std::to_string(sportdata->starttime) + ".bin";
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveHeartTable filePath: %s",
-                filePath.c_str());
-  std::ofstream heartRateFile(filePath, std::ios::binary);
-  if (!heartRateFile) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
-                  filePath.c_str());
-    return false; // 返回失败
-  }
-
-  // 存储表数据
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heartRateCount = %d", heartRateCount);
-  if (!heartRateFile.write(
-          reinterpret_cast<const char *>(heartRateTable.data()),
-          heartRateCount * sizeof(HeartRateEntry))) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入心率数据失败。");
-    return false; // 返回失败
-  }
-
-  heartRateFile.close();
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Heart Rate Table Saved.");
-  return true; // 返回成功
-}
-
-// 保存配速表
-bool TraingModel::SavePaceTable() {
-
-  //打印数组
-  PrintPaceTable();
-
-  CreateDirectoryIfNotExists(TRAINING_PACE_FILE);
-
-  size_t paceCount = paceTable.size();
-  if (paceCount == 0) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配速表为空,无法保存。");
-    return false;
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "paceCount = %d", paceCount);
-
-  std::string filePath =
-      TRAINING_PACE_FILE + std::to_string(sportdata->starttime) + ".bin";
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SavePaceTable filePath: %s",
-                filePath.c_str());
-
-  std::ofstream paceFile(filePath, std::ios::binary);
-  if (!paceFile) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
-                  filePath.c_str());
-    return false; // 返回失败
-  }
-  // 写入配速数据
-  if (!paceFile.write(reinterpret_cast<const char *>(paceTable.data()),
-                      paceCount * sizeof(PaceEntry))) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入配速数据失败。");
-    return false; // 返回失败
-  }
-
-  paceFile.close();
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SavePaceTable Success.");
-  return true; // 返回成功
-}
-// 返回心率表路径
-std::string TraingModel::GetHeartTablePath(uint32_t timestamp) {
-  // 首先检查完全匹配的时间戳
-  std::string exactFilePath =
-      TRAINING_HEART_FILE + std::to_string(timestamp) + ".bin";
-  if (IsFileAccessibleAndNotEmpty(exactFilePath)) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到心率表: %s",
-                  exactFilePath.c_str());
-    return exactFilePath; // 返回完全匹配的文件路径
-  }
-
-  // 如果未找到,检查时间戳相差1到2秒的文件
-  for (int i = -2; i <= 2; ++i) {
-    uint32_t checkTimestamp = timestamp + i;
-    std::string filePath =
-        TRAINING_HEART_FILE + std::to_string(checkTimestamp) + ".bin";
-    if (IsFileAccessibleAndNotEmpty(filePath)) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到心率表: %s",
-                    filePath.c_str());
-      return filePath; // 返回找到的文件路径
-    }
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的心率表。");
-  return ""; // 未找到文件
-}
-
-// 返回配速表路径
-std::string TraingModel::GetPaceTablePath(uint32_t timestamp) {
-  // 首先检查完全匹配的时间戳
-  std::string exactFilePath =
-      TRAINING_PACE_FILE + std::to_string(timestamp) + ".bin";
-  if (IsFileAccessibleAndNotEmpty(exactFilePath)) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到配速表: %s",
-                  exactFilePath.c_str());
-    return exactFilePath; // 返回完全匹配的文件路径
-  }
-
-  // 如果未找到,检查时间戳相差1到2秒的文件
-  for (int i = -2; i <= 2; ++i) {
-    uint32_t checkTimestamp = timestamp + i;
-    std::string filePath =
-        TRAINING_PACE_FILE + std::to_string(checkTimestamp) + ".bin";
-    if (IsFileAccessibleAndNotEmpty(filePath)) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到配速表: %s",
-                    filePath.c_str());
-      return filePath; // 返回找到的文件路径
-    }
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的配速表。");
-  return ""; // 未找到文件
-}
-/*发送实时数据*/
-void TraingModel::SendLiveData() {
-#ifdef SUPPORT_BLE_SERVICE
-  msg_get_train_data_info_t data;
-  memset(&data, 0, sizeof(msg_get_train_data_info_t));
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sportdata->starttime %d \r\n",
-                sportdata->starttime);
-  data.st = sportdata->starttime;
-  data.hr = sportdata->heart;
-  data.ca = sportdata->calories * 10; // app端需要乘10
-  data.di = sportdata->distance;
-  data.stp = sportdata->steps;
-  data.ti = sportdata->intensity;
-  data.pc = sportdata->pc;
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SendLiveData Begin!");
-  sendtraningdata(&data); // 发送数据函数
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SendLiveData Stop!");
-#endif
-}
-/* -------------------------------- 运动识别发起处理
- * -------------------------------- */
-void TraingModel::set_sport_config(UIResourceTextId id) {
-  if (id >= MAXSPORTID) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "id is error");
-    return;
-  }
-  // 开始训练 ->不返回
-  NativeAbility::GetInstance().ChangeSlice(VIEW_TRAININGCRAD);
-  // 配置运动项
-  SetSportEvent(id);
-  // 获取运动项目
-  ExerciseClass type = GetSportId();
-  // 开启对应的运动
-  TraingCardPresenter::GetInstance()->OpenSensor(type);
-  // 设置为手表开启运动
-  SetSportOpenWay(false);
-}
-
-/* -------------------------------------------------------------------------- */
-
-#include <chrono>
-#include <iomanip>
-#include <sstream>
-#include <string>
-
-std::string TraingModel::DisplayMotionDuration() {
-  // 清空 motionDuration
-  motionDuration.clear();
-
-  // 重置运动次数
-  if (g_motionTimes >= NUM_TIME_DAY) {
-    g_motionTimes = 0;
-  }
-
-  // 计算和格式化运动时长
-  int hours = g_motionTimes / NUM_TIME_HOUR;
-  int minutes = (g_motionTimes % NUM_TIME_HOUR) / NUM_TIME_MIN;
-  int seconds = g_motionTimes % NUM_TIME_MIN;
-
-  std::ostringstream oss;
-  oss << std::setfill('0') << std::setw(2) << hours << ":" << std::setw(2)
-      << minutes << ":" << std::setw(2) << seconds;
-
-  motionDuration = oss.str();
-
-  // // 获取当前时间(以微秒为单位)
-  // uint32_t currentTime = static_cast<uint32_t>(
-  //     std::chrono::duration_cast<std::chrono::microseconds>(
-  //         std::chrono::system_clock::now().time_since_epoch())
-  //         .count());
-
-  // // 记录和检查上一次调用的时间
-  // static uint32_t lastCallTime = 0;
-  // if (currentTime - lastCallTime < 1000000) { // 小于1秒
-  //   return motionDuration;
-  // }
-  // lastCallTime = currentTime; // 更新最后调用时间
-
-  // 如果 g_motionTimes 不为零,进行计算和数据存储
-  if (g_motionTimes > 0) {
-    sportdata->duration = g_motionTimes; // 设置训练时长
-
-    // 每分钟进行配速和心率数据存储
-    // StoreDataIfMinutePassed();
-  }
-
-  return motionDuration; // 返回格式化的运动时长
-}
-
-// 检查并发送实时数据
-void TraingModel::SendLiveDataIfNecessary() {
-  // 检查自动获取的配置 app发起
-  if (user_autoget && Openingway) {
-    // 发送实时数据
-    if (g_motionTimes % user_freq == 0) {
-      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SendLiveData is OK\r\n");
-      SendLiveData(); // 发送实时数据
-    }
-  }
-}
-
-// 每5秒进行配速和心率数据存储
-void TraingModel::StoreDataIfMinutePassed() {
-  if (sportdata->duration % 5 == 0) {
-    uint32_t timestamp;
-    //进行数据的筛选
-    if (uapi_get_timestampe_ss(&timestamp) == ERRCODE_SUCC) {
-      if (sportdata->heart != 0)
-        AddHeartRateData(timestamp, sportdata->heart);
-      if (sportdata->apc != 0)
-        AddPaceData(timestamp, sportdata->apc);
-    }
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "duration:[%d] g_motionTimes[%d]\r\n",
-                sportdata->duration, g_motionTimes);
-}
-#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(void) {
-  // 只在活动状态下进行更新
-
-  if (pauseStartTimestamp == 0) {
-    //开始时将该值设置为运动开始值
-    pauseStartTimestamp = sportdata->starttime;
-  }
-
-  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++;
-    custom_VibratorFunc_int(0); // 触发振动反馈
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "触发了振动。振动计数: %d",
-                  shock_count);
-  }
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingTimerCallback 被执行。");
-}
-
-/* 启动定时器 */
-void StartTimer(void) {
-  if (g_startCounting != NULL) {
-    LogError("定时器已经存在", osError);
-    return;
-  }
-
-  g_startCounting = osTimerNew((osTimerFunc_t)TraingTimerCallback,
-                               osTimerPeriodic, NULL, NULL);
-  if (g_startCounting == NULL) {
-    LogError("定时器创建失败", osError);
-    return;
-  }
-
-  int tick = osMs2Tick(MS_ONE_SECONDS);
-  osStatus_t retTimer = osTimerStart(g_startCounting, tick);
-  if (retTimer != osOK) {
-    LogError("定时器启动失败", retTimer);
-    osTimerDelete(g_startCounting);
-    g_startCounting = NULL;
-  }
-}
-
-/* 停止并重置定时器 */
-void StopAndResetTimer(void) {
-  if (g_startCounting != NULL) {
-    osTimerStop(g_startCounting);
-    osStatus_t ret = osTimerDelete(g_startCounting);
-    if (ret != osOK) {
-      LogError("定时器删除失败", ret);
-    }
-    g_startCounting = NULL;
-    g_motionTimes = 0;
-    pauseStartTimestamp = 0;
-    totalPausedDuration = 0; // 重置总暂停时长
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已停止并重置。");
-  }
-}
-
-/* 暂停定时器 */
-void PauseTimer(void) {
-  if (g_startCounting != NULL) {
-    osTimerStop(g_startCounting);
-
-    totalPausedDuration = sportdata->duration; //记录暂停前的时间;后续加上
-
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已暂停。暂停开始时间戳: %u",
-                  pauseStartTimestamp);
-  }
-}
-
-/* 恢复定时器 */
-void ResumeTimer(void) {
-  if (g_startCounting != NULL) {
-
-    uint32_t currentTimestamp =
-        OHOS::TraingModel::GetInstance()->get_current_time(); // 获取当前时间戳
-    pauseStartTimestamp = currentTimestamp; // 保存暂停开始的时间戳 将这个更新
-
-    int tick = osMs2Tick(MS_ONE_SECONDS);
-    if (osTimerStart(g_startCounting, tick) != osOK) {
-      LogError("恢复定时器时启动失败", osError);
-    }
-
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器已恢复。当前运动时间: %u %d",
-                  g_motionTimes, pauseStartTimestamp);
-  }
-}
-
-#ifdef __cplusplus
-}
-#endif
-/* ---------------------------------- 数据存储
- * ---------------------------------- */
-static int32 SaveTraingDataToFile(void) {
-  time_t now = time(nullptr);
-  struct tm *timeinfo = localtime(&now);
-  char filename[20];
-  strftime(filename, sizeof(filename), "%Y%m%d.bin", timeinfo);
-
-  uint32 size = sizeof(Trainingdata);
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SaveTraingDataToFile !!");
-
-  char filePath[20];
-  sprintf(filePath, "%s%s", TRAINING_DATA_DIRECTORY, filename);
-
-  std::ofstream fd(filePath, std::ios::binary);
-  if (!fd.is_open()) {
-    if (mkdir(TRAINING_DATA_DIRECTORY, S_IRWXU) != 0) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create directory");
-      return 0;
-    }
-
-    fd.open(filePath, std::ios::binary);
-    if (!fd.is_open()) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for write");
-      return 0;
-    }
-
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory created successfully!!");
-  }
-
-  fd.write(reinterpret_cast<const char *>(&sportdata), size);
-  fd.close();
-  return 1;
-}
-static std::vector<Trainingdata> LoadTrainingDataFromTodayFile() {
-  std::vector<Trainingdata> trainingRecords;
-
-  time_t now = time(nullptr);
-  struct tm *timeinfo = localtime(&now);
-  char filename[20];
-  strftime(filename, sizeof(filename), "%Y%m%d.bin", timeinfo);
-  // 找到训练文件夹里面的当天文件
-  char filePath[20];
-  sprintf(filePath, "%s%s", TRAINING_DATA_DIRECTORY, filename);
-
-  std::ifstream fd(filePath, std::ios::binary);
-  if (!fd.is_open()) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open today's file");
-    return trainingRecords; // Return an empty vector if file open fails
-  }
-
-  // 读取训练信息
-  while (!fd.eof()) {
-    Trainingdata record;
-    fd.read(reinterpret_cast<char *>(&record), sizeof(Trainingdata));
-    if (fd.gcount() == sizeof(Trainingdata)) {
-      trainingRecords.push_back(record);
-    }
-  }
-
-  fd.close();
-
-  return trainingRecords;
-}
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-// 获得数据个数
-static int get_Trainingdata_data_num(FILE *fp) {
-  if (fp == NULL) {
-    return 0; // 如果文件指针为空,返回0
-  }
-
-  fseek(fp, 0, SEEK_END); // 将文件指针移动到文件末尾
-  long size = ftell(fp);  // 获取当前文件指针位置,即文件大小
-  fseek(fp, 0, SEEK_SET); // 将文件指针移回文件开头
-
-  return (size / sizeof(Trainingdata));
-}
-
-// 写训练bin文件
-int write_Trainingdata_data(Trainingdata data) {
-  char file_path[MAX_FILE_PATH_LENGTH] = {0};
-  char timeday[12] = {0};
-  uapi_get_YYMMDD_Time(timeday, '_');
-  snprintf(file_path, sizeof(file_path), "%s%s.bin", TRAINING_PATH, timeday);
-
-  // 检查目录是否存在,如果不存在则创建
-  struct stat st = {0};
-  if (stat(TRAINING_PATH, &st) == -1) {
-    if (mkdir(TRAINING_PATH, 0700) != 0) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create directory: %s",
-                    strerror(errno));
-      return -1; // 返回错误码
-    }
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", file_path);
-  FILE *fp = fopen(file_path, "ab+");
-  if (fp == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for append: %s",
-                  strerror(errno));
-    fp = fopen(file_path, "wb+");
-    if (fp == NULL) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "Failed to open file for write: %s", strerror(errno));
-      return -1; // 返回错误码
-    }
-  }
-
-  int ret = fwrite((void *)&data, sizeof(Trainingdata), 1, fp);
-  if (ret != 1) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "fwrite_data error! %d", ret);
-    fclose(fp);
-    return -1; // 返回错误码
-  }
-
-  fclose(fp); // 关闭文件
-  return 1;   // 返回成功码
-}
-
-// 读数据
-Trainingdata *read_Trainingdata_data(char *timedata, uint16_t offset) {
-  char file_path[128] = {0};
-  snprintf(file_path, sizeof(file_path), "%s%s.bin", TRAINING_PATH, timedata);
-
-  FILE *fp = fopen(file_path, "rb");
-  if (fp == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file for read: %s",
-                  strerror(errno));
-    return NULL;
-  }
-
-  Trainingdata *data = (Trainingdata *)malloc(sizeof(Trainingdata));
-  if (data == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "Failed to allocate memory for Trainingdata");
-    fclose(fp);
-    return NULL;
-  }
-
-  int num_data = get_Trainingdata_data_num(fp);
-  if (num_data <= offset) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "Offset %d exceeds number of data %d", offset, num_data);
-    free(data); // 释放内存
-    fclose(fp);
-    return NULL;
-  }
-
-  fseek(fp, sizeof(Trainingdata) * offset, SEEK_SET);
-  fread(data, sizeof(Trainingdata), 1, fp);
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Data src: %d", data->src);
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Offset: %d, Size: %zu", offset,
-                sizeof(Trainingdata));
-
-  fclose(fp);  // 关闭文件
-  return data; // 返回读取的数据
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-/* -------------------------------------------------------------------------- */
-/*检查是否存在数据*/
-bool TraingModel::CheckDataJson() {
-  // 读取record.json文件
-  std::ifstream file(TRAINING_RECORD_FILE);
-
-  // 检查文件是否打开成功
-  if (!file.is_open()) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unable to open file");
-    return false;
-  }
-
-  // 检查文件是否为空
-  file.seekg(0, std::ios::end);
-  if (file.tellg() == 0) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File is empty");
-    file.close();
-    return false;
-  }
-
-  // 解析json
-  std::vector<SportData> sportDataVector;
-  if (!LoadDataFormJson(sportDataVector)) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDataFormJson is error");
-    file.close();
-    return false;
-  }
-
-  // 关闭文件
-  file.close();
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckDataJson is ok");
-  return true;
-}
-
-bool TraingModel::SaveDataToJson(SportData *data) {
-  FILE *fp;
-  char *jsonStr = NULL;
-
-  // 读取现有的 JSON 数据
-  fp = fopen(TRAINING_RECORD_FILE, "r");
-  cJSON *data_root = NULL;
-  cJSON *dataArray = NULL;
-
-  if (fp != NULL) {
-    fseek(fp, 0, SEEK_END);
-    long fileSize = ftell(fp);
-    fseek(fp, 0, SEEK_SET);
-
-    jsonStr = (char *)malloc(fileSize + 1);
-    if (jsonStr != nullptr) {
-      if (fread(jsonStr, fileSize, 1, fp) == 1) {
-        data_root = cJSON_Parse(jsonStr);
-        if (data_root != NULL) {
-          dataArray = cJSON_GetObjectItem(data_root, "data");
-        }
-      }
-    }
-    fclose(fp);
-  }
-
-  if (dataArray == NULL) {
-    data_root = cJSON_CreateObject();
-    cJSON_AddItemToObject(data_root, "data", cJSON_CreateArray());
-    dataArray = cJSON_GetObjectItem(data_root, "data");
-  }
-
-  // 创建或更新数据节点
-  cJSON *sportData = cJSON_CreateObject();
-  cJSON_AddNumberToObject(sportData, "sportTypeId",
-                          int(data->sportType)); // 训练项目类 Id
-  cJSON_AddNumberToObject(sportData, "sportId", data->sportId); // 训练项目 Id
-  cJSON_AddStringToObject(sportData, "startDate",
-                          (data->start_date).c_str()); // 训练开始日期字符串
-  cJSON_AddStringToObject(sportData, "startTime",
-                          (data->start_time).c_str()); // 训练开始时间
-  cJSON_AddStringToObject(sportData, "endTime",
-                          (data->end_time).c_str()); // 训练结束时间
-  cJSON_AddNumberToObject(sportData, "goalDegree",
-                          data->goaldegree); // 训练目标完成度
-  cJSON_AddNumberToObject(sportData, "duration",
-                          data->duration); // 训练时长(秒)
-  cJSON_AddNumberToObject(sportData, "distance", data->distance); // 训练距离
-  cJSON_AddNumberToObject(sportData, "avgHeartRate",
-                          data->avgheart); // 训练平均心率
-  cJSON_AddNumberToObject(sportData, "steps", data->steps); // 训练步数
-  cJSON_AddNumberToObject(sportData, "intensity", data->intensity); // 训练强度
-  cJSON_AddNumberToObject(sportData, "apc", data->apc); // 训练平均配速
-  cJSON_AddNumberToObject(sportData, "cdc", data->cdc); // 训练步频
-  cJSON_AddNumberToObject(sportData, "std", data->std); // 训练步幅
-  cJSON_AddNumberToObject(sportData, "calories", data->calories); //卡路里
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "starttime is %d", data->starttime);
-  cJSON_AddNumberToObject(sportData, "start_time",
-                          data->starttime); // 开始时间戳
-
-  // 添加运动数据节点到数组并限制数量
-  cJSON_AddItemToArray(dataArray, sportData);
-  while (cJSON_GetArraySize(dataArray) > MAX_DATA_COUNT) {
-    cJSON_DeleteItemFromArray(dataArray, 0);
-  }
-
-  // 将更新后的 JSON 数据写入文件
-  char *jsonStrNew = cJSON_Print(data_root);
-  fp = fopen(TRAINING_RECORD_FILE, "w");
-  if (fp != NULL) {
-    fwrite(jsonStrNew, strlen(jsonStrNew), 1, fp);
-    fclose(fp);
-  }
-
-  // 释放资源
-  cJSON_Delete(data_root);
-  free(jsonStr);
-  cJSON_free(jsonStrNew);
-
-  return true;
-}
-
-/* 加载训练数据函数 */
-/* 加载训练数据函数 */
-bool TraingModel::LoadDataFormJson(std::vector<SportData> &sportDataVector) {
-  // 清空输出向量,避免旧数据干扰
-  sportDataVector.clear();
-
-  // 打开JSON文件
-  std::ifstream file(TRAINING_RECORD_FILE);
-  if (!file.is_open()) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file: %s",
-                  TRAINING_RECORD_FILE);
-    return false;
-  }
-
-  // 读取文件内容到字符串
-  std::string jsonData((std::istreambuf_iterator<char>(file)),
-                       std::istreambuf_iterator<char>());
-  file.close();
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Read %zu bytes from JSON file",
-                jsonData.size());
-
-  // 解析JSON根对象
-  cJSON *root = cJSON_Parse(jsonData.c_str());
-  if (root == NULL) {
-    const char *errorPtr = cJSON_GetErrorPtr();
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse JSON: %s",
-                  errorPtr ? errorPtr : "Unknown error");
-    return false;
-  }
-
-  // 查找并验证data数组
-  cJSON *dataArray = cJSON_GetObjectItem(root, "data");
-  if (dataArray == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing 'data' array in JSON");
-    cJSON_Delete(root);
-    return false;
-  }
-  if (!cJSON_IsArray(dataArray)) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "'data' is not an array in JSON");
-    cJSON_Delete(root);
-    return false;
-  }
-
-  // 检查数组大小
-  int dataCount = cJSON_GetArraySize(dataArray);
-  if (dataCount == 0) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Empty 'data' array in JSON");
-    cJSON_Delete(root);
-    return false;
-  }
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Found %d items in 'data' array",
-                dataCount);
-
-  // 遍历解析每个数据项
-  for (int i = 0; i < dataCount; i++) {
-    cJSON *item = cJSON_GetArrayItem(dataArray, i);
-    if (item == NULL) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "Null item at index %d in 'data' array", i);
-      continue; // 跳过无效项,继续处理其他项
-    }
-
-    SportData sportData;
-    bool isValid = true;
-    std::string missingFields; // 记录缺失的字段
-
-    // 解析sportTypeId字段
-    if (cJSON *sportTypeIdItem = cJSON_GetObjectItem(item, "sportTypeId")) {
-      if (cJSON_IsNumber(sportTypeIdItem)) {
-        sportData.sportType = (Exercisetype)sportTypeIdItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "sportTypeId ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "sportTypeId ";
-    }
-
-    // 解析sportId字段
-    if (cJSON *sportIdItem = cJSON_GetObjectItem(item, "sportId")) {
-      if (cJSON_IsNumber(sportIdItem)) {
-        sportData.sportId = (UIResourceTextId)sportIdItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "sportId ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "sportId ";
-    }
-
-    // 解析startDate字段
-    if (cJSON *startDateItem = cJSON_GetObjectItem(item, "startDate")) {
-      if (cJSON_IsString(startDateItem) && startDateItem->valuestring) {
-        sportData.start_date = startDateItem->valuestring;
-      } else {
-        isValid = false;
-        missingFields += "startDate ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "startDate ";
-    }
-
-    // 解析startTime字段
-    if (cJSON *startTimeItem = cJSON_GetObjectItem(item, "startTime")) {
-      if (cJSON_IsString(startTimeItem) && startTimeItem->valuestring) {
-        sportData.start_time = startTimeItem->valuestring;
-      } else {
-        isValid = false;
-        missingFields += "startTime ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "startTime ";
-    }
-
-    // 解析endTime字段
-    if (cJSON *endTimeItem = cJSON_GetObjectItem(item, "endTime")) {
-      if (cJSON_IsString(endTimeItem) && endTimeItem->valuestring) {
-        sportData.end_time = endTimeItem->valuestring;
-      } else {
-        isValid = false;
-        missingFields += "endTime ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "endTime ";
-    }
-
-    // 解析goalDegree字段
-    if (cJSON *goalDegreeItem = cJSON_GetObjectItem(item, "goalDegree")) {
-      if (cJSON_IsNumber(goalDegreeItem)) {
-        sportData.goaldegree = goalDegreeItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "goalDegree ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "goalDegree ";
-    }
-
-    // 解析duration字段
-    if (cJSON *durationItem = cJSON_GetObjectItem(item, "duration")) {
-      if (cJSON_IsNumber(durationItem)) {
-        sportData.duration = durationItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "duration ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "duration ";
-    }
-
-    // 解析distance字段
-    if (cJSON *distanceItem = cJSON_GetObjectItem(item, "distance")) {
-      if (cJSON_IsNumber(distanceItem)) {
-        sportData.distance = distanceItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "distance ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "distance ";
-    }
-
-    // 解析avgHeartRate字段
-    if (cJSON *avgHeartRateItem = cJSON_GetObjectItem(item, "avgHeartRate")) {
-      if (cJSON_IsNumber(avgHeartRateItem)) {
-        sportData.avgheart = avgHeartRateItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "avgHeartRate ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "avgHeartRate ";
-    }
-
-    // 解析steps字段
-    if (cJSON *stepsItem = cJSON_GetObjectItem(item, "steps")) {
-      if (cJSON_IsNumber(stepsItem)) {
-        sportData.steps = stepsItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "steps ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "steps ";
-    }
-
-    // 解析intensity字段
-    if (cJSON *intensityItem = cJSON_GetObjectItem(item, "intensity")) {
-      if (cJSON_IsNumber(intensityItem)) {
-        sportData.intensity = intensityItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "intensity ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "intensity ";
-    }
-
-    // 解析apc字段
-    if (cJSON *apcItem = cJSON_GetObjectItem(item, "apc")) {
-      if (cJSON_IsNumber(apcItem)) {
-        sportData.apc = apcItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "apc ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "apc ";
-    }
-
-    // 解析cdc字段
-    if (cJSON *cdcItem = cJSON_GetObjectItem(item, "cdc")) {
-      if (cJSON_IsNumber(cdcItem)) {
-        sportData.cdc = cdcItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "cdc ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "cdc ";
-    }
-
-    // 解析std字段
-    if (cJSON *stdItem = cJSON_GetObjectItem(item, "std")) {
-      if (cJSON_IsNumber(stdItem)) {
-        sportData.std = stdItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "std ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "std ";
-    }
-
-    // 解析calories字段
-    if (cJSON *caloriesItem = cJSON_GetObjectItem(item, "calories")) {
-      if (cJSON_IsNumber(caloriesItem)) {
-        sportData.calories = caloriesItem->valueint;
-      } else {
-        isValid = false;
-        missingFields += "calories ";
-      }
-    } else {
-      isValid = false;
-      missingFields += "calories ";
-    }
-
-    // 解析starttime字段(时间戳)
-    if (cJSON *starttimeItem = cJSON_GetObjectItem(item, "start_time")) {
-      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Found starttime field. Type: %d",
-                    starttimeItem->type);
-      if (cJSON_IsNumber(starttimeItem)) {
-        sportData.starttime = starttimeItem->valueint;
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Parsed starttime: %d",
-                      sportData.starttime);
-      } else {
-        // 打印详细信息,帮助定位问题
-        const char *valueStr =
-            starttimeItem->valuestring ? starttimeItem->valuestring : "null";
-        WEARABLE_LOGE(
-            WEARABLE_LOG_MODULE_APP,
-            "Invalid starttime type. Expected number, got type %d (value: %s)",
-            starttimeItem->type, valueStr);
-        isValid = false;
-      }
-    } else {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing starttime field");
-      isValid = false;
-    }
-
-    // 处理解析结果
-    if (isValid) {
-      sportDataVector.push_back(sportData);
-      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Successfully parsed item %d", i);
-    } else {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "Invalid data in item %d. Missing fields: %s", i,
-                    missingFields.c_str());
-    }
-  }
-
-  cJSON_Delete(root);
-
-  // 检查是否成功解析了任何数据
-  if (sportDataVector.empty()) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "No valid data items found in JSON");
-    return false;
-  }
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                "Successfully loaded %zu valid data items",
-                sportDataVector.size());
-  return true;
-}
-
-//////////////////////////////////////GPS///////////////////////////////////////////////
-/*
-  Latitude(纬度):范围:-90° 至 +90°(或南纬 90° 至北纬 90°);
-  Longitude(经度):范围:-180° 至 +180°(或西经 180° 至东经 180°);
-
-  -画布数据集最多是100个定位坐标,超过按比例进行拿取100个点位;
-  -通过映射关系,将经纬度转换为400*400画布上的坐标;
-  -但是不能靠近400,以免显示不全等问题,350*350;
-  -如果处理负数,需要将其转换为正数,然后再进行映射?
-  -如果有正数又有负数,应该怎么处理?
-*/
-
-static double getmin(double a, double b) { return a < b ? a : b; }
-static double getmax(double a, double b) { return a > b ? a : b; }
-// 计算点p到由p1和p2确定的线段的垂直距离(优化版)
-static double perpendicularDistance(const Point &p, const Point &p1,
-                                    const Point &p2) {
-  // 计算向量 p1->p2
-  double dx = p2.x - p1.x;
-  double dy = p2.y - p1.y;
-
-  // 线段长度的平方
-  double len2 = dx * dx + dy * dy;
-
-  // 如果线段退化为一个点,直接计算点到点的距离
-  if (len2 == 0) {
-    return std::hypot(p.x - p1.x, p.y - p1.y);
-  }
-
-  // 计算投影比例 t
-  double t = ((p.x - p1.x) * dx + (p.y - p1.y) * dy) / len2;
-
-  if (t < 0) {
-    // 投影在p1之前,返回p到p1的距离
-    return std::hypot(p.x - p1.x, p.y - p1.y);
-  }
-
-  if (t > 1) {
-    // 投影在p2之后,返回p到p2的距离
-    return std::hypot(p.x - p2.x, p.y - p2.y);
-  }
-
-  // 投影在线段上,计算投影点并返回距离
-  double projX = p1.x + t * dx;
-  double projY = p1.y + t * dy;
-  return std::hypot(p.x - projX, p.y - projY);
-}
-
-// Douglas-Peucker算法实现(优化版)
-static void douglasPeucker(const std::vector<Point> &points, double epsilon,
-                           std::vector<Point> &result) {
-  if (points.size() <= 2) {
-    // 点数量不足,直接返回
-    result = points;
-    return;
-  }
-
-  double dmax = 0;
-  int index = 0;
-  int end = points.size() - 1;
-
-  // 找到距离最大的点
-  for (int i = 1; i < end; i++) {
-    double d = perpendicularDistance(points[i], points[0], points[end]);
-    if (d > dmax) {
-      index = i;
-      dmax = d;
-    }
-  }
-
-  // 如果最大距离大于阈值,则递归处理
-  if (dmax > epsilon) {
-    std::vector<Point> recResults1, recResults2;
-
-    // 递归处理前半部分
-    douglasPeucker(
-        std::vector<Point>(points.begin(), points.begin() + index + 1), epsilon,
-        recResults1);
-
-    // 递归处理后半部分
-    douglasPeucker(std::vector<Point>(points.begin() + index, points.end()),
-                   epsilon, recResults2);
-
-    // 合并结果(避免重复添加端点)
-    result.assign(recResults1.begin(), recResults1.end() - 1);
-    result.insert(result.end(), recResults2.begin(), recResults2.end());
-  } else {
-    // 否则保留首尾点
-    result = {points[0], points[end]};
-  }
-}
-
-// 改进的GetPointData函数(优化版)
-void TraingModel::GetPointData() {
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                "Generating point data from %zu GPS points", gpsData.size());
-
-  std::vector<GPSData> sampledData;
-
-  // 处理GPS数据
-  if (gpsData.size() > 100) {
-    // 计算经纬度范围
-    double minLat = 90.0, maxLat = -90.0;
-    double minLon = 180.0, maxLon = -180.0;
-
-    // 同时计算平均值用于判断数据分布
-    double sumLat = 0, sumLon = 0;
-
-    for (const auto &point : gpsData) {
-      minLat = getmin(minLat, point.latitude);
-      maxLat = getmax(maxLat, point.latitude);
-      minLon = getmin(minLon, point.longitude);
-      maxLon = getmax(maxLon, point.longitude);
-      sumLat += point.latitude;
-      sumLon += point.longitude;
-    }
-
-    // 计算经纬度范围和平均值
-    double rangeLat = maxLat - minLat;
-    double rangeLon = maxLon - minLon;
-    double avgLat = sumLat / gpsData.size();
-    double avgLon = sumLon / gpsData.size();
-
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                  "GPS range: lat=[%.6f, %.6f], lon=[%.6f, %.6f]", minLat,
-                  maxLat, minLon, maxLon);
-
-    // 检查数据是否集中在极小区域或几乎相同
-    const double MIN_SIGNIFICANT_RANGE = 0.01; // 根据实际情况调整
-    bool isDataDegenerate =
-        (rangeLat < MIN_SIGNIFICANT_RANGE && rangeLon < MIN_SIGNIFICANT_RANGE);
-
-    if (isDataDegenerate) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "GPS data is degenerate (very small range)");
-      // 使用均匀采样,避免算法失效
-      double step = static_cast<double>(gpsData.size() - 1) / 99;
-      for (int i = 0; i < 100; i++) {
-        int index = static_cast<int>(i * step);
-        sampledData.push_back(gpsData[index]);
-      }
-    } else {
-      // 转换GPS坐标到屏幕坐标
-      std::vector<Point> screenPoints;
-      screenPoints.reserve(gpsData.size());
-
-      for (const auto &point : gpsData) {
-        double normLat = (point.latitude - minLat) / rangeLat;
-        double normLon = (point.longitude - minLon) / rangeLon;
-        screenPoints.push_back(
-            {normLon * 300 + 50, (1.0 - normLat) * 300 + 50});
-      }
-
-      // 使用Douglas-Peucker算法简化轨迹
-      std::vector<Point> simplifiedPoints;
-      douglasPeucker(screenPoints, 0.5, simplifiedPoints);
-
-      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                    "After Douglas-Peucker: %zu points",
-                    simplifiedPoints.size());
-
-      // 处理简化结果
-      if (simplifiedPoints.size() <= 2) {
-        WEARABLE_LOGE(
-            WEARABLE_LOG_MODULE_APP,
-            "Trajectory over-simplified! Using uniform sampling instead.");
-        // 过度简化时回退到均匀采样
-        double step = static_cast<double>(gpsData.size() - 1) / 99;
-        for (int i = 0; i < 100; i++) {
-          int index = static_cast<int>(i * step);
-          sampledData.push_back(gpsData[index]);
-        }
-      } else if (simplifiedPoints.size() > 100) {
-        // 简化后仍超过100点,再次均匀采样
-        double step = static_cast<double>(simplifiedPoints.size() - 1) / 99;
-        for (int i = 0; i < 100; i++) {
-          int index = static_cast<int>(i * step);
-          // 屏幕坐标反推回GPS坐标
-          double normX = (simplifiedPoints[index].x - 50) / 300;
-          double normY = (simplifiedPoints[index].y - 50) / 300;
-          double lat = minLat + (1.0 - normY) * rangeLat;
-          double lon = minLon + normX * rangeLon;
-          sampledData.push_back({0, lat, lon});
-        }
-      } else {
-        // 简化后点数量合适,直接使用
-        for (const auto &point : simplifiedPoints) {
-          double normX = (point.x - 50) / 300;
-          double normY = (point.y - 50) / 300;
-          double lat = minLat + (1.0 - normY) * rangeLat;
-          double lon = minLon + normX * rangeLon;
-          sampledData.push_back({0, lat, lon});
-        }
-      }
-    }
-  } else {
-    // GPS点数不足100,直接使用全部数据
-    sampledData = gpsData;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "Using all %zu GPS points (no sampling)", sampledData.size());
-  }
-
-  // 映射到画布坐标
-  canvasData.clear();
-  canvasData.reserve(sampledData.size());
-
-  // 如果没有采样数据,直接返回
-  if (sampledData.empty()) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "No sampled data to map!");
-    return;
-  }
-
-  // 基于采样数据重新计算经纬度范围
-  double minLat = 90.0, maxLat = -90.0;
-  double minLon = 180.0, maxLon = -180.0;
-
-  for (const auto &point : sampledData) {
-    minLat = getmin(minLat, point.latitude);
-    maxLat = getmax(maxLat, point.latitude);
-    minLon = getmin(minLon, point.longitude);
-    maxLon = getmax(maxLon, point.longitude);
-  }
-
-  double rangeLat = maxLat - minLat;
-  double rangeLon = maxLon - minLon;
-
-  // 避免除零错误
-  if (rangeLat == 0)
-    rangeLat = 1e-10;
-  if (rangeLon == 0)
-    rangeLon = 1e-10;
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                "Sampled GPS range: lat=[%.6f, %.6f], lon=[%.6f, %.6f]", minLat,
-                maxLat, minLon, maxLon);
-
-  // 映射每个点到画布
-  for (const auto &point : sampledData) {
-    double normLat = (point.latitude - minLat) / rangeLat;
-    double normLon = (point.longitude - minLon) / rangeLon;
-
-    // 转换到画布坐标
-    double x = normLon * 300 + 50;
-    double y = (1.0 - normLat) * 300 + 50;
-
-    canvasData.push_back({x, y});
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                  "Mapped point: (%.6f, %.6f) -> (%.2f, %.2f)", point.latitude,
-                  point.longitude, x, y);
-  }
-
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Generated %zu canvas points",
-                canvasData.size());
-}
-
-// 添加经纬度数据集
-void TraingModel::AddGPSData(uint32_t timestamp, double latitude,
-                             double longitude) {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== AddGPSData函数调用开始 ===");
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                "输入参数: timestamp=%u, latitude=%.6f, longitude=%.6f",
-                timestamp, latitude, longitude);
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "当前GPS数据点数量: %zu",
-                gpsData.size());
-
-  // 判断数据是否合理
-  if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "错误: GPS数据无效 - 纬度=%.6f (范围: -90~90), 经度=%.6f "
-                  "(范围: -180~180)",
-                  latitude, longitude);
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "=== AddGPSData函数调用结束(数据无效) ===");
-    return;
-  }
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GPS数据有效性检查通过");
-
-  // 校验时间戳是否递增
-  if (!gpsData.empty() && timestamp <= gpsData.back().timestamp) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "错误: 时间戳未递增 - 当前=%u, 上一个=%u, 差值=%d", timestamp,
-                  gpsData.back().timestamp,
-                  (int)timestamp - (int)gpsData.back().timestamp);
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "=== AddGPSData函数调用结束(时间戳错误) ===");
-    return;
-  }
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "时间戳递增检查通过");
-
-  // 添加数据
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "准备添加GPS数据到容器...");
-  gpsData.push_back({timestamp, latitude, longitude});
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                "成功添加GPS数据 #%zu: 时间戳=%u, 坐标=(%.6f, %.6f)",
-                gpsData.size(), timestamp, latitude, longitude);
-
-  // 打印当前GPS数据统计信息
-  if (gpsData.size() > 1) {
-    double lat_diff = latitude - gpsData[gpsData.size() - 2].latitude;
-    double lon_diff = longitude - gpsData[gpsData.size() - 2].longitude;
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                  "与上一个点的距离差: 纬度差=%.6f, 经度差=%.6f", lat_diff,
-                  lon_diff);
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== AddGPSData函数调用结束 ===");
-}
-
-//保存canvas数据
-bool TraingModel::SaveCanvasData() {
-
-  //打印一下gps的数据
-  for (const auto &point : gpsData) {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                  "GPS Data: Latitude = %f, Longitude = %f", point.latitude,
-                  point.longitude);
-  }
-
-  if (canvasData.size() == 0) {
-    WEARABLE_LOGE(WEARING_LOG_MODULE_APP, "canvasData is empty");
-    return false;
-  }
-
-  CreateDirectoryIfNotExists(TRAINING_CANVAS_FILE);
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "canvasData.size() = %zu",
-                canvasData.size());
-
-  std::string filePath =
-      TRAINING_CANVAS_FILE + std::to_string(sportdata->starttime) + ".bin";
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveCanvasData filePath: %s",
-                filePath.c_str());
-
-  std::ofstream gpsFile(filePath, std::ios::binary);
-  if (!gpsFile) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
-                  filePath.c_str());
-    return false; // 返回失败
-  }
-  // 写入gps数据
-  if (!gpsFile.write(reinterpret_cast<const char *>(canvasData.data()),
-                     canvasData.size() * sizeof(Point))) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入GPS数据失败。");
-    return false; // 返回失败
-  }
-
-  gpsFile.close();
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData Success.");
-  return true; // 返回成功
-}
-// 清除canvas数据
-void TraingModel::ClearCanvasData() { canvasData.clear(); }
-// 获取轨迹点集
-std::vector<Point> TraingModel::GetCanvasData() const { return canvasData; }
-// 获取canvas数据
-std::string TraingModel::GetCanvasDataPath(uint32_t timestamp) {
-  // 首先检查完全匹配的时间戳
-  std::string exactFilePath =
-      TRAINING_CANVAS_FILE + std::to_string(timestamp) + ".bin";
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "canvas表: %s", exactFilePath.c_str());
-  if (IsFileAccessibleAndNotEmpty(exactFilePath)) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到canvas表: %s",
-                  exactFilePath.c_str());
-    return exactFilePath; // 返回完全匹配的文件路径
-  }
-
-  // 如果未找到,检查时间戳相差1到2秒的文件
-  for (int i = -2; i <= 2; ++i) {
-    uint32_t checkTimestamp = timestamp + i;
-    std::string filePath =
-        TRAINING_CANVAS_FILE + std::to_string(checkTimestamp) + ".bin";
-    if (IsFileAccessibleAndNotEmpty(filePath)) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到canvas表: %s",
-                    filePath.c_str());
-      return filePath; // 返回找到的文件路径
-    }
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的找到canvas表。");
-  return ""; // 未找到文件
-}
-// 加载GPS数据
-bool TraingModel::LoadCanvasData(const std::string &filePath) {
-  std::ifstream gpsFile(filePath, std::ios::binary);
-  if (!gpsFile) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
-                  filePath.c_str());
-    return false;
-  }
-
-  // 清空现有数据
-  canvasData.clear();
-
-  // 动态读取数据(假设文件格式允许逐点读取)
-  Point point;
-  while (gpsFile.read(reinterpret_cast<char *>(&point), sizeof(Point))) {
-    canvasData.push_back(point);
-  }
-
-  gpsFile.close();
-
-  if (canvasData.empty()) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未读取到有效数据: %s",
-                  filePath.c_str());
-    return false;
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                "LoadCanvasData Success. 加载了 %zu 个点", canvasData.size());
-  return true;
-}
-//////////////////////////////////////gps存储///////////////////////////////////////
-//存储gps数据
-bool TraingModel::SaveGPSData() {
-  //打印gps数据
-  for (const auto &point : gpsData) {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
-                  "GPS Data: Latitude = %f, Longitude = %f", point.`latitude,
-                  point.longitude);
-  }
-  CreateDirectoryIfNotExists(TRAINING_GPS_FILE);
-  std::string filePath =
-      TRAINING_GPS_FILE + std::to_string(sportdata->starttime) + ".bin";
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData filePath: %s",
-                filePath.c_str());
-
-  std::ofstream gpsFile(filePath, std::ios::binary);
-  if (!gpsFile) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "无法打开文件: %s",
-                  filePath.c_str());
-    return false; // 返回失败
-  }
-  // 写入gps数据
-  if (!gpsFile.write(reinterpret_cast<const char *>(gpsData.data()),
-                     gpsData.size() * sizeof(GPSData))) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "写入GPS数据失败。");
-    return false; // 返回失败
-  }
-  gpsFile.close();
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveGPSData Success.");
-  return true;
-}
-std::string TraingModel::GetGPSDataPath(uint32_t timestamp) {
-  // 首先检查完全匹配的时间戳
-  std::string exactFilePath =
-      TRAINING_GPS_FILE + std::to_string(timestamp) + ".bin";
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gps表: %s", exactFilePath.c_str());
-  if (IsFileAccessibleAndNotEmpty(exactFilePath)) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到gps表: %s",
-                  exactFilePath.c_str());
-    return exactFilePath; // 返回完全匹配的文件路径
-  }
-
-  // 如果未找到,检查时间戳相差1到2秒的文件
-  for (int i = -2; i <= 2; ++i) {
-    uint32_t checkTimestamp = timestamp + i;
-    std::string filePath =
-        TRAINING_GPS_FILE + std::to_string(checkTimestamp) + ".bin";
-    if (IsFileAccessibleAndNotEmpty(filePath)) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "找到gps表: %s", filePath.c_str());
-      return filePath; // 返回找到的文件路径
-    }
-  }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "未找到与时间戳相关的找到gps表。");
-  return "";
-}
-
-//获取GPS连接状态
-bool TraingModel::GetGPSConnectState() { return gpsconnect; }
-//设置GPS连接状态
-void TraingModel::SetGPSConnectState(bool state) {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS连接状态设置 ===");
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前GPS连接状态: %d, 新状态: %d",
-                gpsconnect, state);
-
-  if (gpsconnect != state) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS连接状态发生变化: %d -> %d",
-                  gpsconnect, state);
-    gpsconnect = state;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS连接状态已更新为: %d",
-                  gpsconnect);
-
-    //状态改变记录
-    // SystemLogModel::GetInstance()->save_gps_status_log_type(gpsconnect);
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS状态变化记录完成");
-  } else {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS连接状态未发生变化,保持: %d",
-                  gpsconnect);
-  }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS连接状态设置完成 ===");
-}
-//运动心率、gps开启准备
-void TraingModel::start_training_heart() {
-  if (gpsopen == false) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始启动GPS定位服务...");
-    //开启心率检测
-#ifdef SUPPORT_PPG_SERVICE
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "启动心率检测服务");
-    ppg_hr_start();
-#endif
-    gpsopen = true;
-  }
-}
-//运动心率、gps关闭
-void TraingModel::stop_heart_gps() {
-  if (gpsopen == true) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始关闭GPS定位服务...");
-    // 关闭gps
-#if defined(SUPPORT_GNSS)
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "调用gnss_stop()关闭GPS服务");
-    gnss_stop();
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gnss_stop()调用完成");
-#endif
-
-    //关闭心率检测
-#ifdef SUPPORT_PPG_SERVICE
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "关闭心率检测服务");
-    ppg_hr_stop();
-#endif
-
-    gpsopen = false;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "GPS定位服务关闭完成,gpsopen设置为false");
-  }
-}
-
-/////////////////////////////////////位置服务定时器/////////////////////////////////////
-/*
- * 位置服务定时器说明:
- * - 功能:负责获取GPS定位数据,更新GPS连接状态,添加经纬度数据
- * - 频率:1秒间隔,保证位置数据的实时性
- * - 触发条件:仅在训练进行中且训练状态非结束时执行
- */
-static osTimerId_t g_location_timer = nullptr;
-static int location_timer_interval = 1; // 位置数据获取间隔,单位秒
-static int gps_timer_count = 0;
-
-/*位置服务定时器到期时的处理*/
-static void gnss_timer_callbackProc(int data) {
-  /*
-      GPS数据获取处理
-      1、目前gps注册有问题 ;需要延迟2s 去开启gps;
+         i++;
+     }
+     return NULL;
+ }
+ 
+ extern bleInstruct_t_ bleInstruct_t;
+ 
+ void ble_training_init(void) {
+   bleInstruct_t.get_training_spead_path_cb = get_training_spead_path_;
+   bleInstruct_t.get_training_heart_path_cb = get_training_heart_path_;
+   bleInstruct_t.get_training_gps_path_cb = get_training_gps_path_;
+   bleInstruct_t.struct_to_json_buf_malloc = struct_to_json_buf_malloc_;
+   bleInstruct_t.read_gps_data_cb = read_gps_data_;
+   bleInstruct_t.ble_get_Trainingdata_by_timetamp = ble_get_Trainingdata_by_timetamp_;
+ }
+ 
+ #ifdef __cplusplus
+ #if __cplusplus
+ }
+ #endif /* __cplusplus */
+ #endif /* __cplusplus */
+ 
+ #endif
+ 
+ /*
+  * 定时器分工总结:
+  *
+  * 1. 位置服务定时器 (g_location_timer)
+  *    - 频率:1秒间隔
+  *    - 功能:GPS定位、连接状态更新、轨迹数据采集
+  *    - 特点:中等频率,保证位置数据实时性
+  *
+  * 2. 运动数据采集定时器 (g_sport_start_data_timer)
+  *    - 频率:300毫秒间隔
+  *    - 功能:运动数据采集、心率监测、目标完成度检查、UI更新
+  *    - 特点:高频率,保证运动数据实时性和准确性
+  *
+  * 数据获取函数封装(职责单一,无耦合):
+  * - GetSportActivityData(): 获取运动基础数据,返回是否成功
+  * - GetSportExtraData(): 获取运动额外数据,返回是否成功
+  * - GetHeartRateData(): 获取心率数据,返回心率值
+  * - 数据分析和处理逻辑在定时器回调中协调完成
+  *
+  * 两个定时器独立运行,互不干扰,根据各自功能特点选择合适的执行频率
   */
-  gps_timer_count++;
-  if (gps_timer_count < 2) {
-    return;
-  }
-  if (gps_timer_count == 2) {
-#if defined(SUPPORT_GNSS)
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开启gps");
-    // gnss_start();
-#endif
-  }
-#if defined(SUPPORT_GNSS)
-  gps_data_t send_gps_data = {0};
-  gps_data_t *gps_data = getPGPSGlobaldata();
-
-  if (gps_data == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "错误: gps_data == NULL,GPS全局数据获取失败");
-    return;
-  }
-
-  if (gps_data->last_gps_time_ms > 0) {
-    memcpy_s(&send_gps_data, sizeof(gps_data_t), gps_data, sizeof(gps_data_t));
-  } else {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS时间戳无效,跳过本次处理");
-    return;
-  }
-
-  // 判断是否定位成功并设置连接状态
-  bool isGpsConnected = (send_gps_data.status > 1);
-  TraingModel::GetInstance()->SetGPSConnectState(isGpsConnected);
-
-  // 判断是否在运动或训练已结束
-  int train_status = uapi_dev_runtime_get_train_status();
-  ExerciseState sport_state = TraingModel::GetInstance()->GetSportState();
-
-  if (train_status == 0 || sport_state == ExerciseState::End) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "运动已结束或未开始,跳过GPS数据添加");
-    return;
-  }
-
-  // 如果定位成功,添加经纬度数据
-  if (isGpsConnected) {
-    uint32_t time = TraingModel::GetInstance()->get_current_time();
-    TraingModel::GetInstance()->AddGPSData(time, send_gps_data.location.lat,
-                                           send_gps_data.location.lng);
-  } else {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定位失败,跳过数据添加");
-  }
-#endif
-}
-
-/*
- * @brief 位置服务定时器回调函数
- */
-static void gnss_timer_callback(int data) {
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "gnss_timer_callback %d", data);
-  GraphicService::GetInstance()->PostGraphicEvent(
-      std::bind(gnss_timer_callbackProc, data));
-}
-
-/*
- *  @brief 开启位置服务定时器函数
- *  @param interval 时间间隔,单位ms
- */
-void TraingModel::gnss_start_timer(uint32_t interval) {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS定时器启动流程开始 ===");
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "定时器间隔: %u ms", interval);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前定时器状态: %p",
-                g_location_timer);
-
-  /* -------------------------- 1.检查位置服务定时器是否已经存在,如果存在则返回
-   * ------------------------- */
-  if (g_location_timer != nullptr) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "错误: GPS定时器已存在,跳过创建");
-    return;
-  }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器不存在,开始创建...");
-
-  /* --------------------------------- 2.创建位置服务定时器
-   * -------------------------------- */
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "调用osTimerNew创建GPS定时器...");
-  g_location_timer = osTimerNew((osTimerFunc_t)gnss_timer_callback,
-                                osTimerPeriodic, nullptr, nullptr);
-  // 检查定时器创建是否成功
-  if (g_location_timer == nullptr) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "错误: GPS定时器创建失败!!");
-    return;
-  }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器创建成功: %p",
-                g_location_timer);
-
-  /* ----------------------------- 3.将毫秒转换为系统时钟节拍数
-   * ---------------------------- */
-  int tick = osMs2Tick(interval);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "时间转换: %u ms -> %d ticks",
-                interval, tick);
-
-  /* --------------------------------- 4.启动位置服务定时器
-   * -------------------------------- */
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "启动GPS定时器...");
-  osStatus_t ret = osTimerStart(g_location_timer, tick);
-  /* -------------------- 5.检查位置服务定时器启动是否成功,如果启动失败,删除定时器并置为
-   * nullptr -------------------- */
-  if (ret != osOK) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "错误: GPS定时器启动失败, ret = %lx!!", ret);
-    if (g_location_timer != nullptr) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "删除失败的GPS定时器...");
-      ret = osTimerDelete(g_location_timer);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器删除结果: %lx", ret);
-    }
-    g_location_timer = nullptr;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "=== GPS定时器启动流程结束(失败) ===");
-    return;
-  }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器启动成功");
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS定时器启动流程结束(成功) ===");
-}
-
-/*
- * @brief 停止位置服务定时器
- */
-void TraingModel::gnss_stop_timer(void) {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS定时器停止流程开始 ===");
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前定时器状态: %p",
-                g_location_timer);
-
-  // 检查位置服务定时器是否存在
-  if (g_location_timer != nullptr) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器存在,开始停止流程...");
-
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "停止GPS定时器...");
-    osTimerStop(g_location_timer);
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器已停止");
-
-    // 删除定时器并置为 nullptr
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "删除GPS定时器...");
-    osStatus_t ret = osTimerDelete(g_location_timer);
-    if (ret != osOK) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "错误: GPS定时器删除失败, ret = %lx!!", ret);
-    } else {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器删除成功");
-    }
-    g_location_timer = nullptr;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器指针已置空");
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== GPS定时器停止流程结束 ===");
-  } else {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定时器不存在,跳过停止流程");
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "=== GPS定时器停止流程结束(无需停止) ===");
-  }
-  gps_timer_count = 0;
-}
-
-///////////////////////////////////////运动数据采集定时器//////////////////////////////////
-/*
- * 运动数据采集定时器说明:
- * - 功能:负责获取运动数据(步数、距离、卡路里、心率等),更新训练目标完成度
- * - 频率:300ms间隔,保证运动数据的实时性和准确性
- * - 触发条件:仅在训练进行中且训练状态非结束时执行
- * - 包含服务:CYWEE运动数据、PPG心率数据、训练目标检查、UI更新
- */
-#if SPORT_TIMER_DATA
-// 声明运动数据采集定时器变量
-static osTimerId_t g_sport_start_data_timer = nullptr;
-static int sport_start_data_timer_interval = 300; // 运动数据获取间隔,单位毫秒
-
-/*
- * @brief 获取运动基础数据
- * @return 是否成功获取数据
- */
-bool TraingModel::GetSportActivityData(void) {
-#ifdef SUPPORT_CYWEE_SERVICE
-  act_result_t cyweeInfo;
-  cywee_get_act_data(&cyweeInfo);
-  // 更新运动基础数据
-  TraingModel::GetInstance()->AnalysisData(&cyweeInfo);
-  // 更新其他目标完成度
-  TraingModel::GetInstance()->CheckSportTag();
-#endif
-  return true;
-}
-
-/*
- * @brief 获取运动额外数据
- * @return 是否成功获取数据
- */
-bool TraingModel::GetSportExtraData(void) {
-#ifdef SUPPORT_CYWEE_SERVICE
-  act_ext_result_t cyweeInfo_ext;
-  cywee_get_act_ext_data(&cyweeInfo_ext);
-  TraingModel::GetInstance()->AnalysisExtraData(&cyweeInfo_ext);
-#endif
-  return true;
-}
-
-/*
- * @brief 获取心率数据
- * @return 获取到的心率值,如果服务不支持则返回0
- */
-uint8_t TraingModel::GetHeartRateData(void) {
-  uint8_t hrs = 0;
-#ifdef SUPPORT_PPG_SERVICE
-  hrs = ppg_get_hrs();
-#endif
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Heart rate data: %d", hrs);
-  return hrs;
-}
-
-static void sport_data_time_proc(int data) {
-  //增加训练runtime控制
-  if (uapi_dev_runtime_get_train_status() == 0 ||
-      TraingModel::GetInstance()->GetSportState() == ExerciseState::End) {
-    return;
-  }
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sport_data_time_proc");
-
-  // 获取并处理运动基础数据
-  TraingModel::GetInstance()->GetSportActivityData();
-
-  // 获取并处理运动额外数据 前提是特殊运动
-  if (TraingModel::GetInstance()->GetIsSpecial()) {
-    TraingModel::GetInstance()->GetSportExtraData();
-  }
-
-  // 获取并处理心率数据
-  uint8_t heartRate = TraingModel::GetInstance()->GetHeartRateData();
-  TraingModel::GetInstance()->AnalysisHeartData(heartRate);
-
-  // 更新UI
-  if (TraingCardPresenter::GetInstance()) {
-    TraingCardPresenter::GetInstance()->updataview();
-  }
-}
-
-static void sport_data_time_callback(int data) {
-  GraphicService::GetInstance()->PostGraphicEvent(
-      std::bind(sport_data_time_proc, data));
-}
-
-void TraingModel::sport_start_data_timer(uint32_t interval) {
-  WEARABLE_LOGE(
-      WEARABLE_LOG_MODULE_APP,
-      "TraingModel::sport_start_data_timer - Starting sport data timer");
-  if (g_sport_start_data_timer != nullptr) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sport Data Timer already exists!!");
-    return;
-  }
-  g_sport_start_data_timer = osTimerNew((osTimerFunc_t)sport_data_time_callback,
-                                        osTimerPeriodic, nullptr, nullptr);
-  if (g_sport_start_data_timer == nullptr) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sport Data Timer create failed!!");
-    return;
-  }
-  int tick = osMs2Tick(interval);
-  osStatus_t ret = osTimerStart(g_sport_start_data_timer, tick);
-  if (ret != osOK) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                  "Sport Data Timer start failed, ret = %lx!!", ret);
-    if (g_sport_start_data_timer != nullptr) {
-      ret = osTimerDelete(g_sport_start_data_timer);
-    }
-    g_sport_start_data_timer = nullptr;
-    return;
-  }
-}
-
-void TraingModel::sport_stop_data_timer(void) {
-  // 检查运动数据采集定时器是否存在
-  if (g_sport_start_data_timer != nullptr) {
-    WEARABLE_LOGE(
-        WEARABLE_LOG_MODULE_APP,
-        "TraingModel::sport_stop_data_timer - Stopping sport data timer");
-    osTimerStop(g_sport_start_data_timer);
-    // 删除定时器并置为 nullptr
-    osStatus_t ret = osTimerDelete(g_sport_start_data_timer);
-    if (ret != osOK) {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "Sport Data Timer delete failed, ret = %lx!!", ret);
-    }
-    g_sport_start_data_timer = nullptr;
-  }
-}
-#endif
-
-#ifdef BLE_INSTRUCT
-
-#include "bleEvent.h"
-#include "bleInstruct.h"
-
-//////////////////////////////ble////////////////////////////////////////////
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
-bool get_training_spead_path_(char *path, uint32_t time, uint32_t max_len) {
-  std::string str = OHOS::TraingModel::GetInstance()->GetPaceTablePath(time);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "get_training_spead:%s\r\n",
-                str.c_str());
-  if (str.length() <= 3) {
-    return false;
-  }
-  memcpy_s(path, max_len, str.c_str(), str.length());
-  return true;
-}
-
-bool get_training_heart_path_(char *path, uint32_t time, uint32_t max_len) {
-  std::string str = OHOS::TraingModel::GetInstance()->GetHeartTablePath(time);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "get_training_heart:%s\r\n",
-                str.c_str());
-  if (str.length() <= 3) {
-    return false;
-  }
-  memcpy_s(path, max_len, str.c_str(), str.length());
-  return true;
-}
-
-//获取gps轨迹路径
-bool get_training_gps_path_(char *path, uint32_t time, uint32_t max_len) {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 获取GPS轨迹路径开始 ===");
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "请求时间戳: %u, 最大路径长度: %u",
-                time, max_len);
-
-  std::string str = OHOS::TraingModel::GetInstance()->GetGPSDataPath(time);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "获取到的GPS路径: %s", str.c_str());
-
-  if (str.length() <= 3) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "错误: GPS路径长度不足,长度: %zu",
-                  str.length());
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 获取GPS轨迹路径结束(失败) ===");
-    return false;
-  }
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS路径长度: %zu", str.length());
-  memcpy_s(path, max_len, str.c_str(), str.length());
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS路径复制完成");
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 获取GPS轨迹路径结束(成功) ===");
-  return true;
-}
-
-char *struct_to_json_buf_malloc_(uint8_t day) {
-  cJSON *dataJSON = cJSON_CreateObject();
-  cJSON *data_arryJSON = cJSON_CreateArray();
-  struct Trainingdata *data = NULL;
-  int i = 0;
-  // char file_path[128] = {0};
-  char timeday[12] = {0};
-  uapi_get_YYMMDD_Time_extend(timeday, '_', day);
-  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%s\r\n", timeday);
-  // sprintf(file_path, "%s%s.bin", TRAINING_PATH_BLE, timeday);
-
-  while (data = read_Trainingdata_data(timeday, i)) {
-    cJSON *itemJSON = cJSON_CreateObject();
-    if (data != NULL) {
-      cJSON_AddNumberToObject(itemJSON, "src", data->src);
-      cJSON_AddNumberToObject(itemJSON, "bt", data->bt);
-      cJSON_AddNumberToObject(itemJSON, "ty", data->ty);
-      cJSON_AddNumberToObject(itemJSON, "st", data->st);
-      cJSON_AddNumberToObject(itemJSON, "sp", data->sp);
-      cJSON_AddNumberToObject(itemJSON, "tgt", data->tgt);
-      cJSON_AddNumberToObject(itemJSON, "tg", data->tg);
-      cJSON_AddNumberToObject(itemJSON, "pg", data->pg);
-      cJSON_AddNumberToObject(itemJSON, "du", data->du);
-      cJSON_AddNumberToObject(itemJSON, "ca", data->ca);
-      cJSON_AddNumberToObject(itemJSON, "di", data->di);
-      cJSON_AddNumberToObject(itemJSON, "hr", data->hr);
-      cJSON_AddNumberToObject(itemJSON, "stp", data->stp);
-      cJSON_AddNumberToObject(itemJSON, "ti", data->ti);
-      cJSON_AddNumberToObject(itemJSON, "cir", data->cir);
-      cJSON_AddNumberToObject(itemJSON, "alt", data->alt);
-      cJSON_AddNumberToObject(itemJSON, "apc", data->apc);
-      cJSON_AddNumberToObject(itemJSON, "fpc", data->fpc);
-      cJSON_AddNumberToObject(itemJSON, "spc", data->spc);
-      cJSON_AddNumberToObject(itemJSON, "std", data->std);
-      cJSON_AddNumberToObject(itemJSON, "cdc", data->cdc);
-      cJSON_AddItemReferenceToArray(data_arryJSON, itemJSON);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"src:%d",data->src);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"bt:%d",data->bt);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ty:%d",data->ty);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"st:%d",data->st);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sp:%d",data->sp);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tgt:%d",data->tgt);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tg:%d",data->tg);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"pg:%d",data->pg);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"du:%d",data->du);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ca:%d",data->ca);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"di:%d",data->di);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hr:%d",data->hr);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"stp:%d",data->stp);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ti:%d",data->ti);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cir:%d",data->cir);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"alt:%d",data->alt);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"apc:%d",data->apc);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"fpc:%d",data->fpc);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"spc:%d",data->spc);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"std:%d",data->std);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cdc:%d",data->cdc);
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
-      free(data);
-      data = NULL;
-    } else {
-      break;
-    }
-    i++;
-  }
-  cJSON_AddItemToObject(dataJSON, "recs", data_arryJSON);
-
-  char *json_format = cJSON_PrintUnformatted(dataJSON);
-
-  int pSize = cJSON_GetArraySize(dataJSON);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "训练历史数据:%s\r\n", json_format);
-  cJSON_Delete(dataJSON);
-  return json_format;
-}
-
-int read_gps_data_(char *path, uint8_t *out_buf) {
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 读取GPS数据开始 ===");
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件路径: %s", path);
-
-  FILE *fp = fopen(path, "rb+");
-  if (fp == NULL) {
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "错误: 无法打开GPS文件");
-    return 0;
-  }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件打开成功");
-
-  uint32_t file_size = 0;
-  fseek(fp, 0, SEEK_END);
-  file_size = ftell(fp);
-  fseek(fp, 0, SEEK_SET);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件大小: %u 字节", file_size);
-
-  int len = 0;
-  int point_count = 0;
-  OHOS::GPSData_t data = {0};
-
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始读取GPS轨迹点...");
-  while (1) {
-    int read_size = fread(&data, 1, sizeof(data), fp);
-    if (read_size == sizeof(data)) {
-      point_count++;
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "读取GPS点 #%d: 时间戳=%u, 纬度=%.6f, 经度=%.6f",
-                    point_count, data.timestamp, data.latitude, data.longitude);
-
-      int temp_data = data.timestamp;
-      memcpy_s(out_buf + len, 4, &temp_data, sizeof(data.timestamp));
-      len += 4;
-
-      int temp_latitude = (int)(data.latitude * 10000000);
-      memcpy_s(out_buf + len, 4, &temp_latitude, sizeof(temp_latitude));
-      len += 4;
-
-      int temp_longitude = (int)(data.longitude * 10000000);
-      memcpy_s(out_buf + len, 4, &temp_longitude, sizeof(temp_longitude));
-      len += 4;
-
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "GPS点数据转换: 时间戳=%u, 纬度=%d, 经度=%d", temp_data,
-                    temp_latitude, temp_longitude);
-    } else {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件读取结束,读取大小: %d",
-                    read_size);
-      break;
-    }
-  }
-
-  fclose(fp);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS文件关闭");
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                "总共读取 %d 个GPS点,输出数据长度: %d 字节", point_count, len);
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "=== 读取GPS数据结束 ===");
-
-  return len;
-}
-
-//通过时间戳获取训练数据
-cJSON* ble_get_Trainingdata_by_timetamp_(uint32_t timetamp)
-{
-    struct Trainingdata * data=NULL;
-    int i=0;
-  
-    time_t currtime=timetamp;
-    struct tm *timeinfo;
-    timeinfo = localtime(&currtime);
-    int y=timeinfo->tm_year+ 1900;
-    int m=timeinfo->tm_mon+1;
-    int d=timeinfo->tm_mday;
-    int h=timeinfo->tm_hour;
-    int min=timeinfo->tm_min;
-
-    char timeday[24]={0};
-    sprintf_s(timeday,24,"%d_%02d_%02d",y,m,d);
-
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"%s\r\n",timeday);
-
-    while(data=read_Trainingdata_data(timeday, i))
-    {
-        if(data!=NULL)
-        {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"%d,%d\r\n",timetamp,data->st);
-            // 打印data数据
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"src:%d",data->src);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"bt:%d",data->bt);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ty:%d",data->ty);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"st:%d",data->st);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sp:%d",data->sp);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tgt:%d",data->tgt);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tg:%d",data->tg);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"pg:%d",data->pg);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"du:%d",data->du);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ca:%d",data->ca);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"di:%d",data->di);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hr:%d",data->hr);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"stp:%d",data->stp);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ti:%d",data->ti);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cir:%d",data->cir);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"alt:%d",data->alt);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"apc:%d",data->apc);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"fpc:%d",data->fpc);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"spc:%d",data->spc);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"std:%d",data->std);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cdc:%d",data->cdc);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"*******************************");
-            int time_error= timetamp>data->st ? timetamp-data->st:data->st-timetamp;
-            if(time_error<=2)
-            {
-                cJSON* itemJSON = cJSON_CreateObject();
-                cJSON_AddNumberToObject(itemJSON, "src", data->src);
-                cJSON_AddNumberToObject(itemJSON,"bt",data->bt);
-                cJSON_AddNumberToObject(itemJSON,"ty",data->ty);
-                cJSON_AddNumberToObject(itemJSON,"st",data->st);
-                cJSON_AddNumberToObject(itemJSON,"sp",data->sp);
-                cJSON_AddNumberToObject(itemJSON,"tgt",data->tgt);
-                cJSON_AddNumberToObject(itemJSON,"tg",data->tg);
-                cJSON_AddNumberToObject(itemJSON,"pg",data->pg);
-                cJSON_AddNumberToObject(itemJSON,"du",data->du);
-                cJSON_AddNumberToObject(itemJSON,"ca",data->ca);
-                cJSON_AddNumberToObject(itemJSON,"di",data->di);
-                cJSON_AddNumberToObject(itemJSON,"hr",data->hr);
-                cJSON_AddNumberToObject(itemJSON,"stp",data->stp);
-                cJSON_AddNumberToObject(itemJSON,"ti",data->ti);
-                cJSON_AddNumberToObject(itemJSON,"cir",data->cir);
-                cJSON_AddNumberToObject(itemJSON, "alt", data->alt);
-                cJSON_AddNumberToObject(itemJSON,"apc",data->apc);
-                cJSON_AddNumberToObject(itemJSON,"fpc",data->fpc);
-                cJSON_AddNumberToObject(itemJSON,"spc",data->spc);
-                cJSON_AddNumberToObject(itemJSON,"std",data->std);
-                cJSON_AddNumberToObject(itemJSON,"cdc",data->cdc);
-                free(data);
-                return itemJSON;
-            }
-
-            free(data);
-            data=NULL;
-        }
-        else{
-            break;
-        }
-        i++;
-    }
-    return NULL;
-}
-
-extern bleInstruct_t_ bleInstruct_t;
-
-void ble_training_init(void) {
-  bleInstruct_t.get_training_spead_path_cb = get_training_spead_path_;
-  bleInstruct_t.get_training_heart_path_cb = get_training_heart_path_;
-  bleInstruct_t.get_training_gps_path_cb = get_training_gps_path_;
-  bleInstruct_t.struct_to_json_buf_malloc = struct_to_json_buf_malloc_;
-  bleInstruct_t.read_gps_data_cb = read_gps_data_;
-  bleInstruct_t.ble_get_Trainingdata_by_timetamp = ble_get_Trainingdata_by_timetamp_;
-}
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
-#endif
-
-/*
- * 定时器分工总结:
- *
- * 1. 位置服务定时器 (g_location_timer)
- *    - 频率:1秒间隔
- *    - 功能:GPS定位、连接状态更新、轨迹数据采集
- *    - 特点:中等频率,保证位置数据实时性
- *
- * 2. 运动数据采集定时器 (g_sport_start_data_timer)
- *    - 频率:300毫秒间隔
- *    - 功能:运动数据采集、心率监测、目标完成度检查、UI更新
- *    - 特点:高频率,保证运动数据实时性和准确性
- *
- * 数据获取函数封装(职责单一,无耦合):
- * - GetSportActivityData(): 获取运动基础数据,返回是否成功
- * - GetSportExtraData(): 获取运动额外数据,返回是否成功
- * - GetHeartRateData(): 获取心率数据,返回心率值
- * - 数据分析和处理逻辑在定时器回调中协调完成
- *
- * 两个定时器独立运行,互不干扰,根据各自功能特点选择合适的执行频率
- */
-
-} // namespace OHOS
+ 
+ } // namespace OHOS
+ 
\ No newline at end of file
index 09cec2a..14d7b84 100644 (file)
@@ -1416,17 +1416,17 @@ void CWM_AP_SensorListen(pSensorEVT_t sensorEVT) {
             if((int)sensorEVT->fData[1] == CUSTOM_GNSS)
             {
                 CWM_OS_dbgPrintf("CUSTOM_GNSS !!! \r\n");
-#ifdef SUPPORT_GNSS
-                if((int)sensorEVT->fData[2] == 1)
-                {
+// #ifdef SUPPORT_GNSS
+//                 if((int)sensorEVT->fData[2] == 1)
+//                 {
 
-                    gnss_start();
-                }
-                else
-                {
-                    gnss_stop();
-                }
-#endif
+//                     gnss_start();
+//                 }
+//                 else
+//                 {
+//                     gnss_stop();
+//                 }
+// #endif
             }
              break;
         case IDX_ALGO_SHAKE: