心率:增加读取控制
authorCaisking <3449750381@qq.com>
Wed, 23 Oct 2024 03:59:01 +0000 (11:59 +0800)
committerCaisking <3449750381@qq.com>
Wed, 23 Oct 2024 03:59:01 +0000 (11:59 +0800)
code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.cpp
code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.h
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp
code/sdk/application/wearable/fd230app/nativeui/safemodemanager/include/SafeModeManagerModelC.h
code/sdk/drivers/peripheral/utils/custom_fileoperate_service.c

index 85786f1..a19afb1 100644 (file)
@@ -1,21 +1,22 @@
 #include "health_service.h"
-#include <iostream>
-#include "wearable_log.h"
+#include "bloodoxygen/include/BloodOxygenModel.h"
 #include "cJSON.h"
-#include <sys/stat.h>
-#include <ctime>
+#include "heartrate/include/HeartModel.h"
 #include "kv_store.h"
-#include "custom_utils.h"
-#include "custom_runtime.h"
+#include "wearable_log.h"
+#include <cstdint>
+#include <ctime>
 #include <fstream>
+#include <iostream>
 #include <sstream>
 #include <string>
-#include <cstdint>
-#include "heartrate/include/HeartModel.h"
-#include "bloodoxygen/include/BloodOxygenModel.h"
+#include <sys/stat.h>
 
-namespace OHOS
-{
+#include "custom_runtime.h"
+#include "custom_utils.h"
+
+#include "safemodemanager/include/SafeModeManagerModelC.h"
+namespace OHOS {
 extern "C" {
 void uapi_dev_runtime_set_bloodoxygen_storage_status(uint8_t status);
 void uapi_dev_runtime_set_heartrate_storage_status(uint8_t status);
@@ -28,11 +29,56 @@ void save_heart_data() {
 
 void save_heart_maxmin() {
   printf("save_heart_maxmin\r\n");
-  uint16_t max_heart_data = OHOS::HeartModel::GetInstance()->GetShowMaxHeartdata();
-  uint16_t min_heart_data = OHOS::HeartModel::GetInstance()->GetShowMinHeartdata();
+  uint16_t max_heart_data =
+      OHOS::HeartModel::GetInstance()->GetShowMaxHeartdata();
+  uint16_t min_heart_data =
+      OHOS::HeartModel::GetInstance()->GetShowMinHeartdata();
 
   OHOS::HealthService::GetInstance()->SaveHeartMaxMin(max_heart_data,
-                                                       min_heart_data);
+                                                      min_heart_data);
+  return;
+}
+void save_blood_oxygen_data() {
+  OHOS::BloodOxygenData data;
+  data.SPO2 = OHOS::BloodOxygenModel::GetInstance()->GetSPO2data();
+  data.timestamp = OHOS::BloodOxygenModel::GetInstance()->GetCheckTime();
+  // 进行血氧存储 如果处于读取
+  if (uapi_dev_runtime_get_bloodoxygen_storage_status()) {
+    printf("save_blood_oxygen_data is reading\n");
+    //进行延迟
+    LOS_Msleep(100);
+    if (uapi_dev_runtime_get_bloodoxygen_storage_status()) {
+      printf("save_blood_oxygen_data is reading again\n");
+      //重新发送该消息
+      do_custom_fileoperate_service_check_msg(
+          CUSTOM_FILEOPERATE_MSG_TYPE_BLOODXYGEN_SAVE, nullptr, 0);
+      return;
+    }
+  }
+  HealthService::GetInstance()->UpdateHealthData(data);
+  printf("save_blood_oxygen_data success\n");
+  return;
+}
+
+void save_heart_rate_data() {
+  OHOS::HeartRateData data;
+  data.Heart = OHOS::HeartModel::GetInstance()->GetHeartdata();
+  data.timestamp = OHOS::HeartModel::GetInstance()->GetCheckTime();
+  // 进行心率存储 如果处于读取
+  if (uapi_dev_runtime_get_heartrate_storage_status()) {
+    printf("save_heart_rate_data is reading\n");
+    //进行延迟
+    LOS_Msleep(100);
+    if (uapi_dev_runtime_get_heartrate_storage_status()) {
+      printf("save_heart_rate_data is reading again\n");
+      //重新发送该消息
+      do_custom_fileoperate_service_check_msg(
+          CUSTOM_FILEOPERATE_MSG_TYPE_HEARTRATE_SAVE, nullptr, 0);
+      return;
+    }
+  }
+  HealthService::GetInstance()->UpdateHealthData(data);
+  printf("save_heart_rate_data success\n");
   return;
 }
 }
@@ -98,493 +144,481 @@ bool HealthService::CreateHealthFolder() {
       WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
                     "mkdir HEALTH_JSON_PATH_OXYGEN is error");
       return false;
-       }
-   }
-
-        return true;
     }
+  }
 
