Showing
14 changed files
with
297 additions
and
83 deletions
| 1 | import Foundation | 1 | import Foundation |
| 2 | import HealthKit | 2 | import HealthKit |
| 3 | 3 | ||
| 4 | +let kLocalAnchored = 0 | ||
| 5 | + | ||
| 4 | struct AnchoredHealthUploadSummary { | 6 | struct AnchoredHealthUploadSummary { |
| 5 | let sleepUploadSuccess: Bool | 7 | let sleepUploadSuccess: Bool |
| 6 | let errorMessage: String? | 8 | let errorMessage: String? |
| @@ -139,7 +139,7 @@ final class HealthKitQueryReader { | @@ -139,7 +139,7 @@ final class HealthKitQueryReader { | ||
| 139 | return try await fetchRawQuantitySamples( | 139 | return try await fetchRawQuantitySamples( |
| 140 | identifier: .appleStandTime, | 140 | identifier: .appleStandTime, |
| 141 | dataType: .stand, | 141 | dataType: .stand, |
| 142 | - unit: .hour(), | 142 | + unit: .count(), |
| 143 | startDate: startDate, | 143 | startDate: startDate, |
| 144 | endDate: endDate | 144 | endDate: endDate |
| 145 | ) | 145 | ) |
| @@ -209,7 +209,7 @@ final class HealthKitQueryReader { | @@ -209,7 +209,7 @@ final class HealthKitQueryReader { | ||
| 209 | healthValueTimestamp: timestamp, | 209 | healthValueTimestamp: timestamp, |
| 210 | move: Int(summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie())), | 210 | move: Int(summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie())), |
| 211 | stand: Int(summary.appleStandHoursGoal.doubleValue(for: .count())), | 211 | stand: Int(summary.appleStandHoursGoal.doubleValue(for: .count())), |
| 212 | -// activityMoveMode: Self.activityMoveModeValue(from: summary), | 212 | + activityMoveMode: Self.activityMoveModeValue(from: summary), |
| 213 | activeEnergyBurned: summary.activeEnergyBurned.doubleValue(for: .kilocalorie()), | 213 | activeEnergyBurned: summary.activeEnergyBurned.doubleValue(for: .kilocalorie()), |
| 214 | activeEnergyBurnedGoal: summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie()), | 214 | activeEnergyBurnedGoal: summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie()), |
| 215 | appleMoveTime: Self.appleMoveTimeValue(from: summary), | 215 | appleMoveTime: Self.appleMoveTimeValue(from: summary), |
| @@ -132,7 +132,7 @@ struct NativeActivityTarget { | @@ -132,7 +132,7 @@ struct NativeActivityTarget { | ||
| 132 | let healthValueTimestamp: TimeInterval? | 132 | let healthValueTimestamp: TimeInterval? |
| 133 | let move: Int? | 133 | let move: Int? |
| 134 | let stand: Int? | 134 | let stand: Int? |
| 135 | -// let activityMoveMode: Int? | 135 | + let activityMoveMode: Int? |
| 136 | // 千卡 | 136 | // 千卡 |
| 137 | let activeEnergyBurned: Double? | 137 | let activeEnergyBurned: Double? |
| 138 | let activeEnergyBurnedGoal: Double? | 138 | let activeEnergyBurnedGoal: Double? |
| @@ -251,6 +251,7 @@ struct HealthKitRawMotionDataPoint: Hashable { | @@ -251,6 +251,7 @@ struct HealthKitRawMotionDataPoint: Hashable { | ||
| 251 | /// Generated class from Pigeon that represents data sent in messages. | 251 | /// Generated class from Pigeon that represents data sent in messages. |
| 252 | struct HealthKitRawActivityDataPoint: Hashable { | 252 | struct HealthKitRawActivityDataPoint: Hashable { |
| 253 | var endTime: Int64 | 253 | var endTime: Int64 |
| 254 | + var activityMoveMode: Int64? = nil | ||
| 254 | var activeEnergyBurned: Double? = nil | 255 | var activeEnergyBurned: Double? = nil |
| 255 | var activeEnergyBurnedGoal: Double? = nil | 256 | var activeEnergyBurnedGoal: Double? = nil |
| 256 | var appleMoveTime: Double? = nil | 257 | var appleMoveTime: Double? = nil |
| @@ -264,17 +265,19 @@ struct HealthKitRawActivityDataPoint: Hashable { | @@ -264,17 +265,19 @@ struct HealthKitRawActivityDataPoint: Hashable { | ||
| 264 | // swift-format-ignore: AlwaysUseLowerCamelCase | 265 | // swift-format-ignore: AlwaysUseLowerCamelCase |
| 265 | static func fromList(_ pigeonVar_list: [Any?]) -> HealthKitRawActivityDataPoint? { | 266 | static func fromList(_ pigeonVar_list: [Any?]) -> HealthKitRawActivityDataPoint? { |
| 266 | let endTime = pigeonVar_list[0] as! Int64 | 267 | let endTime = pigeonVar_list[0] as! Int64 |
| 267 | - let activeEnergyBurned: Double? = nilOrValue(pigeonVar_list[1]) | ||
| 268 | - let activeEnergyBurnedGoal: Double? = nilOrValue(pigeonVar_list[2]) | ||
| 269 | - let appleMoveTime: Double? = nilOrValue(pigeonVar_list[3]) | ||
| 270 | - let appleMoveTimeGoal: Double? = nilOrValue(pigeonVar_list[4]) | ||
| 271 | - let appleExerciseTime: Double? = nilOrValue(pigeonVar_list[5]) | ||
| 272 | - let exerciseTimeGoal: Double? = nilOrValue(pigeonVar_list[6]) | ||
| 273 | - let appleStandHours: Double? = nilOrValue(pigeonVar_list[7]) | ||
| 274 | - let standHoursGoal: Double? = nilOrValue(pigeonVar_list[8]) | 268 | + let activityMoveMode: Int64? = nilOrValue(pigeonVar_list[1]) |
| 269 | + let activeEnergyBurned: Double? = nilOrValue(pigeonVar_list[2]) | ||
| 270 | + let activeEnergyBurnedGoal: Double? = nilOrValue(pigeonVar_list[3]) | ||
| 271 | + let appleMoveTime: Double? = nilOrValue(pigeonVar_list[4]) | ||
| 272 | + let appleMoveTimeGoal: Double? = nilOrValue(pigeonVar_list[5]) | ||
| 273 | + let appleExerciseTime: Double? = nilOrValue(pigeonVar_list[6]) | ||
| 274 | + let exerciseTimeGoal: Double? = nilOrValue(pigeonVar_list[7]) | ||
| 275 | + let appleStandHours: Double? = nilOrValue(pigeonVar_list[8]) | ||
| 276 | + let standHoursGoal: Double? = nilOrValue(pigeonVar_list[9]) | ||
| 275 | 277 | ||
| 276 | return HealthKitRawActivityDataPoint( | 278 | return HealthKitRawActivityDataPoint( |
| 277 | endTime: endTime, | 279 | endTime: endTime, |
| 280 | + activityMoveMode: activityMoveMode, | ||
| 278 | activeEnergyBurned: activeEnergyBurned, | 281 | activeEnergyBurned: activeEnergyBurned, |
| 279 | activeEnergyBurnedGoal: activeEnergyBurnedGoal, | 282 | activeEnergyBurnedGoal: activeEnergyBurnedGoal, |
| 280 | appleMoveTime: appleMoveTime, | 283 | appleMoveTime: appleMoveTime, |
| @@ -288,6 +291,7 @@ struct HealthKitRawActivityDataPoint: Hashable { | @@ -288,6 +291,7 @@ struct HealthKitRawActivityDataPoint: Hashable { | ||
| 288 | func toList() -> [Any?] { | 291 | func toList() -> [Any?] { |
| 289 | return [ | 292 | return [ |
| 290 | endTime, | 293 | endTime, |
| 294 | + activityMoveMode, | ||
| 291 | activeEnergyBurned, | 295 | activeEnergyBurned, |
| 292 | activeEnergyBurnedGoal, | 296 | activeEnergyBurnedGoal, |
| 293 | appleMoveTime, | 297 | appleMoveTime, |
| @@ -386,6 +390,16 @@ protocol HealthKitRawDataHostApi { | @@ -386,6 +390,16 @@ protocol HealthKitRawDataHostApi { | ||
| 386 | func getHealthKitRawActivityData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawActivityDataPoint], Error>) -> Void) | 390 | func getHealthKitRawActivityData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawActivityDataPoint], Error>) -> Void) |
| 387 | /// 从从AppleHealth中读取锻炼数据 | 391 | /// 从从AppleHealth中读取锻炼数据 |
| 388 | func getHealthKitRawWorkoutData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawWorkoutDataPoint], Error>) -> Void) | 392 | func getHealthKitRawWorkoutData(startTime: Int64, endTime: Int64, completion: @escaping (Result<[HealthKitRawWorkoutDataPoint], Error>) -> Void) |
| 393 | + /// 原生是否通知了flutter ,apple health数据变化,让native 记录这次调用记录 | ||
| 394 | + /// 需要保存引起此次计算的数据变化类型列表、当前时间 | ||
| 395 | + func saveNativeCallFlutterChange(relativeDataTypes: [Int64], completion: @escaping (Result<Bool, Error>) -> Void) | ||
| 396 | + /// caculate 一旦完成,让native 存储这次的计算记录 | ||
| 397 | + /// 需要保存引起此次计算的数据变化类型列表、当前时间 | ||
| 398 | + func saveFlutterCaculateFinished(relativeDataTypes: [Int64], completion: @escaping (Result<Bool, Error>) -> Void) | ||
| 399 | + /// 让原生分享出来本地的记录文件 | ||
| 400 | + func shareNativeAppleHealthObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void) | ||
| 401 | + /// 让原生分享出来flutter的记录文件 | ||
| 402 | + func shareFlutterObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void) | ||
| 389 | } | 403 | } |
| 390 | 404 | ||
| 391 | /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. | 405 | /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. |
| @@ -596,5 +610,75 @@ class HealthKitRawDataHostApiSetup { | @@ -596,5 +610,75 @@ class HealthKitRawDataHostApiSetup { | ||
| 596 | } else { | 610 | } else { |
| 597 | getHealthKitRawWorkoutDataChannel.setMessageHandler(nil) | 611 | getHealthKitRawWorkoutDataChannel.setMessageHandler(nil) |
| 598 | } | 612 | } |
| 613 | + /// 原生是否通知了flutter ,apple health数据变化,让native 记录这次调用记录 | ||
| 614 | + /// 需要保存引起此次计算的数据变化类型列表、当前时间 | ||
| 615 | + let saveNativeCallFlutterChangeChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.saveNativeCallFlutterChange\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) | ||
| 616 | + if let api = api { | ||
| 617 | + saveNativeCallFlutterChangeChannel.setMessageHandler { message, reply in | ||
| 618 | + let args = message as! [Any?] | ||
| 619 | + let relativeDataTypesArg = args[0] as! [Int64] | ||
| 620 | + api.saveNativeCallFlutterChange(relativeDataTypes: relativeDataTypesArg) { result in | ||
| 621 | + switch result { | ||
| 622 | + case .success(let res): | ||
| 623 | + reply(wrapResult(res)) | ||
| 624 | + case .failure(let error): | ||
| 625 | + reply(wrapError(error)) | ||
| 626 | + } | ||
| 627 | + } | ||
| 628 | + } | ||
| 629 | + } else { | ||
| 630 | + saveNativeCallFlutterChangeChannel.setMessageHandler(nil) | ||
| 631 | + } | ||
| 632 | + /// caculate 一旦完成,让native 存储这次的计算记录 | ||
| 633 | + /// 需要保存引起此次计算的数据变化类型列表、当前时间 | ||
| 634 | + let saveFlutterCaculateFinishedChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.saveFlutterCaculateFinished\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) | ||
| 635 | + if let api = api { | ||
| 636 | + saveFlutterCaculateFinishedChannel.setMessageHandler { message, reply in | ||
| 637 | + let args = message as! [Any?] | ||
| 638 | + let relativeDataTypesArg = args[0] as! [Int64] | ||
| 639 | + api.saveFlutterCaculateFinished(relativeDataTypes: relativeDataTypesArg) { result in | ||
| 640 | + switch result { | ||
| 641 | + case .success(let res): | ||
| 642 | + reply(wrapResult(res)) | ||
| 643 | + case .failure(let error): | ||
| 644 | + reply(wrapError(error)) | ||
| 645 | + } | ||
| 646 | + } | ||
| 647 | + } | ||
| 648 | + } else { | ||
| 649 | + saveFlutterCaculateFinishedChannel.setMessageHandler(nil) | ||
| 650 | + } | ||
| 651 | + /// 让原生分享出来本地的记录文件 | ||
| 652 | + let shareNativeAppleHealthObserverRecordChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareNativeAppleHealthObserverRecord\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) | ||
| 653 | + if let api = api { | ||
| 654 | + shareNativeAppleHealthObserverRecordChannel.setMessageHandler { _, reply in | ||
| 655 | + api.shareNativeAppleHealthObserverRecord { result in | ||
| 656 | + switch result { | ||
| 657 | + case .success(let res): | ||
| 658 | + reply(wrapResult(res)) | ||
| 659 | + case .failure(let error): | ||
| 660 | + reply(wrapError(error)) | ||
| 661 | + } | ||
| 662 | + } | ||
| 663 | + } | ||
| 664 | + } else { | ||
| 665 | + shareNativeAppleHealthObserverRecordChannel.setMessageHandler(nil) | ||
| 666 | + } | ||
| 667 | + /// 让原生分享出来flutter的记录文件 | ||
| 668 | + let shareFlutterObserverRecordChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareFlutterObserverRecord\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) | ||
| 669 | + if let api = api { | ||
| 670 | + shareFlutterObserverRecordChannel.setMessageHandler { _, reply in | ||
| 671 | + api.shareFlutterObserverRecord { result in | ||
| 672 | + switch result { | ||
| 673 | + case .success(let res): | ||
| 674 | + reply(wrapResult(res)) | ||
| 675 | + case .failure(let error): | ||
| 676 | + reply(wrapError(error)) | ||
| 677 | + } | ||
| 678 | + } | ||
| 679 | + } | ||
| 680 | + } else { | ||
| 681 | + shareFlutterObserverRecordChannel.setMessageHandler(nil) | ||
| 682 | + } | ||
| 599 | } | 683 | } |
| 600 | } | 684 | } |
| 1 | import Foundation | 1 | import Foundation |
| 2 | 2 | ||
| 3 | final class HealthKitRawDataHostApiImpl: HealthKitRawDataHostApi { | 3 | final class HealthKitRawDataHostApiImpl: HealthKitRawDataHostApi { |
| 4 | + func saveNativeCallFlutterChange(relativeDataTypes: [Int64], completion: @escaping (Result<Bool, any Error>) -> Void) { | ||
| 5 | + | ||
| 6 | + } | ||
| 7 | + | ||
| 8 | + func saveFlutterCaculateFinished(relativeDataTypes: [Int64], completion: @escaping (Result<Bool, any Error>) -> Void) { | ||
| 9 | + | ||
| 10 | + } | ||
| 11 | + | ||
| 12 | + func shareNativeAppleHealthObserverRecord(completion: @escaping (Result<Bool, any Error>) -> Void) { | ||
| 13 | + | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + func shareFlutterObserverRecord(completion: @escaping (Result<Bool, any Error>) -> Void) { | ||
| 17 | + | ||
| 18 | + } | ||
| 19 | + | ||
| 4 | private let service: HealthKitService | 20 | private let service: HealthKitService |
| 5 | 21 | ||
| 6 | init(service: HealthKitService = .shared) { | 22 | init(service: HealthKitService = .shared) { |
| @@ -229,6 +245,7 @@ final class HealthKitRawDataHostApiImpl: HealthKitRawDataHostApi { | @@ -229,6 +245,7 @@ final class HealthKitRawDataHostApiImpl: HealthKitRawDataHostApi { | ||
| 229 | } | 245 | } |
| 230 | return HealthKitRawActivityDataPoint( | 246 | return HealthKitRawActivityDataPoint( |
| 231 | endTime: Int64(endTime.rounded()), | 247 | endTime: Int64(endTime.rounded()), |
| 248 | + activityMoveMode: target.activityMoveMode == nil ? nil : Int64(target.activityMoveMode!), | ||
| 232 | activeEnergyBurned: target.activeEnergyBurned, | 249 | activeEnergyBurned: target.activeEnergyBurned, |
| 233 | activeEnergyBurnedGoal: target.activeEnergyBurnedGoal, | 250 | activeEnergyBurnedGoal: target.activeEnergyBurnedGoal, |
| 234 | appleMoveTime: target.appleMoveTime, | 251 | appleMoveTime: target.appleMoveTime, |
| @@ -490,7 +490,7 @@ class TodayController extends GetMaterialController { | @@ -490,7 +490,7 @@ class TodayController extends GetMaterialController { | ||
| 490 | case AppFailure(): | 490 | case AppFailure(): |
| 491 | stressChartData.clear(); | 491 | stressChartData.clear(); |
| 492 | } | 492 | } |
| 493 | - switch (await _healthApi.getV2ActivityTarget(friendUserId)) { | 493 | + switch (await _healthApi.getV2ActivityTarget(friendUserId, intDate)) { |
| 494 | case AppSuccess(:final data): | 494 | case AppSuccess(:final data): |
| 495 | v2ActivityTarget.value = data; | 495 | v2ActivityTarget.value = data; |
| 496 | case AppFailure(): | 496 | case AppFailure(): |
| @@ -703,6 +703,8 @@ class TodayController extends GetMaterialController { | @@ -703,6 +703,8 @@ class TodayController extends GetMaterialController { | ||
| 703 | checkAddFriendVisible(); | 703 | checkAddFriendVisible(); |
| 704 | checkHrvAdBannerVisible(); | 704 | checkHrvAdBannerVisible(); |
| 705 | checkHealthDataAuthCardVisible(); | 705 | checkHealthDataAuthCardVisible(); |
| 706 | + _performHealthDataUpload(); | ||
| 707 | + // _startCoreCaculate(); | ||
| 706 | // unawaited(loadDataForDate(selectedDate.value)); | 708 | // unawaited(loadDataForDate(selectedDate.value)); |
| 707 | } | 709 | } |
| 708 | } | 710 | } |
| @@ -718,6 +720,7 @@ class TodayController extends GetMaterialController { | @@ -718,6 +720,7 @@ class TodayController extends GetMaterialController { | ||
| 718 | checkAddFriendVisible(); | 720 | checkAddFriendVisible(); |
| 719 | checkHrvAdBannerVisible(); | 721 | checkHrvAdBannerVisible(); |
| 720 | checkHealthDataAuthCardVisible(isPullToRefresh: isPullToRefresh); | 722 | checkHealthDataAuthCardVisible(isPullToRefresh: isPullToRefresh); |
| 723 | + _performHealthDataUpload(); | ||
| 721 | // await loadDataForDate(selectedDate.value); | 724 | // await loadDataForDate(selectedDate.value); |
| 722 | } | 725 | } |
| 723 | } | 726 | } |
| @@ -51,6 +51,7 @@ abstract interface class HealthDataSource { | @@ -51,6 +51,7 @@ abstract interface class HealthDataSource { | ||
| 51 | 51 | ||
| 52 | Future<AppResult<V2ActivityTarget>> getV2ActivityTarget( | 52 | Future<AppResult<V2ActivityTarget>> getV2ActivityTarget( |
| 53 | int? queryUserId, | 53 | int? queryUserId, |
| 54 | + int intDate, | ||
| 54 | ); | 55 | ); |
| 55 | 56 | ||
| 56 | Future<AppResult<V2HealthEverUploaded>> getHealthDataEverUploaded(); | 57 | Future<AppResult<V2HealthEverUploaded>> getHealthDataEverUploaded(); |
| @@ -79,13 +79,14 @@ class HealthDataSourceWrapper implements HealthDataSource { | @@ -79,13 +79,14 @@ class HealthDataSourceWrapper implements HealthDataSource { | ||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | @override | 81 | @override |
| 82 | - Future<AppResult<V2ActivityTarget>> getV2ActivityTarget(int? queryUserId) { | 82 | + Future<AppResult<V2ActivityTarget>> getV2ActivityTarget( |
| 83 | + int? queryUserId, int initDate) { | ||
| 83 | HealthDataSource dataSource = remoteDataSource; | 84 | HealthDataSource dataSource = remoteDataSource; |
| 84 | if (queryUserId == null || _myUserId == queryUserId) { | 85 | if (queryUserId == null || _myUserId == queryUserId) { |
| 85 | dataSource = localDataSource; | 86 | dataSource = localDataSource; |
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | - return dataSource.getV2ActivityTarget(queryUserId); | 89 | + return dataSource.getV2ActivityTarget(queryUserId, initDate); |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | @override | 92 | @override |
| @@ -263,7 +263,7 @@ class LocalHealthDataConvert { | @@ -263,7 +263,7 @@ class LocalHealthDataConvert { | ||
| 263 | 263 | ||
| 264 | final data = ActivityBurnStatisticsDataV2( | 264 | final data = ActivityBurnStatisticsDataV2( |
| 265 | totalMove: _sum(daily.map((e) => e.move).toList()), | 265 | totalMove: _sum(daily.map((e) => e.move).toList()), |
| 266 | - totalSteps: _sum(daily.map((e) => e.steps).toList()), | 266 | + totalSteps: 0, |
| 267 | totalStand: _sum(daily.map((e) => e.standHours).toList()), | 267 | totalStand: _sum(daily.map((e) => e.standHours).toList()), |
| 268 | totalExercise: _sum(daily.map((e) => e.exerciseSeconds).toList()), | 268 | totalExercise: _sum(daily.map((e) => e.exerciseSeconds).toList()), |
| 269 | avgMove: _averageOrNull(daily.map((e) => e.move).toList()), | 269 | avgMove: _averageOrNull(daily.map((e) => e.move).toList()), |
| @@ -399,8 +399,8 @@ class LocalHealthDataConvert { | @@ -399,8 +399,8 @@ class LocalHealthDataConvert { | ||
| 399 | ); | 399 | ); |
| 400 | return V2ActivityTarget( | 400 | return V2ActivityTarget( |
| 401 | userId: userId, | 401 | userId: userId, |
| 402 | - move: latestWithGoal?.activeEnergyBurnedGoal?.round(), | ||
| 403 | - step: latestWithGoal?.appleMoveTimeGoal?.round(), | 402 | + move: latestWithGoal?.activeEnergyBurnedGoal?.ceil(), |
| 403 | + step: 0, | ||
| 404 | stand: latestWithGoal?.standHoursGoal?.round(), | 404 | stand: latestWithGoal?.standHoursGoal?.round(), |
| 405 | exercise: latestWithGoal?.exerciseTimeGoal == null | 405 | exercise: latestWithGoal?.exerciseTimeGoal == null |
| 406 | ? null | 406 | ? null |
| @@ -451,7 +451,7 @@ class LocalHealthDataConvert { | @@ -451,7 +451,7 @@ class LocalHealthDataConvert { | ||
| 451 | move: activitySummary.move.ceil(), | 451 | move: activitySummary.move.ceil(), |
| 452 | exercise: activitySummary.exerciseSeconds.round(), | 452 | exercise: activitySummary.exerciseSeconds.round(), |
| 453 | stand: activitySummary.standHours.round(), | 453 | stand: activitySummary.standHours.round(), |
| 454 | - steps: activitySummary.steps.round(), | 454 | + steps: 0, |
| 455 | sleepDuration: sleepSummary.durationSeconds.round(), | 455 | sleepDuration: sleepSummary.durationSeconds.round(), |
| 456 | sleepScore: sleepSummary.score?.toDouble(), | 456 | sleepScore: sleepSummary.score?.toDouble(), |
| 457 | sleepState: sleepSummary.state?.value, | 457 | sleepState: sleepSummary.state?.value, |
| @@ -496,7 +496,7 @@ class LocalHealthDataConvert { | @@ -496,7 +496,7 @@ class LocalHealthDataConvert { | ||
| 496 | move: activitySummary.move.ceil(), | 496 | move: activitySummary.move.ceil(), |
| 497 | exercise: activitySummary.exerciseSeconds.round(), | 497 | exercise: activitySummary.exerciseSeconds.round(), |
| 498 | stand: activitySummary.standHours.round(), | 498 | stand: activitySummary.standHours.round(), |
| 499 | - steps: activitySummary.steps.round(), | 499 | + steps: 0, |
| 500 | sleepDuration: sleepResult == null ? 0 : sleepResult.sleepMinutes * 60, | 500 | sleepDuration: sleepResult == null ? 0 : sleepResult.sleepMinutes * 60, |
| 501 | sleepScore: sleepResult?.sleepScore.toDouble(), | 501 | sleepScore: sleepResult?.sleepScore.toDouble(), |
| 502 | sleepState: sleepResult?.sleepStateValue, | 502 | sleepState: sleepResult?.sleepStateValue, |
| @@ -521,22 +521,14 @@ class LocalHealthDataConvert { | @@ -521,22 +521,14 @@ class LocalHealthDataConvert { | ||
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | static V2LatestHrvData v2LatestHrvData( | 523 | static V2LatestHrvData v2LatestHrvData( |
| 524 | - List<HealthRawHrvStressPoint> hrvPoints, { | ||
| 525 | - List<HealthRawHrvStressPoint> previousHrvPoints = | ||
| 526 | - const <HealthRawHrvStressPoint>[], | ||
| 527 | - }) { | 524 | + List<HealthRawHrvStressPoint> hrvPoints) { |
| 528 | final latest = _latestHrvByRawEndTime(hrvPoints); | 525 | final latest = _latestHrvByRawEndTime(hrvPoints); |
| 529 | return V2LatestHrvData( | 526 | return V2LatestHrvData( |
| 530 | latestHrv: (latest?.result ?? 0).floor().toDouble(), | 527 | latestHrv: (latest?.result ?? 0).floor().toDouble(), |
| 531 | latestDataTime: latest?.rawEndTime, | 528 | latestDataTime: latest?.rawEndTime, |
| 532 | state: latest?.state.value, | 529 | state: latest?.state.value, |
| 533 | tip: _latestHrvTip( | 530 | tip: _latestHrvTip( |
| 534 | - latest: latest, | ||
| 535 | - previous: _previousHrvPoint( | ||
| 536 | - latest: latest, | ||
| 537 | - hrvPoints: hrvPoints, | ||
| 538 | - previousHrvPoints: previousHrvPoints, | ||
| 539 | - ), | 531 | + latest: latest |
| 540 | ), | 532 | ), |
| 541 | ); | 533 | ); |
| 542 | } | 534 | } |
| @@ -581,13 +573,11 @@ class LocalHealthDataConvert { | @@ -581,13 +573,11 @@ class LocalHealthDataConvert { | ||
| 581 | final latest = dayActivity.isEmpty ? null : dayActivity.last; | 573 | final latest = dayActivity.isEmpty ? null : dayActivity.last; |
| 582 | return _ActivityDaySummary( | 574 | return _ActivityDaySummary( |
| 583 | day: day, | 575 | day: day, |
| 584 | - move: latest?.activeEnergyBurned ?? 0, | ||
| 585 | - steps: latest?.appleMoveTime ?? 0, | 576 | + move: (latest?.activeEnergyBurned ?? 0).ceil(), |
| 586 | standHours: latest?.appleStandHours ?? 0, | 577 | standHours: latest?.appleStandHours ?? 0, |
| 587 | exerciseSeconds: latest?.appleExerciseTime ?? 0, | 578 | exerciseSeconds: latest?.appleExerciseTime ?? 0, |
| 588 | - moveGoal: latest?.activeEnergyBurnedGoal, | ||
| 589 | - stepGoal: latest?.appleMoveTimeGoal, | ||
| 590 | - standGoal: latest?.standHoursGoal, | 579 | + moveGoal: latest?.activeEnergyBurnedGoal ?? 480, |
| 580 | + standGoal: latest?.standHoursGoal ?? 8, | ||
| 591 | exerciseGoalSeconds: latest?.exerciseTimeGoal, | 581 | exerciseGoalSeconds: latest?.exerciseTimeGoal, |
| 592 | ); | 582 | ); |
| 593 | } | 583 | } |
| @@ -627,11 +617,9 @@ class LocalHealthDataConvert { | @@ -627,11 +617,9 @@ class LocalHealthDataConvert { | ||
| 627 | } | 617 | } |
| 628 | 618 | ||
| 629 | static String? _latestHrvTip({ | 619 | static String? _latestHrvTip({ |
| 630 | - required HealthRawHrvStressPoint? latest, | ||
| 631 | - required HealthRawHrvStressPoint? previous, | 620 | + required HealthRawHrvStressPoint? latest |
| 632 | }) { | 621 | }) { |
| 633 | - if (latest == null || previous == null) return null; | ||
| 634 | - if (latest.rawEndTime - previous.rawEndTime < 2 * 60 * 60) return null; | 622 | + if (latest == null) return null; |
| 635 | 623 | ||
| 636 | final isAboveBaseline = latest.result >= latest.baselineHrv; | 624 | final isAboveBaseline = latest.result >= latest.baselineHrv; |
| 637 | return switch (latest.state) { | 625 | return switch (latest.state) { |
| @@ -665,7 +653,7 @@ class LocalHealthDataConvert { | @@ -665,7 +653,7 @@ class LocalHealthDataConvert { | ||
| 665 | if (summary == null || !summary.hasGoal) return null; | 653 | if (summary == null || !summary.hasGoal) return null; |
| 666 | return ActivityTargetInfo( | 654 | return ActivityTargetInfo( |
| 667 | move: summary.moveGoal, | 655 | move: summary.moveGoal, |
| 668 | - step: summary.stepGoal, | 656 | + step: 0, |
| 669 | stand: summary.standGoal, | 657 | stand: summary.standGoal, |
| 670 | exercise: summary.exerciseGoalSeconds, | 658 | exercise: summary.exerciseGoalSeconds, |
| 671 | ); | 659 | ); |
| @@ -963,28 +951,23 @@ class _ActivityDaySummary { | @@ -963,28 +951,23 @@ class _ActivityDaySummary { | ||
| 963 | const _ActivityDaySummary({ | 951 | const _ActivityDaySummary({ |
| 964 | required this.day, | 952 | required this.day, |
| 965 | required this.move, | 953 | required this.move, |
| 966 | - required this.steps, | ||
| 967 | required this.standHours, | 954 | required this.standHours, |
| 968 | required this.exerciseSeconds, | 955 | required this.exerciseSeconds, |
| 969 | required this.moveGoal, | 956 | required this.moveGoal, |
| 970 | - required this.stepGoal, | ||
| 971 | required this.standGoal, | 957 | required this.standGoal, |
| 972 | required this.exerciseGoalSeconds, | 958 | required this.exerciseGoalSeconds, |
| 973 | }); | 959 | }); |
| 974 | 960 | ||
| 975 | final DateTime day; | 961 | final DateTime day; |
| 976 | final num move; | 962 | final num move; |
| 977 | - final num steps; | ||
| 978 | final num standHours; | 963 | final num standHours; |
| 979 | final num exerciseSeconds; | 964 | final num exerciseSeconds; |
| 980 | final num? moveGoal; | 965 | final num? moveGoal; |
| 981 | - final num? stepGoal; | ||
| 982 | final num? standGoal; | 966 | final num? standGoal; |
| 983 | final num? exerciseGoalSeconds; | 967 | final num? exerciseGoalSeconds; |
| 984 | 968 | ||
| 985 | bool get hasGoal => | 969 | bool get hasGoal => |
| 986 | moveGoal != null || | 970 | moveGoal != null || |
| 987 | - stepGoal != null || | ||
| 988 | standGoal != null || | 971 | standGoal != null || |
| 989 | exerciseGoalSeconds != null; | 972 | exerciseGoalSeconds != null; |
| 990 | } | 973 | } |
| @@ -160,21 +160,20 @@ class LocalHealthDataSource implements HealthDataSource { | @@ -160,21 +160,20 @@ class LocalHealthDataSource implements HealthDataSource { | ||
| 160 | 160 | ||
| 161 | @override | 161 | @override |
| 162 | Future<AppResult<V2ActivityTarget>> getV2ActivityTarget( | 162 | Future<AppResult<V2ActivityTarget>> getV2ActivityTarget( |
| 163 | - int? queryUserId) async { | 163 | + int? queryUserId, int intDate) async { |
| 164 | try { | 164 | try { |
| 165 | - final now = DateTime.now(); | ||
| 166 | - final queryStart = LocalHealthDataConvert.unixSeconds( | ||
| 167 | - now.subtract( | ||
| 168 | - const Duration(days: HealthRawDataCoreService.defaultLookbackDays)), | 165 | + final day = LocalHealthDataConvert.dateFromKey(intDate); |
| 166 | + final queryStart = LocalHealthDataConvert.unixSeconds(day); | ||
| 167 | + final queryEnd = LocalHealthDataConvert.unixSeconds( | ||
| 168 | + day.add(const Duration(days: 1)), | ||
| 169 | ); | 169 | ); |
| 170 | - final queryEnd = LocalHealthDataConvert.unixSeconds(now); | ||
| 171 | final activity = await coreService.queryRawActivitySummaries( | 170 | final activity = await coreService.queryRawActivitySummaries( |
| 172 | startTime: queryStart, | 171 | startTime: queryStart, |
| 173 | endTime: queryEnd, | 172 | endTime: queryEnd, |
| 174 | ); | 173 | ); |
| 175 | return AppSuccess( | 174 | return AppSuccess( |
| 176 | LocalHealthDataConvert.v2ActivityTarget( | 175 | LocalHealthDataConvert.v2ActivityTarget( |
| 177 | - userId: 0, | 176 | + userId: queryUserId ?? 0, |
| 178 | activity: activity, | 177 | activity: activity, |
| 179 | ), | 178 | ), |
| 180 | ); | 179 | ); |
| @@ -249,21 +248,12 @@ class LocalHealthDataSource implements HealthDataSource { | @@ -249,21 +248,12 @@ class LocalHealthDataSource implements HealthDataSource { | ||
| 249 | int? queryUserId, int intDate) async { | 248 | int? queryUserId, int intDate) async { |
| 250 | try { | 249 | try { |
| 251 | final (startTime, endTime) = _dayRange(intDate); | 250 | final (startTime, endTime) = _dayRange(intDate); |
| 252 | - final previousStartTime = startTime - | ||
| 253 | - HealthRawDataCoreService.defaultLookbackDays * Duration.secondsPerDay; | ||
| 254 | - final previousHrvPoints = await coreService.queryHrvStressPoints( | ||
| 255 | - startTime: previousStartTime, | ||
| 256 | - endTime: startTime - 1, | ||
| 257 | - ); | ||
| 258 | final hrvPoints = await coreService.queryHrvStressPoints( | 251 | final hrvPoints = await coreService.queryHrvStressPoints( |
| 259 | startTime: startTime, | 252 | startTime: startTime, |
| 260 | endTime: endTime, | 253 | endTime: endTime, |
| 261 | ); | 254 | ); |
| 262 | return AppSuccess( | 255 | return AppSuccess( |
| 263 | - LocalHealthDataConvert.v2LatestHrvData( | ||
| 264 | - hrvPoints, | ||
| 265 | - previousHrvPoints: previousHrvPoints, | ||
| 266 | - ), | 256 | + LocalHealthDataConvert.v2LatestHrvData(hrvPoints), |
| 267 | ); | 257 | ); |
| 268 | } catch (error) { | 258 | } catch (error) { |
| 269 | return AppFailure(AppUnknownError(error)); | 259 | return AppFailure(AppUnknownError(error)); |
| @@ -95,6 +95,7 @@ class RemoteHealthDataSource implements HealthDataSource { | @@ -95,6 +95,7 @@ class RemoteHealthDataSource implements HealthDataSource { | ||
| 95 | @override | 95 | @override |
| 96 | Future<AppResult<V2ActivityTarget>> getV2ActivityTarget( | 96 | Future<AppResult<V2ActivityTarget>> getV2ActivityTarget( |
| 97 | int? queryUserId, | 97 | int? queryUserId, |
| 98 | + int initDate, | ||
| 98 | ) { | 99 | ) { |
| 99 | return _healthApi.getV2ActivityTarget(queryUserId); | 100 | return _healthApi.getV2ActivityTarget(queryUserId); |
| 100 | } | 101 | } |
| @@ -242,6 +242,7 @@ class HealthKitRawMotionDataPoint { | @@ -242,6 +242,7 @@ class HealthKitRawMotionDataPoint { | ||
| 242 | class HealthKitRawActivityDataPoint { | 242 | class HealthKitRawActivityDataPoint { |
| 243 | HealthKitRawActivityDataPoint({ | 243 | HealthKitRawActivityDataPoint({ |
| 244 | required this.endTime, | 244 | required this.endTime, |
| 245 | + this.activityMoveMode, | ||
| 245 | this.activeEnergyBurned, | 246 | this.activeEnergyBurned, |
| 246 | this.activeEnergyBurnedGoal, | 247 | this.activeEnergyBurnedGoal, |
| 247 | this.appleMoveTime, | 248 | this.appleMoveTime, |
| @@ -254,6 +255,8 @@ class HealthKitRawActivityDataPoint { | @@ -254,6 +255,8 @@ class HealthKitRawActivityDataPoint { | ||
| 254 | 255 | ||
| 255 | int endTime; | 256 | int endTime; |
| 256 | 257 | ||
| 258 | + int? activityMoveMode; | ||
| 259 | + | ||
| 257 | double? activeEnergyBurned; | 260 | double? activeEnergyBurned; |
| 258 | 261 | ||
| 259 | double? activeEnergyBurnedGoal; | 262 | double? activeEnergyBurnedGoal; |
| @@ -273,6 +276,7 @@ class HealthKitRawActivityDataPoint { | @@ -273,6 +276,7 @@ class HealthKitRawActivityDataPoint { | ||
| 273 | List<Object?> _toList() { | 276 | List<Object?> _toList() { |
| 274 | return <Object?>[ | 277 | return <Object?>[ |
| 275 | endTime, | 278 | endTime, |
| 279 | + activityMoveMode, | ||
| 276 | activeEnergyBurned, | 280 | activeEnergyBurned, |
| 277 | activeEnergyBurnedGoal, | 281 | activeEnergyBurnedGoal, |
| 278 | appleMoveTime, | 282 | appleMoveTime, |
| @@ -291,14 +295,15 @@ class HealthKitRawActivityDataPoint { | @@ -291,14 +295,15 @@ class HealthKitRawActivityDataPoint { | ||
| 291 | result as List<Object?>; | 295 | result as List<Object?>; |
| 292 | return HealthKitRawActivityDataPoint( | 296 | return HealthKitRawActivityDataPoint( |
| 293 | endTime: result[0]! as int, | 297 | endTime: result[0]! as int, |
| 294 | - activeEnergyBurned: result[1] as double?, | ||
| 295 | - activeEnergyBurnedGoal: result[2] as double?, | ||
| 296 | - appleMoveTime: result[3] as double?, | ||
| 297 | - appleMoveTimeGoal: result[4] as double?, | ||
| 298 | - appleExerciseTime: result[5] as double?, | ||
| 299 | - exerciseTimeGoal: result[6] as double?, | ||
| 300 | - appleStandHours: result[7] as double?, | ||
| 301 | - standHoursGoal: result[8] as double?, | 298 | + activityMoveMode: result[1] as int?, |
| 299 | + activeEnergyBurned: result[2] as double?, | ||
| 300 | + activeEnergyBurnedGoal: result[3] as double?, | ||
| 301 | + appleMoveTime: result[4] as double?, | ||
| 302 | + appleMoveTimeGoal: result[5] as double?, | ||
| 303 | + appleExerciseTime: result[6] as double?, | ||
| 304 | + exerciseTimeGoal: result[7] as double?, | ||
| 305 | + appleStandHours: result[8] as double?, | ||
| 306 | + standHoursGoal: result[9] as double?, | ||
| 302 | ); | 307 | ); |
| 303 | } | 308 | } |
| 304 | 309 | ||
| @@ -698,4 +703,122 @@ class HealthKitRawDataHostApi { | @@ -698,4 +703,122 @@ class HealthKitRawDataHostApi { | ||
| 698 | return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawWorkoutDataPoint>(); | 703 | return (pigeonVar_replyList[0] as List<Object?>?)!.cast<HealthKitRawWorkoutDataPoint>(); |
| 699 | } | 704 | } |
| 700 | } | 705 | } |
| 706 | + | ||
| 707 | + /// 原生是否通知了flutter ,apple health数据变化,让native 记录这次调用记录 | ||
| 708 | + /// 需要保存引起此次计算的数据变化类型列表、当前时间 | ||
| 709 | + Future<bool> saveNativeCallFlutterChange({List<int> relativeDataTypes}) async { | ||
| 710 | + final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.saveNativeCallFlutterChange$pigeonVar_messageChannelSuffix'; | ||
| 711 | + final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>( | ||
| 712 | + pigeonVar_channelName, | ||
| 713 | + pigeonChannelCodec, | ||
| 714 | + binaryMessenger: pigeonVar_binaryMessenger, | ||
| 715 | + ); | ||
| 716 | + final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[relativeDataTypes]); | ||
| 717 | + final List<Object?>? pigeonVar_replyList = | ||
| 718 | + await pigeonVar_sendFuture as List<Object?>?; | ||
| 719 | + if (pigeonVar_replyList == null) { | ||
| 720 | + throw _createConnectionError(pigeonVar_channelName); | ||
| 721 | + } else if (pigeonVar_replyList.length > 1) { | ||
| 722 | + throw PlatformException( | ||
| 723 | + code: pigeonVar_replyList[0]! as String, | ||
| 724 | + message: pigeonVar_replyList[1] as String?, | ||
| 725 | + details: pigeonVar_replyList[2], | ||
| 726 | + ); | ||
| 727 | + } else if (pigeonVar_replyList[0] == null) { | ||
| 728 | + throw PlatformException( | ||
| 729 | + code: 'null-error', | ||
| 730 | + message: 'Host platform returned null value for non-null return value.', | ||
| 731 | + ); | ||
| 732 | + } else { | ||
| 733 | + return (pigeonVar_replyList[0] as bool?)!; | ||
| 734 | + } | ||
| 735 | + } | ||
| 736 | + | ||
| 737 | + /// caculate 一旦完成,让native 存储这次的计算记录 | ||
| 738 | + /// 需要保存引起此次计算的数据变化类型列表、当前时间 | ||
| 739 | + Future<bool> saveFlutterCaculateFinished({List<int> relativeDataTypes}) async { | ||
| 740 | + final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.saveFlutterCaculateFinished$pigeonVar_messageChannelSuffix'; | ||
| 741 | + final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>( | ||
| 742 | + pigeonVar_channelName, | ||
| 743 | + pigeonChannelCodec, | ||
| 744 | + binaryMessenger: pigeonVar_binaryMessenger, | ||
| 745 | + ); | ||
| 746 | + final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[relativeDataTypes]); | ||
| 747 | + final List<Object?>? pigeonVar_replyList = | ||
| 748 | + await pigeonVar_sendFuture as List<Object?>?; | ||
| 749 | + if (pigeonVar_replyList == null) { | ||
| 750 | + throw _createConnectionError(pigeonVar_channelName); | ||
| 751 | + } else if (pigeonVar_replyList.length > 1) { | ||
| 752 | + throw PlatformException( | ||
| 753 | + code: pigeonVar_replyList[0]! as String, | ||
| 754 | + message: pigeonVar_replyList[1] as String?, | ||
| 755 | + details: pigeonVar_replyList[2], | ||
| 756 | + ); | ||
| 757 | + } else if (pigeonVar_replyList[0] == null) { | ||
| 758 | + throw PlatformException( | ||
| 759 | + code: 'null-error', | ||
| 760 | + message: 'Host platform returned null value for non-null return value.', | ||
| 761 | + ); | ||
| 762 | + } else { | ||
| 763 | + return (pigeonVar_replyList[0] as bool?)!; | ||
| 764 | + } | ||
| 765 | + } | ||
| 766 | + | ||
| 767 | + /// 让原生分享出来本地的记录文件 | ||
| 768 | + Future<bool> shareNativeAppleHealthObserverRecord() async { | ||
| 769 | + final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareNativeAppleHealthObserverRecord$pigeonVar_messageChannelSuffix'; | ||
| 770 | + final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>( | ||
| 771 | + pigeonVar_channelName, | ||
| 772 | + pigeonChannelCodec, | ||
| 773 | + binaryMessenger: pigeonVar_binaryMessenger, | ||
| 774 | + ); | ||
| 775 | + final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null); | ||
| 776 | + final List<Object?>? pigeonVar_replyList = | ||
| 777 | + await pigeonVar_sendFuture as List<Object?>?; | ||
| 778 | + if (pigeonVar_replyList == null) { | ||
| 779 | + throw _createConnectionError(pigeonVar_channelName); | ||
| 780 | + } else if (pigeonVar_replyList.length > 1) { | ||
| 781 | + throw PlatformException( | ||
| 782 | + code: pigeonVar_replyList[0]! as String, | ||
| 783 | + message: pigeonVar_replyList[1] as String?, | ||
| 784 | + details: pigeonVar_replyList[2], | ||
| 785 | + ); | ||
| 786 | + } else if (pigeonVar_replyList[0] == null) { | ||
| 787 | + throw PlatformException( | ||
| 788 | + code: 'null-error', | ||
| 789 | + message: 'Host platform returned null value for non-null return value.', | ||
| 790 | + ); | ||
| 791 | + } else { | ||
| 792 | + return (pigeonVar_replyList[0] as bool?)!; | ||
| 793 | + } | ||
| 794 | + } | ||
| 795 | + | ||
| 796 | + /// 让原生分享出来flutter的记录文件 | ||
| 797 | + Future<bool> shareFlutterObserverRecord() async { | ||
| 798 | + final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareFlutterObserverRecord$pigeonVar_messageChannelSuffix'; | ||
| 799 | + final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>( | ||
| 800 | + pigeonVar_channelName, | ||
| 801 | + pigeonChannelCodec, | ||
| 802 | + binaryMessenger: pigeonVar_binaryMessenger, | ||
| 803 | + ); | ||
| 804 | + final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null); | ||
| 805 | + final List<Object?>? pigeonVar_replyList = | ||
| 806 | + await pigeonVar_sendFuture as List<Object?>?; | ||
| 807 | + if (pigeonVar_replyList == null) { | ||
| 808 | + throw _createConnectionError(pigeonVar_channelName); | ||
| 809 | + } else if (pigeonVar_replyList.length > 1) { | ||
| 810 | + throw PlatformException( | ||
| 811 | + code: pigeonVar_replyList[0]! as String, | ||
| 812 | + message: pigeonVar_replyList[1] as String?, | ||
| 813 | + details: pigeonVar_replyList[2], | ||
| 814 | + ); | ||
| 815 | + } else if (pigeonVar_replyList[0] == null) { | ||
| 816 | + throw PlatformException( | ||
| 817 | + code: 'null-error', | ||
| 818 | + message: 'Host platform returned null value for non-null return value.', | ||
| 819 | + ); | ||
| 820 | + } else { | ||
| 821 | + return (pigeonVar_replyList[0] as bool?)!; | ||
| 822 | + } | ||
| 823 | + } | ||
| 701 | } | 824 | } |
| @@ -51,6 +51,8 @@ class HealthKitRawMotionDataPoint { | @@ -51,6 +51,8 @@ class HealthKitRawMotionDataPoint { | ||
| 51 | 51 | ||
| 52 | class HealthKitRawActivityDataPoint { | 52 | class HealthKitRawActivityDataPoint { |
| 53 | int endTime; | 53 | int endTime; |
| 54 | + | ||
| 55 | + int? activityMoveMode; | ||
| 54 | // 千卡 | 56 | // 千卡 |
| 55 | double? activeEnergyBurned; | 57 | double? activeEnergyBurned; |
| 56 | double? activeEnergyBurnedGoal; | 58 | double? activeEnergyBurnedGoal; |
| @@ -66,6 +68,7 @@ class HealthKitRawActivityDataPoint { | @@ -66,6 +68,7 @@ class HealthKitRawActivityDataPoint { | ||
| 66 | 68 | ||
| 67 | HealthKitRawActivityDataPoint({ | 69 | HealthKitRawActivityDataPoint({ |
| 68 | required this.endTime, | 70 | required this.endTime, |
| 71 | + this.activityMoveMode, | ||
| 69 | this.activeEnergyBurned, | 72 | this.activeEnergyBurned, |
| 70 | this.activeEnergyBurnedGoal, | 73 | this.activeEnergyBurnedGoal, |
| 71 | this.appleMoveTime, | 74 | this.appleMoveTime, |
| @@ -140,4 +143,23 @@ abstract class HealthKitRawDataHostApi { | @@ -140,4 +143,23 @@ abstract class HealthKitRawDataHostApi { | ||
| 140 | @async | 143 | @async |
| 141 | List<HealthKitRawWorkoutDataPoint> getHealthKitRawWorkoutData( | 144 | List<HealthKitRawWorkoutDataPoint> getHealthKitRawWorkoutData( |
| 142 | int startTime, int endTime); | 145 | int startTime, int endTime); |
| 146 | + | ||
| 147 | +// DEBUG | ||
| 148 | + /// 原生是否通知了flutter ,apple health数据变化,让native 记录这次调用记录 | ||
| 149 | + /// 需要保存引起此次计算的数据变化类型列表、当前时间 | ||
| 150 | + @async | ||
| 151 | + bool saveNativeCallFlutterChange({List<int> relativeDataTypes}); | ||
| 152 | + | ||
| 153 | + /// caculate 一旦完成,让native 存储这次的计算记录 | ||
| 154 | + /// 需要保存引起此次计算的数据变化类型列表、当前时间 | ||
| 155 | + @async | ||
| 156 | + bool saveFlutterCaculateFinished({List<int> relativeDataTypes}); | ||
| 157 | + | ||
| 158 | + /// 让原生分享出来本地的记录文件 | ||
| 159 | + @async | ||
| 160 | + bool shareNativeAppleHealthObserverRecord(); | ||
| 161 | + | ||
| 162 | + /// 让原生分享出来flutter的记录文件 | ||
| 163 | + @async | ||
| 164 | + bool shareFlutterObserverRecord(); | ||
| 143 | } | 165 | } |
| @@ -447,6 +447,7 @@ void main() { | @@ -447,6 +447,7 @@ void main() { | ||
| 447 | final activity = [ | 447 | final activity = [ |
| 448 | HealthKitRawActivityDataPoint( | 448 | HealthKitRawActivityDataPoint( |
| 449 | endTime: endTime, | 449 | endTime: endTime, |
| 450 | + activityMoveMode: 0, | ||
| 450 | activeEnergyBurned: 300, | 451 | activeEnergyBurned: 300, |
| 451 | activeEnergyBurnedGoal: 500, | 452 | activeEnergyBurnedGoal: 500, |
| 452 | appleMoveTime: 8000, | 453 | appleMoveTime: 8000, |
| @@ -502,14 +503,6 @@ void main() { | @@ -502,14 +503,6 @@ void main() { | ||
| 502 | state: HealthRawStressState.excellent, | 503 | state: HealthRawStressState.excellent, |
| 503 | ), | 504 | ), |
| 504 | ], | 505 | ], |
| 505 | - previousHrvPoints: [ | ||
| 506 | - _hrvStressPoint( | ||
| 507 | - rawEndTime: latestTime - 2 * 60 * 60, | ||
| 508 | - result: 28, | ||
| 509 | - baselineHrv: 30, | ||
| 510 | - state: HealthRawStressState.normal, | ||
| 511 | - ), | ||
| 512 | - ], | ||
| 513 | ); | 506 | ); |
| 514 | 507 | ||
| 515 | expect(data.latestHrv, 35); | 508 | expect(data.latestHrv, 35); |
| @@ -528,9 +521,6 @@ void main() { | @@ -528,9 +521,6 @@ void main() { | ||
| 528 | state: HealthRawStressState.attention, | 521 | state: HealthRawStressState.attention, |
| 529 | ), | 522 | ), |
| 530 | ], | 523 | ], |
| 531 | - previousHrvPoints: [ | ||
| 532 | - _hrvStressPoint(rawEndTime: latestTime - 3 * 60 * 60), | ||
| 533 | - ], | ||
| 534 | ); | 524 | ); |
| 535 | 525 | ||
| 536 | expect(data.tip, contains('明显低于日常水平')); | 526 | expect(data.tip, contains('明显低于日常水平')); |
| @@ -548,9 +538,6 @@ void main() { | @@ -548,9 +538,6 @@ void main() { | ||
| 548 | state: HealthRawStressState.excellent, | 538 | state: HealthRawStressState.excellent, |
| 549 | ), | 539 | ), |
| 550 | ], | 540 | ], |
| 551 | - previousHrvPoints: [ | ||
| 552 | - _hrvStressPoint(rawEndTime: latestTime - 60 * 60), | ||
| 553 | - ], | ||
| 554 | ); | 541 | ); |
| 555 | 542 | ||
| 556 | expect(data.tip, isNull); | 543 | expect(data.tip, isNull); |
-
Please register or login to post a comment