import dayjs from 'dayjs'; import { AppState, AppStateStatus, NativeModules } from 'react-native'; import { SimpleEventEmitter } from './SimpleEventEmitter'; type HealthDataOptions = { startDate: string; endDate: string; }; // React Native bridge to native HealthKitManager const { HealthKitManager } = NativeModules; // HealthKit权限状态枚举 export enum HealthPermissionStatus { Unknown = 'unknown', Authorized = 'authorized', Denied = 'denied', NotDetermined = 'notDetermined' } // 权限状态管理类 class HealthPermissionManager extends SimpleEventEmitter { private permissionStatus: HealthPermissionStatus = HealthPermissionStatus.Unknown; private isChecking: boolean = false; private lastCheckTime: number = 0; private checkInterval: number = 5000; // 5秒检查间隔,避免频繁检查 private appStateSubscription: any = null; constructor() { super(); this.setupAppStateListener(); } // 设置应用状态监听 private setupAppStateListener() { this.appStateSubscription = AppState.addEventListener('change', this.handleAppStateChange.bind(this)); } // 处理应用状态变化 private handleAppStateChange(nextAppState: AppStateStatus) { if (nextAppState === 'active') { // 应用回到前台时检查权限状态 console.log('应用回到前台,检查HealthKit权限状态...'); this.checkPermissionStatus(true); } } // 获取当前权限状态 public getPermissionStatus(): HealthPermissionStatus { return this.permissionStatus; } // 设置权限状态 private setPermissionStatus(status: HealthPermissionStatus, shouldEmit: boolean = true) { const oldStatus = this.permissionStatus; this.permissionStatus = status; if (shouldEmit && oldStatus !== status) { console.log(`HealthKit权限状态变化: ${oldStatus} -> ${status}`); this.emit('permissionStatusChanged', status, oldStatus); } } // 检查权限状态(通过尝试读取数据来间接判断) public async checkPermissionStatus(forceCheck: boolean = false): Promise { const now = Date.now(); // 避免频繁检查 if (!forceCheck && this.isChecking) { return this.permissionStatus; } if (!forceCheck && (now - this.lastCheckTime) < this.checkInterval) { return this.permissionStatus; } this.isChecking = true; this.lastCheckTime = now; try { // 尝试获取简单的步数数据来检测权限 const today = new Date(); const options = { startDate: dayjs(today).startOf('day').toDate().toISOString(), endDate: dayjs(today).endOf('day').toDate().toISOString() }; const result = await HealthKitManager.getStepCount(options); if (result && result.totalValue !== undefined) { // 能够获取数据,说明有权限 this.setPermissionStatus(HealthPermissionStatus.Authorized); } else if (result && result.error) { // 有错误返回,可能是权限被拒绝 this.setPermissionStatus(HealthPermissionStatus.Denied); } else { // 其他情况 this.setPermissionStatus(HealthPermissionStatus.Unknown); } } catch (error) { console.log('HealthKit权限检查失败,可能是权限被拒绝:', error); this.setPermissionStatus(HealthPermissionStatus.Denied); } finally { this.isChecking = false; } return this.permissionStatus; } // 请求权限 public async requestPermission(): Promise { try { console.log('开始请求HealthKit权限...'); const result = await HealthKitManager.requestAuthorization(); if (result && result.success) { console.log('HealthKit权限请求成功'); this.setPermissionStatus(HealthPermissionStatus.Authorized); // 权限获取成功后触发数据刷新事件 this.emit('permissionGranted'); return true; } else { console.error('HealthKit权限请求失败'); this.setPermissionStatus(HealthPermissionStatus.Denied); return false; } } catch (error) { console.error('HealthKit权限请求出现异常:', error); this.setPermissionStatus(HealthPermissionStatus.Denied); return false; } } // 清理资源 public destroy() { if (this.appStateSubscription) { this.appStateSubscription.remove(); } this.removeAllListeners(); } } // 全局权限管理实例 export const healthPermissionManager = new HealthPermissionManager(); // Interface for activity summary data from HealthKit export interface HealthActivitySummary { activeEnergyBurned: number; activeEnergyBurnedGoal: number; appleExerciseTime: number; appleExerciseTimeGoal: number; appleStandHours: number; appleStandHoursGoal: number; dateComponents: { day: number; month: number; year: number; }; } // const PERMISSIONS: HealthKitPermissions = { // permissions: { // read: [ // AppleHealthKit.Constants.Permissions.StepCount, // AppleHealthKit.Constants.Permissions.ActiveEnergyBurned, // AppleHealthKit.Constants.Permissions.BasalEnergyBurned, // AppleHealthKit.Constants.Permissions.SleepAnalysis, // AppleHealthKit.Constants.Permissions.HeartRateVariability, // AppleHealthKit.Constants.Permissions.ActivitySummary, // AppleHealthKit.Constants.Permissions.OxygenSaturation, // AppleHealthKit.Constants.Permissions.HeartRate, // AppleHealthKit.Constants.Permissions.Water, // // 添加 Apple Exercise Time 和 Apple Stand Time 权限 // AppleHealthKit.Constants.Permissions.AppleExerciseTime, // AppleHealthKit.Constants.Permissions.AppleStandTime, // ], // write: [ // // 支持体重写入 // AppleHealthKit.Constants.Permissions.Weight, // // 支持饮水量写入 // AppleHealthKit.Constants.Permissions.Water, // ], // }, // }; export type HourlyStepData = { hour: number; // 0-23 steps: number; }; export type HourlyActivityData = { hour: number; // 0-23 calories: number; // 活动热量 }; export type HourlyExerciseData = { hour: number; // 0-23 minutes: number; // 锻炼分钟数 }; export type HourlyStandData = { hour: number; // 0-23 hasStood: number; // 1表示该小时有站立,0表示没有 }; export type TodayHealthData = { activeEnergyBurned: number; // kilocalories basalEnergyBurned: number; // kilocalories - 基础代谢率 hrv: number | null; // 心率变异性 (ms) // 健身圆环数据 activeCalories: number; activeCaloriesGoal: number; exerciseMinutes: number; exerciseMinutesGoal: number; standHours: number; standHoursGoal: number; heartRate: number | null; }; // 更新:使用新的权限管理系统 export async function ensureHealthPermissions(): Promise { return await healthPermissionManager.requestPermission(); } // 获取当前权限状态 export function getHealthPermissionStatus(): HealthPermissionStatus { return healthPermissionManager.getPermissionStatus(); } // 检查权限状态 export async function checkHealthPermissionStatus(forceCheck: boolean = false): Promise { return await healthPermissionManager.checkPermissionStatus(forceCheck); } // 日期工具函数 function createDateRange(date: Date): HealthDataOptions { return { startDate: dayjs(date).startOf('day').toDate().toISOString(), endDate: dayjs(date).endOf('day').toDate().toISOString() }; } // Note: createSleepDateRange and calculateSleepDuration functions removed as unused // 通用错误处理 function logError(operation: string, error: any): void { console.error(`获取${operation}失败:`, error); } function logWarning(operation: string, message: string): void { console.warn(`${operation}数据${message}`); } function logSuccess(operation: string, data: any): void { console.log(`${operation}数据:`, data); } // 数值验证和转换 function validateOxygenSaturation(value: any): number | null { if (value === undefined || value === null) return null; let numValue = Number(value); // 如果值小于1,可能是小数形式(0.0-1.0),需要转换为百分比 if (numValue > 0 && numValue < 1) { numValue = numValue * 100; } // 血氧饱和度通常在0-100之间,验证数据有效性 if (numValue >= 0 && numValue <= 100) { return Number(numValue.toFixed(1)); } console.warn('血氧饱和度数据异常:', numValue); return null; } function validateHeartRate(value: any): number | null { if (value === undefined || value === null) return null; const numValue = Number(value); // 心率通常在30-200之间,验证数据有效性 if (numValue >= 30 && numValue <= 200) { return Math.round(numValue); } console.warn('心率数据异常:', numValue); return null; } // 健康数据获取函数 export async function fetchStepCount(date: Date): Promise { try { const options = createDateRange(date); const result = await HealthKitManager.getStepCount(options); if (result && result.totalValue !== undefined) { logSuccess('步数', result); return Math.round(result.totalValue); } else { logWarning('步数', '为空或格式错误'); return 0; } } catch (error) { logError('步数', error); return 0; } } // 使用样本数据获取每小时步数 export async function fetchHourlyStepSamples(date: Date): Promise { try { const options = createDateRange(date); const result = await HealthKitManager.getDailyStepCountSamples(options); if (result && result.data && Array.isArray(result.data)) { logSuccess('每小时步数样本', result); // 初始化24小时数据 const hourlyData: HourlyStepData[] = Array.from({ length: 24 }, (_, i) => ({ hour: i, steps: 0 })); // 将每小时的步数样本数据映射到对应的小时 result.data.forEach((sample: any) => { if (sample && sample.hour !== undefined && sample.value !== undefined) { const hour = sample.hour; if (hour >= 0 && hour < 24) { hourlyData[hour].steps = Math.round(sample.value); } } }); return hourlyData; } else { logWarning('每小时步数', '为空或格式错误'); return Array.from({ length: 24 }, (_, i) => ({ hour: i, steps: 0 })); } } catch (error) { logError('每小时步数样本', error); return Array.from({ length: 24 }, (_, i) => ({ hour: i, steps: 0 })); } } // 获取每小时活动热量数据 async function fetchHourlyActiveCalories(date: Date): Promise { try { const options = createDateRange(date); const result = await HealthKitManager.getHourlyActiveEnergyBurned(options); if (result && result.data && Array.isArray(result.data)) { logSuccess('每小时活动热量', result); // 初始化24小时数据 const hourlyData: HourlyActivityData[] = Array.from({ length: 24 }, (_, i) => ({ hour: i, calories: 0 })); // 将API返回的数据映射到对应的小时 result.data.forEach((sample: any) => { if (sample && sample.hour !== undefined && sample.value !== undefined) { const hour = sample.hour; if (hour >= 0 && hour < 24) { hourlyData[hour].calories = Math.round(sample.value); } } }); return hourlyData; } else { logWarning('每小时活动热量', '为空或格式错误'); return Array.from({ length: 24 }, (_, i) => ({ hour: i, calories: 0 })); } } catch (error) { logError('每小时活动热量', error); return Array.from({ length: 24 }, (_, i) => ({ hour: i, calories: 0 })); } } // 获取每小时锻炼分钟数据 async function fetchHourlyExerciseMinutes(date: Date): Promise { try { const options = createDateRange(date); const result = await HealthKitManager.getHourlyExerciseTime(options); if (result && result.data && Array.isArray(result.data)) { logSuccess('每小时锻炼分钟', result); // 初始化24小时数据 const hourlyData: HourlyExerciseData[] = Array.from({ length: 24 }, (_, i) => ({ hour: i, minutes: 0 })); // 将API返回的数据映射到对应的小时 result.data.forEach((sample: any) => { if (sample && sample.hour !== undefined && sample.value !== undefined) { const hour = sample.hour; if (hour >= 0 && hour < 24) { hourlyData[hour].minutes = Math.round(sample.value); } } }); return hourlyData; } else { logWarning('每小时锻炼分钟', '为空或格式错误'); return Array.from({ length: 24 }, (_, i) => ({ hour: i, minutes: 0 })); } } catch (error) { logError('每小时锻炼分钟', error); return Array.from({ length: 24 }, (_, i) => ({ hour: i, minutes: 0 })); } } // 获取每小时站立小时数据 async function fetchHourlyStandHours(date: Date): Promise { try { const options = createDateRange(date); const result = await HealthKitManager.getHourlyStandHours(options); if (result && result.data && Array.isArray(result.data)) { logSuccess('每小时站立数据', result); // 初始化24小时数据 const hourlyData: number[] = Array.from({ length: 24 }, () => 0); // 将API返回的数据映射到对应的小时 result.data.forEach((sample: any) => { if (sample && sample.hour !== undefined && sample.value !== undefined) { const hour = sample.hour; if (hour >= 0 && hour < 24) { hourlyData[hour] = sample.value; } } }); return hourlyData; } else { logWarning('每小时站立数据', '为空或格式错误'); return Array.from({ length: 24 }, () => 0); } } catch (error) { logError('每小时站立数据', error); return Array.from({ length: 24 }, () => 0); } } async function fetchActiveEnergyBurned(options: HealthDataOptions): Promise { try { const result = await HealthKitManager.getActiveEnergyBurned(options); if (result && result.totalValue !== undefined) { logSuccess('消耗卡路里', result); return result.totalValue; } else { logWarning('卡路里', '为空或格式错误'); return 0; } } catch (error) { logError('消耗卡路里', error); return 0; } } async function fetchBasalEnergyBurned(options: HealthDataOptions): Promise { try { const result = await HealthKitManager.getBasalEnergyBurned(options); if (result && result.totalValue !== undefined) { logSuccess('基础代谢', result); return result.totalValue; } else { logWarning('基础代谢', '为空或格式错误'); return 0; } } catch (error) { logError('基础代谢', error); return 0; } } async function fetchHeartRateVariability(options: HealthDataOptions): Promise { try { console.log('=== 开始获取HRV数据 ==='); console.log('查询选项:', options); const result = await HealthKitManager.getHeartRateVariabilitySamples(options); console.log('HRV API调用结果:', result); if (result && result.data && Array.isArray(result.data) && result.data.length > 0) { const hrvValue = result.data[0].value; logSuccess('HRV数据', result); return Math.round(hrvValue); // Value already in ms from native } else { logWarning('HRV', '为空或格式错误'); console.warn('HRV数据为空,原始响应:', result); return null; } } catch (error) { logError('HRV数据', error); console.error('HRV获取错误详情:', error); return null; } } async function fetchActivitySummary(options: HealthDataOptions): Promise { try { const result = await HealthKitManager.getActivitySummary(options); if (result && Array.isArray(result) && result.length > 0) { logSuccess('ActivitySummary', result[0]); return result[0]; } else { logWarning('ActivitySummary', '为空'); return null; } } catch (error) { logError('ActivitySummary', error); return null; } } export async function fetchOxygenSaturation(options: HealthDataOptions): Promise { try { const result = await HealthKitManager.getOxygenSaturationSamples(options); if (result && result.data && Array.isArray(result.data) && result.data.length > 0) { logSuccess('血氧饱和度', result); const latestOxygen = result.data[result.data.length - 1]; return validateOxygenSaturation(latestOxygen?.value); } else { logWarning('血氧饱和度', '为空或格式错误'); return null; } } catch (error) { logError('血氧饱和度', error); return null; } } async function fetchHeartRate(options: HealthDataOptions): Promise { try { const result = await HealthKitManager.getHeartRateSamples(options); if (result && result.data && Array.isArray(result.data) && result.data.length > 0) { logSuccess('心率', result); const latestHeartRate = result.data[result.data.length - 1]; return validateHeartRate(latestHeartRate?.value); } else { logWarning('心率', '为空或格式错误'); return null; } } catch (error) { logError('心率', error); return null; } } // 获取指定时间范围内的最大心率 export async function fetchMaximumHeartRate(_options: HealthDataOptions): Promise { try { // 暂未实现,返回null console.log('最大心率获取暂未实现'); return null; // const result = await HealthKitManager.getHeartRateSamples(options); // if (result && result.data && Array.isArray(result.data) && result.data.length > 0) { // // 从所有心率样本中找出最大值 // let maxHeartRate = 0; // let validSamplesCount = 0; // result.data.forEach((sample: any) => { // if (sample && sample.value !== undefined) { // const heartRate = validateHeartRate(sample.value); // if (heartRate !== null) { // maxHeartRate = Math.max(maxHeartRate, heartRate); // validSamplesCount++; // } // } // }); // if (validSamplesCount > 0 && maxHeartRate > 0) { // logSuccess('最大心率', { maxHeartRate, validSamplesCount }); // return maxHeartRate; // } else { // logWarning('最大心率', '没有找到有效的样本数据'); // return null; // } // } else { // logWarning('最大心率', '为空或格式错误'); // return null; // } } catch (error) { logError('最大心率', error); return null; } } // 默认健康数据 function getDefaultHealthData(): TodayHealthData { return { activeEnergyBurned: 0, basalEnergyBurned: 0, hrv: null, activeCalories: 0, activeCaloriesGoal: 350, exerciseMinutes: 0, exerciseMinutesGoal: 30, standHours: 0, standHoursGoal: 12, heartRate: null, }; } export async function fetchHealthDataForDate(date: Date): Promise { try { console.log('开始获取指定日期健康数据...', date); const options = createDateRange(date); console.log('查询选项:', options); // 并行获取所有健康数据 const [ activeEnergyBurned, basalEnergyBurned, hrv, activitySummary, heartRate ] = await Promise.all([ fetchActiveEnergyBurned(options), fetchBasalEnergyBurned(options), fetchHeartRateVariability(options), fetchActivitySummary(options), fetchHeartRate(options) ]); return { activeEnergyBurned, basalEnergyBurned, hrv, activeCalories: Math.round(activitySummary?.activeEnergyBurned || 0), activeCaloriesGoal: Math.round(activitySummary?.activeEnergyBurnedGoal || 350), exerciseMinutes: Math.round(activitySummary?.appleExerciseTime || 0), exerciseMinutesGoal: Math.round(activitySummary?.appleExerciseTimeGoal || 30), standHours: Math.round(activitySummary?.appleStandHours || 0), standHoursGoal: Math.round(activitySummary?.appleStandHoursGoal || 12), heartRate }; } catch (error) { console.error('获取指定日期健康数据失败:', error); return getDefaultHealthData(); } } export async function fetchTodayHealthData(): Promise { return fetchHealthDataForDate(dayjs().toDate()); } export async function fetchHRVForDate(date: Date): Promise { console.log('开始获取指定日期HRV数据...', date); const options = createDateRange(date); return fetchHeartRateVariability(options); } export async function fetchTodayHRV(): Promise { return fetchHRVForDate(dayjs().toDate()); } // 获取最近几小时内的实时HRV数据 export async function fetchRecentHRV(hoursBack: number = 2): Promise { console.log(`开始获取最近${hoursBack}小时内的HRV数据...`); const now = new Date(); const options = { startDate: dayjs(now).subtract(hoursBack, 'hour').toDate().toISOString(), endDate: now.toISOString() }; return fetchHeartRateVariability(options); } // 测试HRV数据获取功能 export async function testHRVDataFetch(date: Date = dayjs().toDate()): Promise { console.log('=== 开始测试HRV数据获取 ==='); try { // 首先确保权限 const hasPermission = await ensureHealthPermissions(); if (!hasPermission) { console.error('没有健康数据权限,无法测试HRV'); return; } console.log('权限检查通过,开始获取HRV数据...'); // 测试不同时间范围的HRV数据 const options = createDateRange(date); // 获取今日HRV const todayHRV = await fetchHeartRateVariability(options); console.log('今日HRV结果:', todayHRV); // 获取最近2小时HRV const recentHRV = await fetchRecentHRV(2); console.log('最近2小时HRV结果:', recentHRV); // 获取指定日期HRV const dateHRV = await fetchHRVForDate(date); console.log('指定日期HRV结果:', dateHRV); console.log('=== HRV数据测试完成 ==='); } catch (error) { console.error('HRV测试过程中出现错误:', error); } } // 更新healthkit中的体重 (暂未实现) export async function updateWeight(_weight: number) { try { // Note: Weight saving would need to be implemented in native module console.log('体重保存到HealthKit暂未实现'); return true; // Return true for now to not break existing functionality } catch (error) { console.error('更新体重失败:', error); return false; } } export async function testOxygenSaturationData(_date: Date = dayjs().toDate()): Promise { console.log('=== 开始测试血氧饱和度数据获取 ==='); // const options = createDateRange(date); try { // const result = await HealthKitManager.getOxygenSaturationSamples(options); // console.log('原始血氧饱和度数据:', result); // if (!result || !result.data || !Array.isArray(result.data) || result.data.length === 0) { // console.warn('血氧饱和度数据为空'); // return; // } // // 分析所有数据样本 // result.data.forEach((sample: any, index: number) => { // console.log(`样本 ${index + 1}:`, { // value: sample.value, // valueType: typeof sample.value, // startDate: sample.startDate, // endDate: sample.endDate // }); // }); // // 获取最新的血氧饱和度值并验证 // const latestOxygen = result.data[result.data.length - 1]; // if (latestOxygen?.value !== undefined && latestOxygen?.value !== null) { // const processedValue = validateOxygenSaturation(latestOxygen.value); // console.log('处理前的值:', latestOxygen.value); // console.log('最终处理后的值:', processedValue); // console.log('数据有效性检查:', processedValue !== null ? '有效' : '无效'); // } // console.log('=== 血氧饱和度数据测试完成 ==='); } catch (error) { console.error('获取血氧饱和度失败:', error); } } // 添加饮水记录到 HealthKit (暂未实现) export async function saveWaterIntakeToHealthKit(_amount: number, _recordedAt?: string): Promise { try { // Note: Water intake saving would need to be implemented in native module console.log('饮水记录保存到HealthKit暂未实现'); return true; // Return true for now to not break existing functionality } catch (error) { console.error('添加饮水记录到 HealthKit 失败:', error); return false; } } // 获取 HealthKit 中的饮水记录 (暂未实现) export async function getWaterIntakeFromHealthKit(_options: HealthDataOptions): Promise { try { // Note: Water intake fetching would need to be implemented in native module console.log('从HealthKit获取饮水记录暂未实现'); return []; } catch (error) { console.error('获取 HealthKit 饮水记录失败:', error); return []; } } // 删除 HealthKit 中的饮水记录 // 注意: react-native-health 库可能不支持直接删除特定记录,这个功能可能需要手动实现或使用其他方法 export async function deleteWaterIntakeFromHealthKit(recordId: string, recordedAt: string): Promise { // HealthKit 通常不支持直接删除单条记录 // 这是一个占位函数,实际实现可能需要更复杂的逻辑 console.log('注意: HealthKit 通常不支持直接删除单条饮水记录'); console.log('记录信息:', { recordId, recordedAt }); // 返回 true 表示"成功"(但实际上可能没有真正删除) return Promise.resolve(true); } // 获取当前小时的站立状态 export async function getCurrentHourStandStatus(): Promise<{ hasStood: boolean; standHours: number; standHoursGoal: number }> { try { const currentHour = new Date().getHours(); console.log(`检查当前小时 ${currentHour} 的站立状态...`); // 获取今日健康数据 const todayHealthData = await fetchTodayHealthData(); return { hasStood: todayHealthData.standHours > currentHour - 1, // 如果站立小时数大于当前小时-1,说明当前小时已站立 standHours: todayHealthData.standHours, standHoursGoal: todayHealthData.standHoursGoal }; } catch (error) { console.error('获取当前小时站立状态失败:', error); return { hasStood: true, // 默认认为已站立,避免过度提醒 standHours: 0, standHoursGoal: 12 }; } } // === 专门为健身圆环详情页提供的独立函数 === // 精简的活动圆环数据类型,只包含必要字段 export type ActivityRingsData = { // 活动圆环数据(来自 getActivitySummary) activeEnergyBurned: number; // activeEnergyBurned activeEnergyBurnedGoal: number; // activeEnergyBurnedGoal appleExerciseTime: number; // appleExerciseTime (分钟) appleExerciseTimeGoal: number; // appleExerciseTimeGoal appleStandHours: number; // appleStandHours appleStandHoursGoal: number; // appleStandHoursGoal }; // 导出每小时活动热量数据获取函数 export async function fetchHourlyActiveCaloriesForDate(date: Date): Promise { return fetchHourlyActiveCalories(date); } // 导出每小时锻炼分钟数据获取函数 export async function fetchHourlyExerciseMinutesForDate(date: Date): Promise { return fetchHourlyExerciseMinutes(date); } // 导出每小时站立数据获取函数 export async function fetchHourlyStandHoursForDate(date: Date): Promise { const hourlyStandData = await fetchHourlyStandHours(date); return hourlyStandData.map((hasStood, hour) => ({ hour, hasStood })); } // 专门为活动圆环详情页获取精简的数据 export async function fetchActivityRingsForDate(date: Date): Promise { try { console.log('获取活动圆环数据...', date); const options = createDateRange(date); const activitySummary = await fetchActivitySummary(options); if (!activitySummary) { console.warn('ActivitySummary 数据为空'); return null; } // 直接使用 getActivitySummary 返回的字段名,与文档保持一致 return { activeEnergyBurned: Math.round(activitySummary.activeEnergyBurned || 0), activeEnergyBurnedGoal: Math.round(activitySummary.activeEnergyBurnedGoal || 350), appleExerciseTime: Math.round(activitySummary.appleExerciseTime || 0), appleExerciseTimeGoal: Math.round(activitySummary.appleExerciseTimeGoal || 30), appleStandHours: Math.round(activitySummary.appleStandHours || 0), appleStandHoursGoal: Math.round(activitySummary.appleStandHoursGoal || 12), }; } catch (error) { console.error('获取活动圆环数据失败:', error); return null; } } // === 权限管理工具函数 === // 初始化健康权限管理(应在应用启动时调用) export function initializeHealthPermissions() { console.log('初始化HealthKit权限管理系统...'); // 延迟检查权限状态,避免应用启动时的性能影响 setTimeout(() => { healthPermissionManager.checkPermissionStatus(true); }, 1000); } // 监听权限状态变化(用于组件外部使用) export function addHealthPermissionListener( event: 'permissionStatusChanged' | 'permissionGranted', listener: (...args: any[]) => void ) { healthPermissionManager.on(event, listener); } // 移除权限状态监听器 export function removeHealthPermissionListener( event: 'permissionStatusChanged' | 'permissionGranted', listener: (...args: any[]) => void ) { healthPermissionManager.off(event, listener); } // 清理权限管理资源(应在应用退出时调用) export function cleanupHealthPermissions() { console.log('清理HealthKit权限管理资源...'); healthPermissionManager.destroy(); } // 获取权限状态的可读文本 export function getPermissionStatusText(status: HealthPermissionStatus): string { switch (status) { case HealthPermissionStatus.Authorized: return '已授权'; case HealthPermissionStatus.Denied: return '已拒绝'; case HealthPermissionStatus.NotDetermined: return '未确定'; case HealthPermissionStatus.Unknown: default: return '未知'; } } // 检查是否需要显示权限请求UI export function shouldShowPermissionRequest(): boolean { const status = healthPermissionManager.getPermissionStatus(); return status === HealthPermissionStatus.NotDetermined || status === HealthPermissionStatus.Unknown; } // 检查是否权限被用户拒绝 export function isPermissionDenied(): boolean { const status = healthPermissionManager.getPermissionStatus(); return status === HealthPermissionStatus.Denied; }