-    /*生成bin*/
-    std::string GetBinFilePath(uint8_t type)
-    {
-        std::string currentDate = GetCurrentDate();
-        const char *healthTypePath = (type == HEALTH_TYPE_HEART) ? HEALTH_JSON_PATH_HEART : HEALTH_JSON_PATH_OXYGEN;
+  return true;
+}
 
-        return healthTypePath + currentDate + ".bin";
-    }
+/*生成bin*/
+std::string GetBinFilePath(uint8_t type) {
+  std::string currentDate = GetCurrentDate();
+  const char *healthTypePath = (type == HEALTH_TYPE_HEART)
+                                   ? HEALTH_JSON_PATH_HEART
+                                   : HEALTH_JSON_PATH_OXYGEN;
 
-    /* --------------------------------- json操作 --------------------------------- */
-    static constexpr const char *HEART_JSON_PATH = "/user/userdata/health/heart.json";
-    static constexpr const char *BLOOD_JSON_PATH = "/user/userdata/health/blood.json";
-
-    // 读取血氧数据  
-    BloodOxygenData *HealthService::ReadBloodOxygenData()  
-    {  
-        // 判断文件夹是否存在  
-        if (!CreateHealthFolder())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create health folder");  
-            return nullptr;  
-        }  
-
-        // 读取文件  
-        std::ifstream inFile(BLOOD_JSON_PATH);  
-        if (!inFile.is_open())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open JSON file");  
-            return nullptr;  
-        }  
-
-        // 读取文件内容到字符串  
-        std::stringstream buffer;  
-        buffer << inFile.rdbuf();  
-        std::string jsonDataString = buffer.str();  
-        const char *jsonData = jsonDataString.c_str();  
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData);  
-
-        // 关闭文件  
-        inFile.close();  
-
-        if (jsonDataString.empty())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty");  
-            return nullptr;  
-        }  
-
-        cJSON *oxygen_root = cJSON_Parse(jsonData);  
-        if (oxygen_root == NULL)  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse JSON data");  
-            return nullptr;  
-        }  
-
-        BloodOxygenData *data = new BloodOxygenData();  
-
-        cJSON *value_item = cJSON_GetObjectItem(oxygen_root, "value");  
-        cJSON *timestamp_item = cJSON_GetObjectItem(oxygen_root, "timestamp");  
-
-        // 检查是否存在必要字段,并验证数据类型  
-        if (value_item && cJSON_IsNumber(value_item) && timestamp_item && cJSON_IsNumber(timestamp_item))  
-        {  
-            data->SPO2 = value_item->valueint;  
-            data->timestamp = timestamp_item->valuedouble;  
-
-            // 进一步验证数据的合理性  
-            if (data->SPO2 < 0 || data->SPO2 > 100)  // 血氧饱和度范围是0-100  
-            {  
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid SPO2 value: %d", data->SPO2);  
-                cJSON_Delete(oxygen_root);  
-                delete data;  
-                return nullptr;  
-            }  
-        }  
-        else  
-        {  
-            // 读取的数据异常  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing or invalid data fields");  
-            cJSON_Delete(oxygen_root);  
-            delete data;  
-            return nullptr;  
-        }  
-
-        cJSON_Delete(oxygen_root);  
-        return data;  
-    }
+  return healthTypePath + currentDate + ".bin";
+}
 
