import { fetchRecentWorkouts, WorkoutData } from '@/utils/health'; import AsyncStorage from '@/utils/kvStore'; import { NativeEventEmitter, NativeModules } from 'react-native'; import { analyzeWorkoutAndSendNotification } from './workoutNotificationService'; const { HealthKitManager } = NativeModules; const workoutEmitter = new NativeEventEmitter(HealthKitManager); class WorkoutMonitorService { private static instance: WorkoutMonitorService; private isInitialized = false; private lastProcessedWorkoutId: string | null = null; private processingTimeout: any = null; private eventListenerSubscription: any = null; static getInstance(): WorkoutMonitorService { if (!WorkoutMonitorService.instance) { WorkoutMonitorService.instance = new WorkoutMonitorService(); } return WorkoutMonitorService.instance; } async initialize(): Promise { if (this.isInitialized) { console.log('锻炼监听服务已初始化'); return; } try { // 获取上次处理的锻炼ID await this.loadLastProcessedWorkoutId(); // 启动 iOS 原生锻炼监听器 await HealthKitManager.startWorkoutObserver(); // 监听锻炼更新事件 this.eventListenerSubscription = workoutEmitter.addListener( 'workoutUpdate', this.handleWorkoutUpdate.bind(this) ); this.isInitialized = true; console.log('锻炼监听服务初始化成功'); } catch (error) { console.error('锻炼监听服务初始化失败:', error); throw error; } } async stop(): Promise { try { // 停止原生监听器 await HealthKitManager.stopWorkoutObserver(); // 移除事件监听器 if (this.eventListenerSubscription) { this.eventListenerSubscription.remove(); this.eventListenerSubscription = null; } // 清理定时器 if (this.processingTimeout) { clearTimeout(this.processingTimeout); this.processingTimeout = null; } this.isInitialized = false; console.log('锻炼监听服务已停止'); } catch (error) { console.error('停止锻炼监听服务失败:', error); } } private async loadLastProcessedWorkoutId(): Promise { try { const storedId = await AsyncStorage.getItem('@last_processed_workout_id'); this.lastProcessedWorkoutId = storedId; console.log('上次处理的锻炼ID:', this.lastProcessedWorkoutId); } catch (error) { console.error('加载上次处理的锻炼ID失败:', error); } } private async saveLastProcessedWorkoutId(workoutId: string): Promise { try { await AsyncStorage.setItem('@last_processed_workout_id', workoutId); this.lastProcessedWorkoutId = workoutId; } catch (error) { console.error('保存上次处理的锻炼ID失败:', error); } } private async handleWorkoutUpdate(event: any): Promise { console.log('收到锻炼更新事件:', event); // 防抖处理,避免短时间内重复处理 if (this.processingTimeout) { clearTimeout(this.processingTimeout); } this.processingTimeout = setTimeout(async () => { try { await this.checkForNewWorkouts(); } catch (error) { console.error('检查新锻炼失败:', error); } }, 5000); // 5秒延迟,确保 HealthKit 数据已完全更新 } private async checkForNewWorkouts(): Promise { try { console.log('检查新的锻炼记录...'); // 获取最近1小时的锻炼记录 const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000); const recentWorkouts = await fetchRecentWorkouts({ startDate: oneHourAgo.toISOString(), endDate: new Date().toISOString(), limit: 10 }); console.log(`找到 ${recentWorkouts.length} 条最近的锻炼记录`); // 检查是否有新的锻炼记录 for (const workout of recentWorkouts) { if (workout.id !== this.lastProcessedWorkoutId) { console.log('检测到新锻炼:', { id: workout.id, type: workout.workoutActivityTypeString, duration: workout.duration, startDate: workout.startDate }); await this.processNewWorkout(workout); await this.saveLastProcessedWorkoutId(workout.id); } else { console.log('锻炼已处理过,跳过:', workout.id); } } } catch (error) { console.error('检查新锻炼失败:', error); } } private async processNewWorkout(workout: WorkoutData): Promise { try { console.log('开始处理新锻炼:', workout.id); // 分析锻炼并发送通知 await analyzeWorkoutAndSendNotification(workout); console.log('新锻炼处理完成:', workout.id); } catch (error) { console.error('处理新锻炼失败:', error); } } // 手动触发检查(用于测试) async manualCheck(): Promise { console.log('手动触发锻炼检查...'); await this.checkForNewWorkouts(); } // 获取服务状态 getStatus(): { initialized: boolean; lastProcessedWorkoutId: string | null } { return { initialized: this.isInitialized, lastProcessedWorkoutId: this.lastProcessedWorkoutId }; } } export const workoutMonitorService = WorkoutMonitorService.getInstance();