236 lines
7.5 KiB
TypeScript
236 lines
7.5 KiB
TypeScript
/**
|
||
* HealthKit Native Module Usage Example
|
||
* 展示如何使用HealthKit native module的示例代码
|
||
*/
|
||
|
||
import HealthKitManager, { HealthKitUtils, SleepDataSample } from './healthKit';
|
||
|
||
export class HealthKitService {
|
||
|
||
/**
|
||
* 初始化HealthKit并请求权限
|
||
*/
|
||
static async initializeHealthKit(): Promise<boolean> {
|
||
try {
|
||
// 检查HealthKit是否可用
|
||
if (!HealthKitUtils.isAvailable()) {
|
||
console.log('HealthKit不可用,可能运行在Android设备或模拟器上');
|
||
return false;
|
||
}
|
||
|
||
// 请求授权
|
||
const result = await HealthKitManager.requestAuthorization();
|
||
|
||
if (result.success) {
|
||
console.log('HealthKit授权成功');
|
||
console.log('权限状态:', result.permissions);
|
||
|
||
// 检查睡眠数据权限
|
||
const sleepPermission = result.permissions['HKCategoryTypeIdentifierSleepAnalysis'];
|
||
if (sleepPermission === 'authorized') {
|
||
console.log('睡眠数据访问权限已获得');
|
||
return true;
|
||
} else {
|
||
console.log('睡眠数据访问权限未获得:', sleepPermission);
|
||
return false;
|
||
}
|
||
} else {
|
||
console.log('HealthKit授权失败');
|
||
return false;
|
||
}
|
||
} catch (error) {
|
||
console.error('HealthKit初始化失败:', error);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取最近的睡眠数据
|
||
*/
|
||
static async getRecentSleepData(days: number = 7): Promise<SleepDataSample[]> {
|
||
try {
|
||
const endDate = new Date();
|
||
const startDate = new Date();
|
||
startDate.setDate(endDate.getDate() - days);
|
||
|
||
const result = await HealthKitManager.getSleepData({
|
||
startDate: startDate.toISOString(),
|
||
endDate: endDate.toISOString(),
|
||
limit: 100
|
||
});
|
||
|
||
console.log(`获取到 ${result.count} 条睡眠记录`);
|
||
return result.data;
|
||
} catch (error) {
|
||
console.error('获取睡眠数据失败:', error);
|
||
return [];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 分析睡眠质量
|
||
*/
|
||
static async analyzeSleepQuality(days: number = 7): Promise<any> {
|
||
try {
|
||
const sleepData = await this.getRecentSleepData(days);
|
||
|
||
if (sleepData.length === 0) {
|
||
return {
|
||
error: '没有找到睡眠数据',
|
||
hasData: false
|
||
};
|
||
}
|
||
|
||
// 按日期分组
|
||
const groupedData = HealthKitUtils.groupSamplesByDate(sleepData);
|
||
const dates = Object.keys(groupedData).sort().reverse(); // 最新的日期在前
|
||
|
||
const analysis = dates.slice(0, days).map(date => {
|
||
const daySamples = groupedData[date];
|
||
const totalSleepDuration = HealthKitUtils.getTotalSleepDuration(daySamples, new Date(date));
|
||
const qualityMetrics = HealthKitUtils.getSleepQualityMetrics(daySamples);
|
||
|
||
return {
|
||
date,
|
||
totalSleepDuration,
|
||
totalSleepFormatted: HealthKitUtils.formatDuration(totalSleepDuration),
|
||
qualityMetrics,
|
||
samplesCount: daySamples.length
|
||
};
|
||
});
|
||
|
||
// 计算平均值
|
||
const validDays = analysis.filter(day => day.totalSleepDuration > 0);
|
||
const averageSleepDuration = validDays.length > 0
|
||
? validDays.reduce((sum, day) => sum + day.totalSleepDuration, 0) / validDays.length
|
||
: 0;
|
||
|
||
return {
|
||
hasData: true,
|
||
days: analysis,
|
||
summary: {
|
||
averageSleepDuration,
|
||
averageSleepFormatted: HealthKitUtils.formatDuration(averageSleepDuration),
|
||
daysWithData: validDays.length,
|
||
totalDaysAnalyzed: days
|
||
}
|
||
};
|
||
} catch (error) {
|
||
console.error('睡眠质量分析失败:', error);
|
||
return {
|
||
error: error instanceof Error ? error.message : String(error),
|
||
hasData: false
|
||
};
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取昨晚的睡眠数据
|
||
*/
|
||
static async getLastNightSleep(): Promise<any> {
|
||
try {
|
||
const today = new Date();
|
||
const yesterday = new Date(today);
|
||
yesterday.setDate(today.getDate() - 1);
|
||
|
||
// 设置查询范围:昨天下午6点到今天上午12点
|
||
const startDate = new Date(yesterday);
|
||
startDate.setHours(18, 0, 0, 0);
|
||
|
||
const endDate = new Date(today);
|
||
endDate.setHours(12, 0, 0, 0);
|
||
|
||
const result = await HealthKitManager.getSleepData({
|
||
startDate: startDate.toISOString(),
|
||
endDate: endDate.toISOString(),
|
||
limit: 50
|
||
});
|
||
|
||
if (result.data.length === 0) {
|
||
return {
|
||
hasData: false,
|
||
message: '未找到昨晚的睡眠数据'
|
||
};
|
||
}
|
||
|
||
const sleepSamples = result.data.filter(sample =>
|
||
['asleep', 'core', 'deep', 'rem'].includes(sample.categoryType)
|
||
);
|
||
|
||
if (sleepSamples.length === 0) {
|
||
return {
|
||
hasData: false,
|
||
message: '未找到有效的睡眠阶段数据'
|
||
};
|
||
}
|
||
|
||
// 找到睡眠的开始和结束时间
|
||
const sleepStart = new Date(Math.min(...sleepSamples.map(s => new Date(s.startDate).getTime())));
|
||
const sleepEnd = new Date(Math.max(...sleepSamples.map(s => new Date(s.endDate).getTime())));
|
||
const totalDuration = sleepSamples.reduce((sum, s) => sum + s.duration, 0);
|
||
|
||
const qualityMetrics = HealthKitUtils.getSleepQualityMetrics(sleepSamples);
|
||
|
||
return {
|
||
hasData: true,
|
||
sleepStart: sleepStart.toISOString(),
|
||
sleepEnd: sleepEnd.toISOString(),
|
||
totalDuration,
|
||
totalDurationFormatted: HealthKitUtils.formatDuration(totalDuration),
|
||
qualityMetrics,
|
||
samples: sleepSamples,
|
||
bedTime: sleepStart.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }),
|
||
wakeTime: sleepEnd.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
|
||
};
|
||
} catch (error) {
|
||
console.error('获取昨晚睡眠数据失败:', error);
|
||
return {
|
||
hasData: false,
|
||
error: error instanceof Error ? error.message : String(error)
|
||
};
|
||
}
|
||
}
|
||
}
|
||
|
||
// 使用示例
|
||
export const useHealthKitExample = async () => {
|
||
console.log('=== HealthKit 使用示例 ===');
|
||
|
||
// 1. 初始化和授权
|
||
const initialized = await HealthKitService.initializeHealthKit();
|
||
if (!initialized) {
|
||
console.log('HealthKit初始化失败,无法继续');
|
||
return;
|
||
}
|
||
|
||
// 2. 获取昨晚的睡眠数据
|
||
console.log('\n--- 昨晚睡眠数据 ---');
|
||
const lastNightSleep = await HealthKitService.getLastNightSleep();
|
||
if (lastNightSleep.hasData) {
|
||
console.log(`睡眠时间: ${lastNightSleep.bedTime} - ${lastNightSleep.wakeTime}`);
|
||
console.log(`睡眠时长: ${lastNightSleep.totalDurationFormatted}`);
|
||
if (lastNightSleep.qualityMetrics) {
|
||
console.log(`深睡眠: ${lastNightSleep.qualityMetrics.deepSleepPercentage.toFixed(1)}%`);
|
||
console.log(`REM睡眠: ${lastNightSleep.qualityMetrics.remSleepPercentage.toFixed(1)}%`);
|
||
}
|
||
} else {
|
||
console.log(lastNightSleep.message || '未找到睡眠数据');
|
||
}
|
||
|
||
// 3. 分析最近一周的睡眠质量
|
||
console.log('\n--- 最近一周睡眠分析 ---');
|
||
const weeklyAnalysis = await HealthKitService.analyzeSleepQuality(7);
|
||
if (weeklyAnalysis.hasData) {
|
||
console.log(`平均睡眠时长: ${weeklyAnalysis.summary.averageSleepFormatted}`);
|
||
console.log(`有数据的天数: ${weeklyAnalysis.summary.daysWithData}/${weeklyAnalysis.summary.totalDaysAnalyzed}`);
|
||
|
||
console.log('\n每日睡眠详情:');
|
||
weeklyAnalysis.days.forEach((day: any) => {
|
||
if (day.totalSleepDuration > 0) {
|
||
console.log(`${day.date}: ${day.totalSleepFormatted}`);
|
||
}
|
||
});
|
||
} else {
|
||
console.log(weeklyAnalysis.error || '睡眠分析失败');
|
||
}
|
||
}; |