-    // 读取心率数据  
-    HeartRateData *HealthService::ReadHeartRateData()  
-    {  
-        // 判断文件夹是否存在  
-        if (!CreateHealthFolder())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create health folder");  
-            return nullptr;  
-        }  
-
-        // 读取文件  
-        std::ifstream inFile(HEART_JSON_PATH);  
-        if (!inFile.is_open())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open JSON file, creating default data");  
-            
-            // 创建默认值为 0 的数据并存储到 JSON 文件  
-            HeartRateData defaultData;  
-            defaultData.Heart = 0;  // 默认心率值  
-            defaultData.timestamp = static_cast<double>(time(nullptr));  // 当前时间戳  
-
-            // 创建 JSON 对象并写入文件  
-            cJSON *defaultRoot = cJSON_CreateObject();  
-            cJSON_AddNumberToObject(defaultRoot, "value", defaultData.Heart);  
-            cJSON_AddNumberToObject(defaultRoot, "timestamp", defaultData.timestamp);  
-
-            // 写入 JSON 文件  
-            FILE *file = fopen(HEART_JSON_PATH, "w");  
-            if (file)  
-            {  
-                char *jsonString = cJSON_Print(defaultRoot);  
-                fprintf(file, "%s", jsonString);  
-                fclose(file);  
-                free(jsonString);  
-            }  
-            cJSON_Delete(defaultRoot);  
-
-            // 返回默认数据  
-            HeartRateData *data = new HeartRateData(defaultData);  
-            return data;  
-        }  
-
-        // 读取文件内容到字符串  
-        std::stringstream buffer;  
-        buffer << inFile.rdbuf();  
-        std::string jsonDataString = buffer.str();  
-        const char *jsonData = jsonDataString.c_str();  
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData);  
-
-        // 关闭文件  
-        inFile.close();  
-
-        if (jsonDataString.empty())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty");  
-            return nullptr;  
-        }  
-
-        cJSON *heart_root = cJSON_Parse(jsonData);  
-        if (heart_root == NULL)  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse JSON data");  
-            return nullptr;  
-        }  
-
-        HeartRateData *data = new HeartRateData();  
-
-        cJSON *value_item = cJSON_GetObjectItem(heart_root, "value");  
-        cJSON *timestamp_item = cJSON_GetObjectItem(heart_root, "timestamp");  
-
-        // 检查是否存在必要字段,并验证数据类型  
-        if (value_item && cJSON_IsNumber(value_item) && timestamp_item && cJSON_IsNumber(timestamp_item))  
-        {  
-            data->Heart = value_item->valueint;  
-            data->timestamp = timestamp_item->valuedouble;  
-        }  
-        else  
-        {  
-            // 读取的数据异常  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing or invalid data fields");  
-            cJSON_Delete(heart_root);  
-            delete data;  
-            return nullptr;  
-        }  
-
-        cJSON_Delete(heart_root);  
-        return data;  
-    }
+/* --------------------------------- json操作 ---------------------------------
+ */
+static constexpr const char *HEART_JSON_PATH =
+    "/user/userdata/health/heart.json";
+static constexpr const char *BLOOD_JSON_PATH =
+    "/user/userdata/health/blood.json";
+
+// 读取血氧数据
+BloodOxygenData *HealthService::ReadBloodOxygenData() {
+  // 判断文件夹是否存在
+  if (!CreateHealthFolder()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create health folder");
+    return nullptr;
+  }
 
-    // 保存血氧数据
-    bool HealthService::UpdateHealthData(const BloodOxygenData &data)  
-    {  
-        // 配置血氧存储状态  
-        uapi_dev_runtime_set_bloodoxygen_storage_status(1);  
-
-        // 判断文件夹是否存在  
-        if (!CreateHealthFolder())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file");  
-            uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        // 判断文件是否存在,不存在即创建并打开以输出模式  
-        std::ofstream outFile(BLOOD_JSON_PATH, std::ios::trunc);  
-        if (!outFile.is_open())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create or open JSON file for writing");  
-            uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        // 创建一个 JSON 对象  
-        cJSON *oxygen_root = cJSON_CreateObject();  
-        if (oxygen_root == NULL)  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create JSON object");  
-            outFile.close();  
-            uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        cJSON_AddItemToObject(oxygen_root, "value", cJSON_CreateNumber(data.SPO2));  
-        cJSON_AddItemToObject(oxygen_root, "timestamp", cJSON_CreateNumber(data.timestamp));  
-
-        char *jsonData = cJSON_Print(oxygen_root);  
-        if (jsonData == NULL)  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data");  
-            cJSON_Delete(oxygen_root); // 释放内存  
-            outFile.close();  
-            uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        // 写入 JSON 数据到文件  
-        outFile << jsonData;  
-
-        // 释放资源  
-        cJSON_Delete(oxygen_root);  
-        free(jsonData);  
-        outFile.close();  
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHealthData SPO2 JSON is ok");  
-
-        /* 存储bin文件[协议使用] */  
-        std::string binFilePath = GetBinFilePath(HEALTH_TYPE_OXYGEN);  
-        FILE *fp = fopen(binFilePath.c_str(), "ab+");  
-        if (fp == NULL)  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open binary file for writing");  
-            uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        // 写入数据  
-        if (fwrite(&data.timestamp, sizeof(data.timestamp), 1, fp) != 1 ||  
-            fwrite(&data.SPO2, sizeof(data.SPO2), 1, fp) != 1)  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to write data to binary file");  
-            fclose(fp);  
-            uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        fclose(fp);  
-
-
-        uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态  
-        return true;  
-    }
+  // 读取文件
+  std::ifstream inFile(BLOOD_JSON_PATH);
+  if (!inFile.is_open()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open JSON file");
+    return nullptr;
+  }
 
-    //存储心率
-    bool HealthService::UpdateHealthData(const HeartRateData &data)  
-    {  
-        // 配置心率存储状态  
-        uapi_dev_runtime_set_heartrate_storage_status(1);  
-
-        // 判断文件夹是否存在  
-        if (!CreateHealthFolder())  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file");  
-            uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        // 判断文件是否存在,不存在即创建并打开以输出模式  
-        std::ofstream outFile(HEART_JSON_PATH, std::ios::trunc);  
-        if (!outFile.is_open())  
-        {  
-            // 文件创建失败  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create or open JSON file for writing");  
-            uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        // 创建一个 JSON 对象  
-        cJSON *heart_root = cJSON_CreateObject();  
-        if (heart_root == NULL)  
-        {  
-            outFile.close();  
-            uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        cJSON_AddItemToObject(heart_root, "value", cJSON_CreateNumber(data.Heart));  
-        cJSON_AddItemToObject(heart_root, "timestamp", cJSON_CreateNumber(data.timestamp));  
-
-        char *jsonData = cJSON_Print(heart_root);  
-        if (jsonData == NULL)  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data");  
-            cJSON_Delete(heart_root); // 使用 cJSON_Delete 释放内存  
-            outFile.close();  
-            uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态  
-        return false;  
-        }  
-
-        // 写入 JSON 数据到文件  
-        outFile << jsonData;  
-
-        // 释放资源  
-        cJSON_Delete(heart_root);  
-        free(jsonData);  
-        outFile.close();  
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHealthData Heart JSON is ok");  
-
-        // 写入文件到当天历史数据  
-        UpdateHourlyHeartRate(data.timestamp, data.Heart);
-
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHourlyHeartRate is ok");  
-
-        if (!SaveDailyHeartRate()) // 进行心率历史数据文件存储  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDailyHeartRate failed");  
-            uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        /* 存储 bin 文件 [协议使用] */  
-        std::string binFilePath = GetBinFilePath(HEALTH_TYPE_HEART);  
-        FILE *fp = fopen(binFilePath.c_str(), "ab+");  
-        if (fp == NULL)  
-        {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open binary file for writing");  
-            uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态  
-            return false;  
-        }  
-
-        // 写入数据  
-        if (fwrite(&data.timestamp, sizeof(data.timestamp), 1, fp) != 1 ||  
-        fwrite(&data.Heart, sizeof(data.Heart), 1, fp) != 1)  
-        {  
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to write data to binary file");  
-        fclose(fp);  
-        uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态  
-        return false;  
-        }  
-
-        fclose(fp);  
-
-        uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态  
-        return true;  
-    }
-    // 清空健康数据
-    bool HealthService::CleanHealthData() {
-        //清空心率数组
-        ClearHourlyHeartRates();
-        //进行数据存储
-        SaveDailyHeartRate();
-
-        HeartModel::GetInstance()->ClearDisplayData();
-        // BloodOxygenModel::GetInstance()->ClearDisplayData();
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CleanHealthData  is ok");
-        return true;
-    }
+  // 读取文件内容到字符串
+  std::stringstream buffer;
+  buffer << inFile.rdbuf();
+  std::string jsonDataString = buffer.str();
+  const char *jsonData = jsonDataString.c_str();
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData);
 
-    HealthState HealthService::GetHealthCurrent()
-    {
-        return healthState_;
-    }
-    void HealthService::SetHealthCurrent(HealthState healthState)
+  // 关闭文件
+  inFile.close();
+
+  if (jsonDataString.empty()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty");
+    return nullptr;
+  }
+
+  cJSON *oxygen_root = cJSON_Parse(jsonData);
+  if (oxygen_root == NULL) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse JSON data");
+    return nullptr;
+  }
+
+  BloodOxygenData *data = new BloodOxygenData();
+
+  cJSON *value_item = cJSON_GetObjectItem(oxygen_root, "value");
+  cJSON *timestamp_item = cJSON_GetObjectItem(oxygen_root, "timestamp");
+
+  // 检查是否存在必要字段,并验证数据类型
+  if (value_item && cJSON_IsNumber(value_item) && timestamp_item &&
+      cJSON_IsNumber(timestamp_item)) {
+    data->SPO2 = value_item->valueint;
+    data->timestamp = timestamp_item->valuedouble;
+
+    // 进一步验证数据的合理性
+    if (data->SPO2 < 0 || data->SPO2 > 100) // 血氧饱和度范围是0-100
     {
-        healthState_ = healthState;
-    }
-    /* ------------------------------- 心率当天历史数据处理 ------------------------------ */
-    static constexpr const char *HEART_DATA_PATH =  "/user/userdata/health/heart_history.bin";
-
-    //清空数组
-    void HealthService::ClearHourlyHeartRates() {  
-        for (int i = 0; i < MAX_HOURS; ++i) {  
-            dailyHeartRates[i].Heart = 0;  
-            dailyHeartRates[i].timestamp = 0;  
-        }
-    }
-    
-    // 加载心率列表  
-    bool HealthService::LoadDailyHeartRate() {  
-        ClearHourlyHeartRates();  // 清空数组  
-
-        // 使用 RAII 管理文件流  
-        std::ifstream file(HEART_DATA_PATH, std::ios::binary);  
-        if (!file.is_open()) {  
-            std::cerr << "Error: Unable to open heart rate data file for reading" << std::endl;  
-            return false;  
-        }  
-
-        // 读取时间戳  
-        file.read(reinterpret_cast<char *>(&lastLoadTime), sizeof(lastLoadTime));  
-        if (lastLoadTime == 0) {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDailyHeartRate is not today");  
-            return false; // 无有效数据  
-        }  
-
-        // 判断时间戳是否为今天  
-        tm *lastTm = localtime(&lastLoadTime);  
-        time_t now = time(nullptr);  
-        tm *currentTm = localtime(&now);  
-        if (currentTm->tm_year == lastTm->tm_year && currentTm->tm_yday == lastTm->tm_yday) {  
-            // 今天:进行数据读取  
-            for (int i = 0; i < MAX_HOURS; ++i) {  
-                HeartRateData rate; // 假设您有一个 HeartRateData 结构体  
-                if (!file.read(reinterpret_cast<char *>(&rate), sizeof(rate))) {  
-                    std::cerr << "Error: Failed to read heart rate data." << std::endl;  
-                    return false; // 读取失败  
-                }  
-                dailyHeartRates[i] = rate; // 保存心率和时间戳  
-                std::cout << "Hour " << i << ": Heart Rate " << rate.Heart << std::endl;  
-            }  
-            return true; // 成功读取  
-        }  
-
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDailyHeartRate is not today");  
-        return false; // 不是今日  
-    }  
-
-    // 保存今日心率列表  
-    bool HealthService::SaveDailyHeartRate() {  
-        std::ofstream outFile(HEART_DATA_PATH, std::ios::binary | std::ios::trunc);  
-        if (!outFile.is_open()) {  
-            std::cerr << "Error: Unable to open heart rate data file for writing" << std::endl;  
-            return false; // 文件打开失败  
-        }  
-
-        // 存储时间戳  
-        time_t currentTime = time(nullptr);  
-        outFile.write(reinterpret_cast<const char *>(&currentTime), sizeof(currentTime));  
-
-        // 存储心率数据  
-        for (const auto& rate : dailyHeartRates) {  
-            if (!outFile.write(reinterpret_cast<const char *>(&rate), sizeof(rate))) {  
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to write heart rate data to file");  
-                return false; // 写入失败  
-            }  
-        }  
-
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDailyHeartRate is ok");  
-        return true; // 成功保存  
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid SPO2 value: %d",
+                    data->SPO2);
+      cJSON_Delete(oxygen_root);
+      delete data;
+      return nullptr;
     }
