Commit a7f33c698359d2620e7f48d4339ca112c58965d0

Authored by 权海
1 parent 16975990

feat(ui):修改一些问题

... ... @@ -209,14 +209,14 @@ final class HealthKitQueryReader {
healthValueTimestamp: timestamp,
move: Int(summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie())),
stand: Int(summary.appleStandHoursGoal.doubleValue(for: .count())),
activityMoveMode: Self.activityMoveModeValue(from: summary),
// activityMoveMode: Self.activityMoveModeValue(from: summary),
activeEnergyBurned: summary.activeEnergyBurned.doubleValue(for: .kilocalorie()),
activeEnergyBurnedGoal: summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie()),
appleMoveTime: Self.appleMoveTimeValue(from: summary),
appleMoveTimeGoal: Self.appleMoveTimeGoalValue(from: summary),
appleExerciseTime: summary.appleExerciseTime.doubleValue(for: .minute()),
appleExerciseTime: summary.appleExerciseTime.doubleValue(for: .second()),
exerciseTimeGoal: Self.exerciseTimeGoalValue(from: summary),
appleStandHours: summary.appleStandHours.doubleValue(for: .count()),
appleStandHours: Self.standSeconds(from: summary.appleStandHours),
standHoursGoal: Self.standHoursGoalValue(from: summary)
)
}
... ... @@ -244,18 +244,22 @@ final class HealthKitQueryReader {
private static func exerciseTimeGoalValue(from summary: HKActivitySummary) -> Double? {
if #available(iOS 16.0, *) {
return summary.exerciseTimeGoal?.doubleValue(for: .minute())
return summary.exerciseTimeGoal?.doubleValue(for: .second())
}
return nil
}
private static func standHoursGoalValue(from summary: HKActivitySummary) -> Double? {
if #available(iOS 16.0, *) {
return summary.standHoursGoal?.doubleValue(for: .count())
return summary.standHoursGoal.map { Self.standSeconds(from: $0) }
}
return nil
}
private static func standSeconds(from quantity: HKQuantity) -> Double {
quantity.doubleValue(for: .count()) * 60 * 60
}
private func fetchHeartRateFamily(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] {
async let heartRate = fetchQuantitySamples(
identifier: .heartRate,
... ... @@ -332,7 +336,7 @@ final class HealthKitQueryReader {
return samples.map { sample in
var ismotion: Bool?
if identifier == .heartRate, let rawValue = sample.metadata?[ HKMetadataKeyHeartRateMotionContext] as? NSNumber, let context = HKHeartRateMotionContext(rawValue: rawValue.intValue) {
ismotion = context == .active || context == .sedentary
ismotion = context == .active
}
return NativeHealthRawDataPoint(
... ...
... ... @@ -132,7 +132,7 @@ struct NativeActivityTarget {
let healthValueTimestamp: TimeInterval?
let move: Int?
let stand: Int?
let activityMoveMode: Int?
// let activityMoveMode: Int?
// 千卡
let activeEnergyBurned: Double?
let activeEnergyBurnedGoal: Double?
... ...
... ... @@ -370,14 +370,18 @@ protocol HealthKitRawDataHostApi {
func getHealthKitRawData(dataType: Int64, startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawDataPoint], Error>) -> Void)
/// 原生数据上传
func performHealthDataUpload(completion: @escaping (Result<Bool, Error>) -> Void)
/// 上传心率 - 实时压力数据, 返回上传截止的时间戳, 方便flutter修改数据库
func performHRDataUpload(sqliteFilePath: String, completion: @escaping (Result<Int64, Error>) -> Void)
/// 上传HRV - HRV压力数据, 返回上传截止的时间戳,方便flutter 修改数据库
func performHRVDataUpload(sqliteFilePath: String, completion: @escaping (Result<Int64, Error>) -> Void)
/// 上传当前实时压力(统计维度是当天)
func performAvgRealtimeStressDataUpload(sqliteFilePath: String, completion: @escaping (Result<Bool, Error>) -> Void)
/// 从从AppleHealth中读取睡眠数据
func getHealthKitRawSleepData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawSleepDataPoint], Error>) -> Void)
/// 从从AppleHealth中读取活动统计数据
func getHealthKitRawActivityData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawActivityDataPoint], Error>) -> Void)
/// 从从AppleHealth中读取锻炼数据
func getHealthKitRawWorkoutData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawWorkoutDataPoint], Error>) -> Void)
/// 从从AppleHealth中读取锻炼数据
func getHealthKitRawMotionData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawMotionDataPoint], Error>) -> Void)
}
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
... ... @@ -438,6 +442,60 @@ class HealthKitRawDataHostApiSetup {
} else {
performHealthDataUploadChannel.setMessageHandler(nil)
}
/// 上传心率 - 实时压力数据, 返回上传截止的时间戳, 方便flutter修改数据库
let performHRDataUploadChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.performHRDataUpload\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
performHRDataUploadChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let sqliteFilePathArg = args[0] as! String
api.performHRDataUpload(sqliteFilePath: sqliteFilePathArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
performHRDataUploadChannel.setMessageHandler(nil)
}
/// 上传HRV - HRV压力数据, 返回上传截止的时间戳,方便flutter 修改数据库
let performHRVDataUploadChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.performHRVDataUpload\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
performHRVDataUploadChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let sqliteFilePathArg = args[0] as! String
api.performHRVDataUpload(sqliteFilePath: sqliteFilePathArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
performHRVDataUploadChannel.setMessageHandler(nil)
}
/// 上传当前实时压力(统计维度是当天)
let performAvgRealtimeStressDataUploadChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.performAvgRealtimeStressDataUpload\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
performAvgRealtimeStressDataUploadChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let sqliteFilePathArg = args[0] as! String
api.performAvgRealtimeStressDataUpload(sqliteFilePath: sqliteFilePathArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
performAvgRealtimeStressDataUploadChannel.setMessageHandler(nil)
}
/// 从从AppleHealth中读取睡眠数据
let getHealthKitRawSleepDataChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawSleepData\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
... ... @@ -495,24 +553,5 @@ class HealthKitRawDataHostApiSetup {
} else {
getHealthKitRawWorkoutDataChannel.setMessageHandler(nil)
}
/// 从从AppleHealth中读取锻炼数据
let getHealthKitRawMotionDataChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawMotionData\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getHealthKitRawMotionDataChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let startTimeArg = args[0] as! Int64
let endTimeArg = args[1] as! Int64
api.getHealthKitRawMotionData(startTime: startTimeArg, endTime: endTimeArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
getHealthKitRawMotionDataChannel.setMessageHandler(nil)
}
}
}
... ...
... ... @@ -20,6 +20,19 @@ final class HealthKitRawDataHostApiImpl: HealthKitRawDataHostApi {
completion(.success(true))
}
}
func performHRDataUpload(sqliteFilePath: String, completion: @escaping (Result<Int64, any Error>) -> Void) {
}
func performHRVDataUpload(sqliteFilePath: String, completion: @escaping (Result<Int64, any Error>) -> Void) {
}
func performAvgRealtimeStressDataUpload(sqliteFilePath: String, completion: @escaping (Result<Bool, any Error>) -> Void) {
}
func getHealthKitRawData(
dataType: Int64,
... ... @@ -133,10 +146,6 @@ final class HealthKitRawDataHostApiImpl: HealthKitRawDataHostApi {
}
}
}
func getHealthKitRawMotionData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawMotionDataPoint], any Error>) -> Void) {
}
func performSleepDataUpload(completion: @escaping (Result<Bool, Error>) -> Void) {
Task {
... ...
... ... @@ -107,7 +107,6 @@ class ApiActivityBurnReportDataSource implements ActivityBurnReportDataSource {
ActivityBurnStatisticsDataV2 data,
) {
final target = data.activityTargetInfo;
final overallValues = _dailyOverallValues(date, data.overallList);
final points = <ActivityBurnHeartRatePoint>[
for (final item in data.hrList ?? const <HrList>[])
if (_parseDateTime(item.dataTime) case final time?)
... ... @@ -120,13 +119,13 @@ class ApiActivityBurnReportDataSource implements ActivityBurnReportDataSource {
return ActivityBurnReport(
date: date,
activeEnergy:
_metric(overallValues?.move ?? data.totalMove, target?.move),
_metric(data.totalMove, target?.move),
exerciseMinutes: _exerciseDurationMetric(
overallValues?.exercise ?? data.totalExercise,
data.totalExercise,
target?.exercise,
),
standHours: _standDurationMetric(
overallValues?.stand ?? data.totalStand,
data.totalStand,
target?.stand,
),
heartRate: ActivityBurnHeartRateSummary(
... ... @@ -137,19 +136,6 @@ class ApiActivityBurnReportDataSource implements ActivityBurnReportDataSource {
);
}
Value? _dailyOverallValues(
DateTime date,
List<OverallList>? overallList,
) {
final items = overallList ?? const <OverallList>[];
for (final item in items) {
final time = _parseDateTime(item.timeKey);
if (time != null && _normalizeDate(time) == date) return item.value;
}
if (items.length == 1) return items.first.value;
return null;
}
List<ActivityBurnReport> _periodReports(
DateTime start,
int dayCount,
... ...
... ... @@ -230,7 +230,7 @@ class LocalHealthDataConvert {
final data = ActivityBurnStatisticsDataV2(
totalMove: _sum(daily.map((e) => e.move).toList()),
totalSteps: _sum(daily.map((e) => e.steps).toList()),
totalStand: _sum(daily.map((e) => e.standHours).toList()),
totalStand: _sum(daily.map((e) => e.standSeconds).toList()),
totalExercise: _sum(daily.map((e) => e.exerciseSeconds).toList()),
avgMove: _averageOrNull(daily.map((e) => e.move).toList()),
qoqAvgMove: _averageOrNull(previousDaily.map((e) => e.move).toList()),
... ... @@ -248,7 +248,7 @@ class LocalHealthDataConvert {
timeKey: dateKey(item.day),
value: Value(
move: item.move,
stand: item.standHours,
stand: item.standSeconds,
exercise: item.exerciseSeconds,
),
),
... ... @@ -370,7 +370,7 @@ class LocalHealthDataConvert {
stand: latestWithGoal?.standHoursGoal?.round(),
exercise: latestWithGoal?.exerciseTimeGoal == null
? null
: (latestWithGoal!.exerciseTimeGoal! * 60).round(),
: latestWithGoal!.exerciseTimeGoal!.round(),
updateTime: latestWithGoal?.endTime,
sleepTargetDuration: (60 * _sleepGoalMinutes).round(),
);
... ... @@ -414,7 +414,7 @@ class LocalHealthDataConvert {
)?.round(),
move: activitySummary.move.round(),
exercise: activitySummary.exerciseSeconds.round(),
stand: activitySummary.standHours.round(),
stand: activitySummary.standSeconds.round(),
steps: activitySummary.steps.round(),
sleepDuration: sleepSummary.durationSeconds.round(),
sleepScore: sleepSummary.score?.toDouble(),
... ... @@ -598,14 +598,12 @@ class LocalHealthDataConvert {
day: day,
move: latest?.activeEnergyBurned ?? 0,
steps: latest?.appleMoveTime ?? 0,
standHours: latest?.appleStandHours ?? 0,
exerciseSeconds: (latest?.appleExerciseTime ?? 0) * 60,
standSeconds: latest?.appleStandHours ?? 0,
exerciseSeconds: latest?.appleExerciseTime ?? 0,
moveGoal: latest?.activeEnergyBurnedGoal,
stepGoal: latest?.appleMoveTimeGoal,
standGoal: latest?.standHoursGoal,
exerciseGoalSeconds: latest?.exerciseTimeGoal == null
? null
: latest!.exerciseTimeGoal! * 60,
exerciseGoalSeconds: latest?.exerciseTimeGoal,
);
}
... ... @@ -1024,7 +1022,7 @@ class _ActivityDaySummary {
required this.day,
required this.move,
required this.steps,
required this.standHours,
required this.standSeconds,
required this.exerciseSeconds,
required this.moveGoal,
required this.stepGoal,
... ... @@ -1035,7 +1033,7 @@ class _ActivityDaySummary {
final DateTime day;
final num move;
final num steps;
final num standHours;
final num standSeconds;
final num exerciseSeconds;
final num? moveGoal;
final num? stepGoal;
... ...
... ... @@ -467,15 +467,15 @@ class HealthKitRawDataHostApi {
}
}
/// 从从AppleHealth中读取睡眠数据
Future<List<HealthKitRawSleepDataPoint>> getHealthKitRawSleepData(int startTime, int endTime) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawSleepData$pigeonVar_messageChannelSuffix';
/// 上传心率 - 实时压力数据, 返回上传截止的时间戳, 方便flutter修改数据库
Future<int> performHRDataUpload({required String sqliteFilePath}) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.performHRDataUpload$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[startTime, endTime]);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[sqliteFilePath]);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
... ... @@ -492,13 +492,71 @@ class HealthKitRawDataHostApi {
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawSleepDataPoint>();
return (pigeonVar_replyList[0] as int?)!;
}
}
/// 从从AppleHealth中读取活动统计数据
Future<List<HealthKitRawActivityDataPoint>> getHealthKitRawActivityData(int startTime, int endTime) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawActivityData$pigeonVar_messageChannelSuffix';
/// 上传HRV - HRV压力数据, 返回上传截止的时间戳,方便flutter 修改数据库
Future<int> performHRVDataUpload({required String sqliteFilePath}) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.performHRVDataUpload$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[sqliteFilePath]);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else if (pigeonVar_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as int?)!;
}
}
/// 上传当前实时压力(统计维度是当天)
Future<bool> performAvgRealtimeStressDataUpload({required String sqliteFilePath}) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.performAvgRealtimeStressDataUpload$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[sqliteFilePath]);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else if (pigeonVar_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as bool?)!;
}
}
/// 从从AppleHealth中读取睡眠数据
Future<List<HealthKitRawSleepDataPoint>> getHealthKitRawSleepData(int startTime, int endTime) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawSleepData$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
... ... @@ -521,13 +579,13 @@ class HealthKitRawDataHostApi {
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawActivityDataPoint>();
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawSleepDataPoint>();
}
}
/// 从从AppleHealth中读取锻炼数据
Future<List<HealthKitRawWorkoutDataPoint>> getHealthKitRawWorkoutData(int startTime, int endTime) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawWorkoutData$pigeonVar_messageChannelSuffix';
/// 从从AppleHealth中读取活动统计数据
Future<List<HealthKitRawActivityDataPoint>> getHealthKitRawActivityData(int startTime, int endTime) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawActivityData$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
... ... @@ -550,13 +608,13 @@ class HealthKitRawDataHostApi {
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawWorkoutDataPoint>();
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawActivityDataPoint>();
}
}
/// 从从AppleHealth中读取锻炼数据
Future<List<HealthKitRawMotionDataPoint>> getHealthKitRawMotionData(int startTime, int endTime) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawMotionData$pigeonVar_messageChannelSuffix';
Future<List<HealthKitRawWorkoutDataPoint>> getHealthKitRawWorkoutData(int startTime, int endTime) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.getHealthKitRawWorkoutData$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
... ... @@ -579,7 +637,7 @@ class HealthKitRawDataHostApi {
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawMotionDataPoint>();
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawWorkoutDataPoint>();
}
}
}
... ...
... ... @@ -102,6 +102,18 @@ abstract class HealthKitRawDataHostApi {
@async
bool performHealthDataUpload();
/// 上传心率 - 实时压力数据, 返回上传截止的时间戳, 方便flutter修改数据库
@async
int performHRDataUpload({required String sqliteFilePath});
/// 上传HRV - HRV压力数据, 返回上传截止的时间戳,方便flutter 修改数据库
@async
int performHRVDataUpload({required String sqliteFilePath});
/// 上传当前实时压力(统计维度是当天)
@async
bool performAvgRealtimeStressDataUpload({required String sqliteFilePath});
/// 从从AppleHealth中读取睡眠数据
@async
List<HealthKitRawSleepDataPoint> getHealthKitRawSleepData(
... ... @@ -116,9 +128,4 @@ abstract class HealthKitRawDataHostApi {
@async
List<HealthKitRawWorkoutDataPoint> getHealthKitRawWorkoutData(
int startTime, int endTime);
/// 从从AppleHealth中读取锻炼数据
@async
List<HealthKitRawMotionDataPoint> getHealthKitRawMotionData(
int startTime, int endTime);
}
... ...
... ... @@ -287,4 +287,56 @@ void main() {
HealthRawStressState.attention.value);
});
});
group('LocalHealthDataConvert activity unit conversion', () {
test('passes through exercise and stand seconds from raw activity data',
() {
final day = DateTime(2026, 7, 16);
final endTime = LocalHealthDataConvert.unixSeconds(
day.add(const Duration(hours: 12)),
);
final activity = [
HealthKitRawActivityDataPoint(
endTime: endTime,
activeEnergyBurned: 300,
activeEnergyBurnedGoal: 500,
appleMoveTime: 8000,
appleMoveTimeGoal: 10000,
appleExerciseTime: 1800,
exerciseTimeGoal: 3600,
appleStandHours: 21600,
standHoursGoal: 43200,
),
];
final healthData = LocalHealthDataConvert.v2HealthData(
day: day,
hrvPoints: const [],
activity: activity,
sleepingHeartRate: const [],
restingHeartRate: const [],
sleepIntervals: const [],
);
final target = LocalHealthDataConvert.v2ActivityTarget(
userId: 1,
activity: activity,
);
final statistics = LocalHealthDataConvert.activityBurnStatistics(
days: [day],
previousDays: const [],
activity: activity,
heartRate: const [],
sleepIntervals: const [],
);
expect(healthData.exercise, 1800);
expect(healthData.stand, 21600);
expect(target.exercise, 3600);
expect(target.stand, 43200);
expect(statistics.totalExercise, 1800);
expect(statistics.totalStand, 21600);
expect(statistics.activityTargetInfo?.exercise, 3600);
expect(statistics.activityTargetInfo?.stand, 43200);
});
});
}
... ...