#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);
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;
}
}
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 *>(¤tTime), 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(×tamp);
- 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 *>(¤tTime),
+ 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(×tamp);
+ 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"
// 保存最大最小值
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