+  } else {
+    // 读取的数据异常
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing or invalid data fields");
+    cJSON_Delete(oxygen_root);
+    delete data;
+    return nullptr;
+  }
+
+  cJSON_Delete(oxygen_root);
+  return data;
+}
 
-    // 更新心率列表项
-    void HealthService::UpdateHourlyHeartRate(time_t timestamp, uint16_t heartRate) {  
-        struct tm *timeInfo = localtime(&timestamp);  
-        uint16_t hour = static_cast<uint16_t>(timeInfo->tm_hour);  
-
-        if (hour < MAX_HOURS && heartRate > 0) {  
-            dailyHeartRates[hour] = {heartRate, timestamp}; // 更新心率和时间戳
-            currenthour = hour; // 记录当前小时
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHourlyHeartRate is ok");
-        }
-        else {  
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid hour or heart rate value %d",hour);
-        }
+// 读取心率数据
+HeartRateData *HealthService::ReadHeartRateData() {
+  // 判断文件夹是否存在
+  if (!CreateHealthFolder()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create health folder");
+    return nullptr;
+  }
+
+  // 读取文件
+  std::ifstream inFile(HEART_JSON_PATH);
+  if (!inFile.is_open()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Failed to open JSON file, creating default data");
+
+    // 创建默认值为 0 的数据并存储到 JSON 文件
+    HeartRateData defaultData;
+    defaultData.Heart = 0; // 默认心率值
+    defaultData.timestamp = static_cast<double>(time(nullptr)); // 当前时间戳
+
+    // 创建 JSON 对象并写入文件
+    cJSON *defaultRoot = cJSON_CreateObject();
+    cJSON_AddNumberToObject(defaultRoot, "value", defaultData.Heart);
+    cJSON_AddNumberToObject(defaultRoot, "timestamp", defaultData.timestamp);
+
+    // 写入 JSON 文件
+    FILE *file = fopen(HEART_JSON_PATH, "w");
+    if (file) {
+      char *jsonString = cJSON_Print(defaultRoot);
+      fprintf(file, "%s", jsonString);
+      fclose(file);
+      free(jsonString);
     }
+    cJSON_Delete(defaultRoot);
+
+    // 返回默认数据
+    HeartRateData *data = new HeartRateData(defaultData);
+    return data;
+  }
 
-    // 获取指定小时的心率
-    uint16_t HealthService::GetHourlyHeartRate(uint16_t hour) {  
-        if (hour < MAX_HOURS) {  
-            return dailyHeartRates[hour].Heart; // 默认为 0 如果未更新  
-        }  
-        return 0; // 或者返回一个异常值
+  // 读取文件内容到字符串
+  std::stringstream buffer;
+  buffer << inFile.rdbuf();
+  std::string jsonDataString = buffer.str();
+  const char *jsonData = jsonDataString.c_str();
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData);
+
+  // 关闭文件
+  inFile.close();
+
+  if (jsonDataString.empty()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty");
+    return nullptr;
+  }
+
+  cJSON *heart_root = cJSON_Parse(jsonData);
+  if (heart_root == NULL) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse JSON data");
+    return nullptr;
+  }
+
+  HeartRateData *data = new HeartRateData();
+
+  cJSON *value_item = cJSON_GetObjectItem(heart_root, "value");
+  cJSON *timestamp_item = cJSON_GetObjectItem(heart_root, "timestamp");
+
+  // 检查是否存在必要字段,并验证数据类型
+  if (value_item && cJSON_IsNumber(value_item) && timestamp_item &&
+      cJSON_IsNumber(timestamp_item)) {
+    data->Heart = value_item->valueint;
+    data->timestamp = timestamp_item->valuedouble;
+  } else {
+    // 读取的数据异常
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing or invalid data fields");
+    cJSON_Delete(heart_root);
+    delete data;
+    return nullptr;
+  }
+
+  cJSON_Delete(heart_root);
+  return data;
+}
+
+// 保存血氧数据
+bool HealthService::UpdateHealthData(const BloodOxygenData &data) {
+  // 配置血氧存储状态
+  uapi_dev_runtime_set_bloodoxygen_storage_status(1);
+
+  // 判断文件夹是否存在
+  if (!CreateHealthFolder()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file");
+    uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  // 判断文件是否存在,不存在即创建并打开以输出模式
+  std::ofstream outFile(BLOOD_JSON_PATH, std::ios::trunc);
+  if (!outFile.is_open()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Failed to create or open JSON file for writing");
+    uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  // 创建一个 JSON 对象
+  cJSON *oxygen_root = cJSON_CreateObject();
+  if (oxygen_root == NULL) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create JSON object");
+    outFile.close();
+    uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  cJSON_AddItemToObject(oxygen_root, "value", cJSON_CreateNumber(data.SPO2));
+  cJSON_AddItemToObject(oxygen_root, "timestamp",
+                        cJSON_CreateNumber(data.timestamp));
+
+  char *jsonData = cJSON_Print(oxygen_root);
+  if (jsonData == NULL) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data");
+    cJSON_Delete(oxygen_root); // 释放内存
+    outFile.close();
+    uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  // 写入 JSON 数据到文件
+  outFile << jsonData;
+
+  // 释放资源
+  cJSON_Delete(oxygen_root);
+  free(jsonData);
+  outFile.close();
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHealthData SPO2 JSON is ok");
+
+  /* 存储bin文件[协议使用] */
+  std::string binFilePath = GetBinFilePath(HEALTH_TYPE_OXYGEN);
+  FILE *fp = fopen(binFilePath.c_str(), "ab+");
+  if (fp == NULL) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Failed to open binary file for writing");
+    uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  // 写入数据
+  if (fwrite(&data.timestamp, sizeof(data.timestamp), 1, fp) != 1 ||
+      fwrite(&data.SPO2, sizeof(data.SPO2), 1, fp) != 1) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Failed to write data to binary file");
+    fclose(fp);
+    uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  fclose(fp);
+
+  uapi_dev_runtime_set_bloodoxygen_storage_status(0); // 恢复状态
+  return true;
+}
+
+//存储心率
+bool HealthService::UpdateHealthData(const HeartRateData &data) {
+  // 配置心率存储状态
+  uapi_dev_runtime_set_heartrate_storage_status(1);
+
+  // 判断文件夹是否存在
+  if (!CreateHealthFolder()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file");
+    uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  // 判断文件是否存在,不存在即创建并打开以输出模式
+  std::ofstream outFile(HEART_JSON_PATH, std::ios::trunc);
+  if (!outFile.is_open()) {
+    // 文件创建失败
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Failed to create or open JSON file for writing");
+    uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  // 创建一个 JSON 对象
+  cJSON *heart_root = cJSON_CreateObject();
+  if (heart_root == NULL) {
+    outFile.close();
+    uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  cJSON_AddItemToObject(heart_root, "value", cJSON_CreateNumber(data.Heart));
+  cJSON_AddItemToObject(heart_root, "timestamp",
+                        cJSON_CreateNumber(data.timestamp));
+
+  char *jsonData = cJSON_Print(heart_root);
+  if (jsonData == NULL) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data");
+    cJSON_Delete(heart_root); // 使用 cJSON_Delete 释放内存
+    outFile.close();
+    uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  // 写入 JSON 数据到文件
+  outFile << jsonData;
+
+  // 释放资源
+  cJSON_Delete(heart_root);
+  free(jsonData);
+  outFile.close();
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHealthData Heart JSON is ok");
+
+  // 写入文件到当天历史数据
+  UpdateHourlyHeartRate(data.timestamp, data.Heart);
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHourlyHeartRate is ok");
+
+  if (!SaveDailyHeartRate()) // 进行心率历史数据文件存储
+  {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDailyHeartRate failed");
+    uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  /* 存储 bin 文件 [协议使用] */
+  std::string binFilePath = GetBinFilePath(HEALTH_TYPE_HEART);
+  FILE *fp = fopen(binFilePath.c_str(), "ab+");
+  if (fp == NULL) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Failed to open binary file for writing");
+    uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  // 写入数据
+  if (fwrite(&data.timestamp, sizeof(data.timestamp), 1, fp) != 1 ||
+      fwrite(&data.Heart, sizeof(data.Heart), 1, fp) != 1) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Failed to write data to binary file");
+    fclose(fp);
+    uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态
+    return false;
+  }
+
+  fclose(fp);
+
+  uapi_dev_runtime_set_heartrate_storage_status(0); // 恢复状态
+  return true;
+}
+// 清空健康数据
+bool HealthService::CleanHealthData() {
+  //清空心率数组
+  ClearHourlyHeartRates();
+  //进行数据存储
+  SaveDailyHeartRate();
+
+  HeartModel::GetInstance()->ClearDisplayData();
+  // BloodOxygenModel::GetInstance()->ClearDisplayData();
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CleanHealthData  is ok");
+  return true;
+}
+
+HealthState HealthService::GetHealthCurrent() { return healthState_; }
+void HealthService::SetHealthCurrent(HealthState healthState) {
+  healthState_ = healthState;
+}
+/* ------------------------------- 心率当天历史数据处理
+ * ------------------------------ */
+static constexpr const char *HEART_DATA_PATH =
+    "/user/userdata/health/heart_history.bin";
+
+//清空数组
+void HealthService::ClearHourlyHeartRates() {
+  for (int i = 0; i < MAX_HOURS; ++i) {
+    dailyHeartRates[i].Heart = 0;
+    dailyHeartRates[i].timestamp = 0;
+  }
+}
+
+// 加载心率列表
+bool HealthService::LoadDailyHeartRate() {
+  ClearHourlyHeartRates(); // 清空数组
+
+  // 使用 RAII 管理文件流
+  std::ifstream file(HEART_DATA_PATH, std::ios::binary);
+  if (!file.is_open()) {
+    std::cerr << "Error: Unable to open heart rate data file for reading"
+              << std::endl;
+    return false;
+  }
+
+  // 读取时间戳
+  file.read(reinterpret_cast<char *>(&lastLoadTime), sizeof(lastLoadTime));
+  if (lastLoadTime == 0) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDailyHeartRate is not today");
+    return false; // 无有效数据
+  }
+
+  // 判断时间戳是否为今天
+  tm *lastTm = localtime(&lastLoadTime);
+  time_t now = time(nullptr);
+  tm *currentTm = localtime(&now);
+  if (currentTm->tm_year == lastTm->tm_year &&
+      currentTm->tm_yday == lastTm->tm_yday) {
+    // 今天:进行数据读取
+    for (int i = 0; i < MAX_HOURS; ++i) {
+      HeartRateData rate; // 假设您有一个 HeartRateData 结构体
+      if (!file.read(reinterpret_cast<char *>(&rate), sizeof(rate))) {
+        std::cerr << "Error: Failed to read heart rate data." << std::endl;
+        return false; // 读取失败
+      }
+      dailyHeartRates[i] = rate; // 保存心率和时间戳
+      std::cout << "Hour " << i << ": Heart Rate " << rate.Heart << std::endl;
     }
-    //获取指定小时的时间戳
-    time_t HealthService::GetHourlyTimestamp(uint16_t hour) {  
-        if (hour < MAX_HOURS) {  
-            return dailyHeartRates[hour].timestamp; // 默认为 0 如果未更新  
-        }  
-        return 0; // 或者返回一个异常值
+    return true; // 成功读取
+  }
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDailyHeartRate is not today");
+  return false; // 不是今日
+}
+
+// 保存今日心率列表
+bool HealthService::SaveDailyHeartRate() {
+  std::ofstream outFile(HEART_DATA_PATH, std::ios::binary | std::ios::trunc);
+  if (!outFile.is_open()) {
+    std::cerr << "Error: Unable to open heart rate data file for writing"
+              << std::endl;
+    return false; // 文件打开失败
+  }
+
+  // 存储时间戳
+  time_t currentTime = time(nullptr);
+  outFile.write(reinterpret_cast<const char *>(&currentTime),
+                sizeof(currentTime));
+
+  // 存储心率数据
+  for (const auto &rate : dailyHeartRates) {
+    if (!outFile.write(reinterpret_cast<const char *>(&rate), sizeof(rate))) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "Failed to write heart rate data to file");
+      return false; // 写入失败
     }
+  }
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDailyHeartRate is ok");
+  return true; // 成功保存
+}
+
+// 更新心率列表项
+void HealthService::UpdateHourlyHeartRate(time_t timestamp,
+                                          uint16_t heartRate) {
+  struct tm *timeInfo = localtime(&timestamp);
+  uint16_t hour = static_cast<uint16_t>(timeInfo->tm_hour);
+
+  if (hour < MAX_HOURS && heartRate > 0) {
+    dailyHeartRates[hour] = {heartRate, timestamp}; // 更新心率和时间戳
+    currenthour = hour;                             // 记录当前小时
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHourlyHeartRate is ok");
+  } else {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Invalid hour or heart rate value %d", hour);
+  }
+}
+
+// 获取指定小时的心率
+uint16_t HealthService::GetHourlyHeartRate(uint16_t hour) {
+  if (hour < MAX_HOURS) {
+    return dailyHeartRates[hour].Heart; // 默认为 0 如果未更新
+  }
+  return 0; // 或者返回一个异常值
+}
+//获取指定小时的时间戳
+time_t HealthService::GetHourlyTimestamp(uint16_t hour) {
+  if (hour < MAX_HOURS) {
+    return dailyHeartRates[hour].timestamp; // 默认为 0 如果未更新
+  }
+  return 0; // 或者返回一个异常值
+}
 
-    // 获取当前小时
-    uint16_t HealthService::GetCurrentHour() { return currenthour; }
-    /*
-    心率最大最小值存储
-    关机存储
+// 获取当前小时
+uint16_t HealthService::GetCurrentHour() { return currenthour; }
+/*
+心率最大最小值存储
+关机存储
 */
 #define HEART_MAX_MIN_PATH "/user/userdata/health/heart_max_min.bin"
 // 保存最大最小值
@@ -635,4 +669,14 @@ void HealthService::LoadHeartMaxMin(uint16_t &max, uint16_t &min) {
   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadHeartMaxMin is ok max %d, min %d",
                 max, min);
 }
+
+//进行消息发送
+void HealthService::send_heart_save() {
+    do_custom_fileoperate_service_check_msg(
+        CUSTOM_FILEOPERATE_MSG_TYPE_HEARTRATE_SAVE, nullptr, 0);
+}
+void HealthService::send_blood_save() {
+     do_custom_fileoperate_service_check_msg(
+        CUSTOM_FILEOPERATE_MSG_TYPE_BLOODXYGEN_SAVE, nullptr, 0);
+}
 } // namespace OHOS
index e062f5c..d82e14a 100644 (file)
@@ -96,6 +96,9 @@ namespace OHOS
         bool SaveHeartMaxMin(uint16_t max, uint16_t min);
         void LoadHeartMaxMin(uint16_t &max, uint16_t &min);
 
+        void send_heart_save();
+        void send_blood_save();
+
     private:
         static const int MAX_HOURS = 24;
         HeartRateData dailyHeartRates[MAX_HOURS]; // 存储心率值,检测时间戳?使用结构体?
index 013ef4b..4aa5b9e 100644 (file)
@@ -503,14 +503,15 @@ void HeartModel::Heart_Stop() {
 }\r
 // 保存检测数据\r
 void HeartModel::Heart_Save() {\r
-  HeartRateData data;\r
-  data.Heart = currentheart;\r
-  data.timestamp = HeartResultPresenter::GetInstance()->GetCurrentTime();\r
-  SetCheckTime(data.timestamp);\r
-  HealthService::GetInstance()->UpdateHealthData(data);\r
-\r
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "保存的心率数据:%d%ld", currentheart,\r
-                data.timestamp);\r
+\r
+  uint32_t timestamp = HeartResultPresenter::GetInstance()->GetCurrentTime();\r
+  SetCheckTime(timestamp);\r
+\r
+  //HealthService::GetInstance()->UpdateHealthData(data);\r
+\r
+  HealthService::GetInstance()->send_heart_save();\r
+\r
+  //WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "保存的心率数据:%d%ld", currentheart,data.timestamp);\r
 }\r
 \r
 void HeartModel::Heart_Result() {\r
index d38e535..3e539e4 100644 (file)
@@ -10,6 +10,10 @@ extern "C" {
 void repair_file_start(void);
 //进行运动存储
 void store_sport_data(void);
+//进行心率存储
+void save_heart_rate_data(void);
+//进行血氧存储
+void save_blood_oxygen_data(void);
 
 #ifdef __cplusplus
 }
index 7842fe8..8ba44f0 100644 (file)
@@ -118,8 +118,10 @@ static void custom_fileoperate_service_check_task(void const *arg)
             store_sport_data();
             break;
         case CUSTOM_FILEOPERATE_MSG_TYPE_HEARTRATE_SAVE:
+            save_heart_rate_data();
             break;
         case CUSTOM_FILEOPERATE_MSG_TYPE_BLOODXYGEN_SAVE:
+            save_blood_oxygen_data();
             break;
         case CUSTOM_FILEOPERATE_MSG_TYPE_MESSAGEDATA_SAVE:
             break;