Commit cf671201b853d1a2c5f68ed95b829d28853cdb7b

Authored by 权海
1 parent 8cf44b6b

feat(ui):修改首页activity的获取参数

import Foundation
import HealthKit
let kLocalAnchored = 0
struct AnchoredHealthUploadSummary {
let sleepUploadSuccess: Bool
let errorMessage: String?
... ...
... ... @@ -139,7 +139,7 @@ final class HealthKitQueryReader {
return try await fetchRawQuantitySamples(
identifier: .appleStandTime,
dataType: .stand,
unit: .hour(),
unit: .count(),
startDate: startDate,
endDate: endDate
)
... ... @@ -209,7 +209,7 @@ 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),
... ...
... ... @@ -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?
... ...
... ... @@ -251,6 +251,7 @@ struct HealthKitRawMotionDataPoint: Hashable {
/// Generated class from Pigeon that represents data sent in messages.
struct HealthKitRawActivityDataPoint: Hashable {
var endTime: Int64
var activityMoveMode: Int64? = nil
var activeEnergyBurned: Double? = nil
var activeEnergyBurnedGoal: Double? = nil
var appleMoveTime: Double? = nil
... ... @@ -264,17 +265,19 @@ struct HealthKitRawActivityDataPoint: Hashable {
// swift-format-ignore: AlwaysUseLowerCamelCase
static func fromList(_ pigeonVar_list: [Any?]) -> HealthKitRawActivityDataPoint? {
let endTime = pigeonVar_list[0] as! Int64
let activeEnergyBurned: Double? = nilOrValue(pigeonVar_list[1])
let activeEnergyBurnedGoal: Double? = nilOrValue(pigeonVar_list[2])
let appleMoveTime: Double? = nilOrValue(pigeonVar_list[3])
let appleMoveTimeGoal: Double? = nilOrValue(pigeonVar_list[4])
let appleExerciseTime: Double? = nilOrValue(pigeonVar_list[5])
let exerciseTimeGoal: Double? = nilOrValue(pigeonVar_list[6])
let appleStandHours: Double? = nilOrValue(pigeonVar_list[7])
let standHoursGoal: Double? = nilOrValue(pigeonVar_list[8])
let activityMoveMode: Int64? = nilOrValue(pigeonVar_list[1])
let activeEnergyBurned: Double? = nilOrValue(pigeonVar_list[2])
let activeEnergyBurnedGoal: Double? = nilOrValue(pigeonVar_list[3])
let appleMoveTime: Double? = nilOrValue(pigeonVar_list[4])
let appleMoveTimeGoal: Double? = nilOrValue(pigeonVar_list[5])
let appleExerciseTime: Double? = nilOrValue(pigeonVar_list[6])
let exerciseTimeGoal: Double? = nilOrValue(pigeonVar_list[7])
let appleStandHours: Double? = nilOrValue(pigeonVar_list[8])
let standHoursGoal: Double? = nilOrValue(pigeonVar_list[9])
return HealthKitRawActivityDataPoint(
endTime: endTime,
activityMoveMode: activityMoveMode,
activeEnergyBurned: activeEnergyBurned,
activeEnergyBurnedGoal: activeEnergyBurnedGoal,
appleMoveTime: appleMoveTime,
... ... @@ -288,6 +291,7 @@ struct HealthKitRawActivityDataPoint: Hashable {
func toList() -> [Any?] {
return [
endTime,
activityMoveMode,
activeEnergyBurned,
activeEnergyBurnedGoal,
appleMoveTime,
... ... @@ -386,6 +390,16 @@ protocol HealthKitRawDataHostApi {
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)
/// 原生是否通知了flutter ,apple health数据变化,让native 记录这次调用记录
/// 需要保存引起此次计算的数据变化类型列表、当前时间
func saveNativeCallFlutterChange(relativeDataTypes: [Int64], completion: @escaping (Result<Bool, Error>) -> Void)
/// caculate 一旦完成,让native 存储这次的计算记录
/// 需要保存引起此次计算的数据变化类型列表、当前时间
func saveFlutterCaculateFinished(relativeDataTypes: [Int64], completion: @escaping (Result<Bool, Error>) -> Void)
/// 让原生分享出来本地的记录文件
func shareNativeAppleHealthObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void)
/// 让原生分享出来flutter的记录文件
func shareFlutterObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void)
}
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
... ... @@ -596,5 +610,75 @@ class HealthKitRawDataHostApiSetup {
} else {
getHealthKitRawWorkoutDataChannel.setMessageHandler(nil)
}
/// 原生是否通知了flutter ,apple health数据变化,让native 记录这次调用记录
/// 需要保存引起此次计算的数据变化类型列表、当前时间
let saveNativeCallFlutterChangeChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.saveNativeCallFlutterChange\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
saveNativeCallFlutterChangeChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let relativeDataTypesArg = args[0] as! [Int64]
api.saveNativeCallFlutterChange(relativeDataTypes: relativeDataTypesArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
saveNativeCallFlutterChangeChannel.setMessageHandler(nil)
}
/// caculate 一旦完成,让native 存储这次的计算记录
/// 需要保存引起此次计算的数据变化类型列表、当前时间
let saveFlutterCaculateFinishedChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.saveFlutterCaculateFinished\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
saveFlutterCaculateFinishedChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let relativeDataTypesArg = args[0] as! [Int64]
api.saveFlutterCaculateFinished(relativeDataTypes: relativeDataTypesArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
saveFlutterCaculateFinishedChannel.setMessageHandler(nil)
}
/// 让原生分享出来本地的记录文件
let shareNativeAppleHealthObserverRecordChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareNativeAppleHealthObserverRecord\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
shareNativeAppleHealthObserverRecordChannel.setMessageHandler { _, reply in
api.shareNativeAppleHealthObserverRecord { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
shareNativeAppleHealthObserverRecordChannel.setMessageHandler(nil)
}
/// 让原生分享出来flutter的记录文件
let shareFlutterObserverRecordChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareFlutterObserverRecord\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
shareFlutterObserverRecordChannel.setMessageHandler { _, reply in
api.shareFlutterObserverRecord { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
shareFlutterObserverRecordChannel.setMessageHandler(nil)
}
}
}
... ...
import Foundation
final class HealthKitRawDataHostApiImpl: HealthKitRawDataHostApi {
func saveNativeCallFlutterChange(relativeDataTypes: [Int64], completion: @escaping (Result<Bool, any Error>) -> Void) {
}
func saveFlutterCaculateFinished(relativeDataTypes: [Int64], completion: @escaping (Result<Bool, any Error>) -> Void) {
}
func shareNativeAppleHealthObserverRecord(completion: @escaping (Result<Bool, any Error>) -> Void) {
}
func shareFlutterObserverRecord(completion: @escaping (Result<Bool, any Error>) -> Void) {
}
private let service: HealthKitService
init(service: HealthKitService = .shared) {
... ... @@ -229,6 +245,7 @@ final class HealthKitRawDataHostApiImpl: HealthKitRawDataHostApi {
}
return HealthKitRawActivityDataPoint(
endTime: Int64(endTime.rounded()),
activityMoveMode: target.activityMoveMode == nil ? nil : Int64(target.activityMoveMode!),
activeEnergyBurned: target.activeEnergyBurned,
activeEnergyBurnedGoal: target.activeEnergyBurnedGoal,
appleMoveTime: target.appleMoveTime,
... ...
... ... @@ -490,7 +490,7 @@ class TodayController extends GetMaterialController {
case AppFailure():
stressChartData.clear();
}
switch (await _healthApi.getV2ActivityTarget(friendUserId)) {
switch (await _healthApi.getV2ActivityTarget(friendUserId, intDate)) {
case AppSuccess(:final data):
v2ActivityTarget.value = data;
case AppFailure():
... ... @@ -703,6 +703,8 @@ class TodayController extends GetMaterialController {
checkAddFriendVisible();
checkHrvAdBannerVisible();
checkHealthDataAuthCardVisible();
_performHealthDataUpload();
// _startCoreCaculate();
// unawaited(loadDataForDate(selectedDate.value));
}
}
... ... @@ -718,6 +720,7 @@ class TodayController extends GetMaterialController {
checkAddFriendVisible();
checkHrvAdBannerVisible();
checkHealthDataAuthCardVisible(isPullToRefresh: isPullToRefresh);
_performHealthDataUpload();
// await loadDataForDate(selectedDate.value);
}
}
... ...
... ... @@ -51,6 +51,7 @@ abstract interface class HealthDataSource {
Future<AppResult<V2ActivityTarget>> getV2ActivityTarget(
int? queryUserId,
int intDate,
);
Future<AppResult<V2HealthEverUploaded>> getHealthDataEverUploaded();
... ...
... ... @@ -79,13 +79,14 @@ class HealthDataSourceWrapper implements HealthDataSource {
}
@override
Future<AppResult<V2ActivityTarget>> getV2ActivityTarget(int? queryUserId) {
Future<AppResult<V2ActivityTarget>> getV2ActivityTarget(
int? queryUserId, int initDate) {
HealthDataSource dataSource = remoteDataSource;
if (queryUserId == null || _myUserId == queryUserId) {
dataSource = localDataSource;
}
return dataSource.getV2ActivityTarget(queryUserId);
return dataSource.getV2ActivityTarget(queryUserId, initDate);
}
@override
... ...
... ... @@ -263,7 +263,7 @@ class LocalHealthDataConvert {
final data = ActivityBurnStatisticsDataV2(
totalMove: _sum(daily.map((e) => e.move).toList()),
totalSteps: _sum(daily.map((e) => e.steps).toList()),
totalSteps: 0,
totalStand: _sum(daily.map((e) => e.standHours).toList()),
totalExercise: _sum(daily.map((e) => e.exerciseSeconds).toList()),
avgMove: _averageOrNull(daily.map((e) => e.move).toList()),
... ... @@ -399,8 +399,8 @@ class LocalHealthDataConvert {
);
return V2ActivityTarget(
userId: userId,
move: latestWithGoal?.activeEnergyBurnedGoal?.round(),
step: latestWithGoal?.appleMoveTimeGoal?.round(),
move: latestWithGoal?.activeEnergyBurnedGoal?.ceil(),
step: 0,
stand: latestWithGoal?.standHoursGoal?.round(),
exercise: latestWithGoal?.exerciseTimeGoal == null
? null
... ... @@ -451,7 +451,7 @@ class LocalHealthDataConvert {
move: activitySummary.move.ceil(),
exercise: activitySummary.exerciseSeconds.round(),
stand: activitySummary.standHours.round(),
steps: activitySummary.steps.round(),
steps: 0,
sleepDuration: sleepSummary.durationSeconds.round(),
sleepScore: sleepSummary.score?.toDouble(),
sleepState: sleepSummary.state?.value,
... ... @@ -496,7 +496,7 @@ class LocalHealthDataConvert {
move: activitySummary.move.ceil(),
exercise: activitySummary.exerciseSeconds.round(),
stand: activitySummary.standHours.round(),
steps: activitySummary.steps.round(),
steps: 0,
sleepDuration: sleepResult == null ? 0 : sleepResult.sleepMinutes * 60,
sleepScore: sleepResult?.sleepScore.toDouble(),
sleepState: sleepResult?.sleepStateValue,
... ... @@ -521,22 +521,14 @@ class LocalHealthDataConvert {
}
static V2LatestHrvData v2LatestHrvData(
List<HealthRawHrvStressPoint> hrvPoints, {
List<HealthRawHrvStressPoint> previousHrvPoints =
const <HealthRawHrvStressPoint>[],
}) {
List<HealthRawHrvStressPoint> hrvPoints) {
final latest = _latestHrvByRawEndTime(hrvPoints);
return V2LatestHrvData(
latestHrv: (latest?.result ?? 0).floor().toDouble(),
latestDataTime: latest?.rawEndTime,
state: latest?.state.value,
tip: _latestHrvTip(
latest: latest,
previous: _previousHrvPoint(
latest: latest,
hrvPoints: hrvPoints,
previousHrvPoints: previousHrvPoints,
),
latest: latest
),
);
}
... ... @@ -581,13 +573,11 @@ class LocalHealthDataConvert {
final latest = dayActivity.isEmpty ? null : dayActivity.last;
return _ActivityDaySummary(
day: day,
move: latest?.activeEnergyBurned ?? 0,
steps: latest?.appleMoveTime ?? 0,
move: (latest?.activeEnergyBurned ?? 0).ceil(),
standHours: latest?.appleStandHours ?? 0,
exerciseSeconds: latest?.appleExerciseTime ?? 0,
moveGoal: latest?.activeEnergyBurnedGoal,
stepGoal: latest?.appleMoveTimeGoal,
standGoal: latest?.standHoursGoal,
moveGoal: latest?.activeEnergyBurnedGoal ?? 480,
standGoal: latest?.standHoursGoal ?? 8,
exerciseGoalSeconds: latest?.exerciseTimeGoal,
);
}
... ... @@ -627,11 +617,9 @@ class LocalHealthDataConvert {
}
static String? _latestHrvTip({
required HealthRawHrvStressPoint? latest,
required HealthRawHrvStressPoint? previous,
required HealthRawHrvStressPoint? latest
}) {
if (latest == null || previous == null) return null;
if (latest.rawEndTime - previous.rawEndTime < 2 * 60 * 60) return null;
if (latest == null) return null;
final isAboveBaseline = latest.result >= latest.baselineHrv;
return switch (latest.state) {
... ... @@ -665,7 +653,7 @@ class LocalHealthDataConvert {
if (summary == null || !summary.hasGoal) return null;
return ActivityTargetInfo(
move: summary.moveGoal,
step: summary.stepGoal,
step: 0,
stand: summary.standGoal,
exercise: summary.exerciseGoalSeconds,
);
... ... @@ -963,28 +951,23 @@ class _ActivityDaySummary {
const _ActivityDaySummary({
required this.day,
required this.move,
required this.steps,
required this.standHours,
required this.exerciseSeconds,
required this.moveGoal,
required this.stepGoal,
required this.standGoal,
required this.exerciseGoalSeconds,
});
final DateTime day;
final num move;
final num steps;
final num standHours;
final num exerciseSeconds;
final num? moveGoal;
final num? stepGoal;
final num? standGoal;
final num? exerciseGoalSeconds;
bool get hasGoal =>
moveGoal != null ||
stepGoal != null ||
standGoal != null ||
exerciseGoalSeconds != null;
}
... ...
... ... @@ -160,21 +160,20 @@ class LocalHealthDataSource implements HealthDataSource {
@override
Future<AppResult<V2ActivityTarget>> getV2ActivityTarget(
int? queryUserId) async {
int? queryUserId, int intDate) async {
try {
final now = DateTime.now();
final queryStart = LocalHealthDataConvert.unixSeconds(
now.subtract(
const Duration(days: HealthRawDataCoreService.defaultLookbackDays)),
final day = LocalHealthDataConvert.dateFromKey(intDate);
final queryStart = LocalHealthDataConvert.unixSeconds(day);
final queryEnd = LocalHealthDataConvert.unixSeconds(
day.add(const Duration(days: 1)),
);
final queryEnd = LocalHealthDataConvert.unixSeconds(now);
final activity = await coreService.queryRawActivitySummaries(
startTime: queryStart,
endTime: queryEnd,
);
return AppSuccess(
LocalHealthDataConvert.v2ActivityTarget(
userId: 0,
userId: queryUserId ?? 0,
activity: activity,
),
);
... ... @@ -249,21 +248,12 @@ class LocalHealthDataSource implements HealthDataSource {
int? queryUserId, int intDate) async {
try {
final (startTime, endTime) = _dayRange(intDate);
final previousStartTime = startTime -
HealthRawDataCoreService.defaultLookbackDays * Duration.secondsPerDay;
final previousHrvPoints = await coreService.queryHrvStressPoints(
startTime: previousStartTime,
endTime: startTime - 1,
);
final hrvPoints = await coreService.queryHrvStressPoints(
startTime: startTime,
endTime: endTime,
);
return AppSuccess(
LocalHealthDataConvert.v2LatestHrvData(
hrvPoints,
previousHrvPoints: previousHrvPoints,
),
LocalHealthDataConvert.v2LatestHrvData(hrvPoints),
);
} catch (error) {
return AppFailure(AppUnknownError(error));
... ...
... ... @@ -95,6 +95,7 @@ class RemoteHealthDataSource implements HealthDataSource {
@override
Future<AppResult<V2ActivityTarget>> getV2ActivityTarget(
int? queryUserId,
int initDate,
) {
return _healthApi.getV2ActivityTarget(queryUserId);
}
... ...
... ... @@ -242,6 +242,7 @@ class HealthKitRawMotionDataPoint {
class HealthKitRawActivityDataPoint {
HealthKitRawActivityDataPoint({
required this.endTime,
this.activityMoveMode,
this.activeEnergyBurned,
this.activeEnergyBurnedGoal,
this.appleMoveTime,
... ... @@ -254,6 +255,8 @@ class HealthKitRawActivityDataPoint {
int endTime;
int? activityMoveMode;
double? activeEnergyBurned;
double? activeEnergyBurnedGoal;
... ... @@ -273,6 +276,7 @@ class HealthKitRawActivityDataPoint {
List<Object?> _toList() {
return <Object?>[
endTime,
activityMoveMode,
activeEnergyBurned,
activeEnergyBurnedGoal,
appleMoveTime,
... ... @@ -291,14 +295,15 @@ class HealthKitRawActivityDataPoint {
result as List<Object?>;
return HealthKitRawActivityDataPoint(
endTime: result[0]! as int,
activeEnergyBurned: result[1] as double?,
activeEnergyBurnedGoal: result[2] as double?,
appleMoveTime: result[3] as double?,
appleMoveTimeGoal: result[4] as double?,
appleExerciseTime: result[5] as double?,
exerciseTimeGoal: result[6] as double?,
appleStandHours: result[7] as double?,
standHoursGoal: result[8] as double?,
activityMoveMode: result[1] as int?,
activeEnergyBurned: result[2] as double?,
activeEnergyBurnedGoal: result[3] as double?,
appleMoveTime: result[4] as double?,
appleMoveTimeGoal: result[5] as double?,
appleExerciseTime: result[6] as double?,
exerciseTimeGoal: result[7] as double?,
appleStandHours: result[8] as double?,
standHoursGoal: result[9] as double?,
);
}
... ... @@ -698,4 +703,122 @@ class HealthKitRawDataHostApi {
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawWorkoutDataPoint>();
}
}
/// 原生是否通知了flutter ,apple health数据变化,让native 记录这次调用记录
/// 需要保存引起此次计算的数据变化类型列表、当前时间
Future<bool> saveNativeCallFlutterChange({List<int> relativeDataTypes}) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.saveNativeCallFlutterChange$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[relativeDataTypes]);
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?)!;
}
}
/// caculate 一旦完成,让native 存储这次的计算记录
/// 需要保存引起此次计算的数据变化类型列表、当前时间
Future<bool> saveFlutterCaculateFinished({List<int> relativeDataTypes}) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.saveFlutterCaculateFinished$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[relativeDataTypes]);
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?)!;
}
}
/// 让原生分享出来本地的记录文件
Future<bool> shareNativeAppleHealthObserverRecord() async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareNativeAppleHealthObserverRecord$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
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?)!;
}
}
/// 让原生分享出来flutter的记录文件
Future<bool> shareFlutterObserverRecord() async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareFlutterObserverRecord$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
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?)!;
}
}
}
... ...
... ... @@ -51,6 +51,8 @@ class HealthKitRawMotionDataPoint {
class HealthKitRawActivityDataPoint {
int endTime;
int? activityMoveMode;
// 千卡
double? activeEnergyBurned;
double? activeEnergyBurnedGoal;
... ... @@ -66,6 +68,7 @@ class HealthKitRawActivityDataPoint {
HealthKitRawActivityDataPoint({
required this.endTime,
this.activityMoveMode,
this.activeEnergyBurned,
this.activeEnergyBurnedGoal,
this.appleMoveTime,
... ... @@ -140,4 +143,23 @@ abstract class HealthKitRawDataHostApi {
@async
List<HealthKitRawWorkoutDataPoint> getHealthKitRawWorkoutData(
int startTime, int endTime);
// DEBUG
/// 原生是否通知了flutter ,apple health数据变化,让native 记录这次调用记录
/// 需要保存引起此次计算的数据变化类型列表、当前时间
@async
bool saveNativeCallFlutterChange({List<int> relativeDataTypes});
/// caculate 一旦完成,让native 存储这次的计算记录
/// 需要保存引起此次计算的数据变化类型列表、当前时间
@async
bool saveFlutterCaculateFinished({List<int> relativeDataTypes});
/// 让原生分享出来本地的记录文件
@async
bool shareNativeAppleHealthObserverRecord();
/// 让原生分享出来flutter的记录文件
@async
bool shareFlutterObserverRecord();
}
... ...
... ... @@ -447,6 +447,7 @@ void main() {
final activity = [
HealthKitRawActivityDataPoint(
endTime: endTime,
activityMoveMode: 0,
activeEnergyBurned: 300,
activeEnergyBurnedGoal: 500,
appleMoveTime: 8000,
... ... @@ -502,14 +503,6 @@ void main() {
state: HealthRawStressState.excellent,
),
],
previousHrvPoints: [
_hrvStressPoint(
rawEndTime: latestTime - 2 * 60 * 60,
result: 28,
baselineHrv: 30,
state: HealthRawStressState.normal,
),
],
);
expect(data.latestHrv, 35);
... ... @@ -528,9 +521,6 @@ void main() {
state: HealthRawStressState.attention,
),
],
previousHrvPoints: [
_hrvStressPoint(rawEndTime: latestTime - 3 * 60 * 60),
],
);
expect(data.tip, contains('明显低于日常水平'));
... ... @@ -548,9 +538,6 @@ void main() {
state: HealthRawStressState.excellent,
),
],
previousHrvPoints: [
_hrvStressPoint(rawEndTime: latestTime - 60 * 60),
],
);
expect(data.tip, isNull);
... ...