Showing
6 changed files
with
110 additions
and
1 deletions
| @@ -400,6 +400,8 @@ protocol HealthKitRawDataHostApi { | @@ -400,6 +400,8 @@ protocol HealthKitRawDataHostApi { | ||
| 400 | func shareNativeAppleHealthObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void) | 400 | func shareNativeAppleHealthObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void) |
| 401 | /// 让原生分享出来flutter的记录文件 | 401 | /// 让原生分享出来flutter的记录文件 |
| 402 | func shareFlutterObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void) | 402 | func shareFlutterObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void) |
| 403 | + /// 让原生分享出来上传记录 | ||
| 404 | + func shareUploadTaskRecord(completion: @escaping (Result<Bool, Error>) -> Void) | ||
| 403 | } | 405 | } |
| 404 | 406 | ||
| 405 | /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. | 407 | /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. |
| @@ -680,5 +682,21 @@ class HealthKitRawDataHostApiSetup { | @@ -680,5 +682,21 @@ class HealthKitRawDataHostApiSetup { | ||
| 680 | } else { | 682 | } else { |
| 681 | shareFlutterObserverRecordChannel.setMessageHandler(nil) | 683 | shareFlutterObserverRecordChannel.setMessageHandler(nil) |
| 682 | } | 684 | } |
| 685 | + /// 让原生分享出来上传记录 | ||
| 686 | + let shareUploadTaskRecordChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareUploadTaskRecord\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) | ||
| 687 | + if let api = api { | ||
| 688 | + shareUploadTaskRecordChannel.setMessageHandler { _, reply in | ||
| 689 | + api.shareUploadTaskRecord { result in | ||
| 690 | + switch result { | ||
| 691 | + case .success(let res): | ||
| 692 | + reply(wrapResult(res)) | ||
| 693 | + case .failure(let error): | ||
| 694 | + reply(wrapError(error)) | ||
| 695 | + } | ||
| 696 | + } | ||
| 697 | + } | ||
| 698 | + } else { | ||
| 699 | + shareUploadTaskRecordChannel.setMessageHandler(nil) | ||
| 700 | + } | ||
| 683 | } | 701 | } |
| 684 | } | 702 | } |
| @@ -24,6 +24,7 @@ enum DeveloperOptionsAction { | @@ -24,6 +24,7 @@ enum DeveloperOptionsAction { | ||
| 24 | shareHealthRawUploadLog, | 24 | shareHealthRawUploadLog, |
| 25 | shareNativeAppleHealthObserverRecord, | 25 | shareNativeAppleHealthObserverRecord, |
| 26 | shareFlutterObserverRecord, | 26 | shareFlutterObserverRecord, |
| 27 | + shareUploadTaskRecord, | ||
| 27 | clearHealthRawDataDatabaseAndUploadLog, | 28 | clearHealthRawDataDatabaseAndUploadLog, |
| 28 | } | 29 | } |
| 29 | 30 | ||
| @@ -68,6 +69,10 @@ class DeveloperOptionsController extends GetxController { | @@ -68,6 +69,10 @@ class DeveloperOptionsController extends GetxController { | ||
| 68 | action: DeveloperOptionsAction.shareFlutterObserverRecord, | 69 | action: DeveloperOptionsAction.shareFlutterObserverRecord, |
| 69 | ), | 70 | ), |
| 70 | DeveloperOptionsItem( | 71 | DeveloperOptionsItem( |
| 72 | + title: '分享上传Task日志', | ||
| 73 | + action: DeveloperOptionsAction.shareUploadTaskRecord, | ||
| 74 | + ), | ||
| 75 | + DeveloperOptionsItem( | ||
| 71 | title: '清除本地数据库、上传日志', | 76 | title: '清除本地数据库、上传日志', |
| 72 | action: DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog, | 77 | action: DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog, |
| 73 | ), | 78 | ), |
| @@ -99,6 +104,9 @@ class DeveloperOptionsController extends GetxController { | @@ -99,6 +104,9 @@ class DeveloperOptionsController extends GetxController { | ||
| 99 | case DeveloperOptionsAction.shareFlutterObserverRecord: | 104 | case DeveloperOptionsAction.shareFlutterObserverRecord: |
| 100 | await shareFlutterObserverRecord(); | 105 | await shareFlutterObserverRecord(); |
| 101 | break; | 106 | break; |
| 107 | + case DeveloperOptionsAction.shareUploadTaskRecord: | ||
| 108 | + await shareUploadTaskRecord(); | ||
| 109 | + break; | ||
| 102 | case DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog: | 110 | case DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog: |
| 103 | await clearHealthRawDataDatabaseAndUploadLog(); | 111 | await clearHealthRawDataDatabaseAndUploadLog(); |
| 104 | break; | 112 | break; |
| @@ -153,6 +161,19 @@ class DeveloperOptionsController extends GetxController { | @@ -153,6 +161,19 @@ class DeveloperOptionsController extends GetxController { | ||
| 153 | } | 161 | } |
| 154 | } | 162 | } |
| 155 | 163 | ||
| 164 | + Future<void> shareUploadTaskRecord() async { | ||
| 165 | + try { | ||
| 166 | + await _healthRawDataCoreService.shareUploadTaskRecord(); | ||
| 167 | + } catch (error, stackTrace) { | ||
| 168 | + AppLogger.e( | ||
| 169 | + 'Share upload task record failed', | ||
| 170 | + error, | ||
| 171 | + stackTrace, | ||
| 172 | + ); | ||
| 173 | + Get.snackbar('Share failed', error.toString()); | ||
| 174 | + } | ||
| 175 | + } | ||
| 176 | + | ||
| 156 | Future<void> clearHealthRawDataDatabaseAndUploadLog() async { | 177 | Future<void> clearHealthRawDataDatabaseAndUploadLog() async { |
| 157 | try { | 178 | try { |
| 158 | await _healthRawDataCoreService.clearLocalDatabaseAndUploadLog(); | 179 | await _healthRawDataCoreService.clearLocalDatabaseAndUploadLog(); |
| @@ -172,6 +172,11 @@ class HealthRawDataCoreService { | @@ -172,6 +172,11 @@ class HealthRawDataCoreService { | ||
| 172 | return _rawDataApi.shareFlutterObserverRecord(); | 172 | return _rawDataApi.shareFlutterObserverRecord(); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | + Future<bool> shareUploadTaskRecord() async { | ||
| 176 | + if (!_isDebug) return false; | ||
| 177 | + return _rawDataApi.shareUploadTaskRecord(); | ||
| 178 | + } | ||
| 179 | + | ||
| 175 | Future<HealthRawStressCalculationResult> startCoreCaculate({ | 180 | Future<HealthRawStressCalculationResult> startCoreCaculate({ |
| 176 | int? endTime, | 181 | int? endTime, |
| 177 | int readChunkDays = defaultReadChunkDays, | 182 | int readChunkDays = defaultReadChunkDays, |
| @@ -38,7 +38,18 @@ Future<void> healthBackgroundMain() async { | @@ -38,7 +38,18 @@ Future<void> healthBackgroundMain() async { | ||
| 38 | WidgetsFlutterBinding.ensureInitialized(); | 38 | WidgetsFlutterBinding.ensureInitialized(); |
| 39 | const channel = MethodChannel('doublefeel_flutter_health_background_channel'); | 39 | const channel = MethodChannel('doublefeel_flutter_health_background_channel'); |
| 40 | 40 | ||
| 41 | - await AppBootstrap.init(); | 41 | + await _healthBackgroundLog(channel, 'entry.start'); |
| 42 | + try { | ||
| 43 | + await _healthBackgroundLog(channel, 'bootstrap.start'); | ||
| 44 | + await AppBootstrap.init(); | ||
| 45 | + await _healthBackgroundLog(channel, 'bootstrap.success'); | ||
| 46 | + } catch (error, stackTrace) { | ||
| 47 | + await _healthBackgroundLog( | ||
| 48 | + channel, | ||
| 49 | + 'bootstrap.failed error=$error stack=$stackTrace', | ||
| 50 | + ); | ||
| 51 | + rethrow; | ||
| 52 | + } | ||
| 42 | 53 | ||
| 43 | channel.setMethodCallHandler((call) async { | 54 | channel.setMethodCallHandler((call) async { |
| 44 | switch (call.method) { | 55 | switch (call.method) { |
| @@ -53,6 +64,7 @@ Future<void> healthBackgroundMain() async { | @@ -53,6 +64,7 @@ Future<void> healthBackgroundMain() async { | ||
| 53 | await channel.invokeMethod('healthBackgroundTaskReady', { | 64 | await channel.invokeMethod('healthBackgroundTaskReady', { |
| 54 | 'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000, | 65 | 'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000, |
| 55 | }); | 66 | }); |
| 67 | + await _healthBackgroundLog(channel, 'entry.readySent'); | ||
| 56 | } | 68 | } |
| 57 | 69 | ||
| 58 | Future<void> _runPendingHealthTasks( | 70 | Future<void> _runPendingHealthTasks( |
| @@ -60,6 +72,10 @@ Future<void> _runPendingHealthTasks( | @@ -60,6 +72,10 @@ Future<void> _runPendingHealthTasks( | ||
| 60 | Object? arguments, | 72 | Object? arguments, |
| 61 | ) async { | 73 | ) async { |
| 62 | final tasks = _backgroundHealthTasksFromArguments(arguments); | 74 | final tasks = _backgroundHealthTasksFromArguments(arguments); |
| 75 | + await _healthBackgroundLog( | ||
| 76 | + channel, | ||
| 77 | + 'tasks.received count=${tasks.length} ids=${tasks.map((e) => e.taskId).join(',')}', | ||
| 78 | + ); | ||
| 63 | if (tasks.isEmpty) return; | 79 | if (tasks.isEmpty) return; |
| 64 | 80 | ||
| 65 | for (final task in tasks) { | 81 | for (final task in tasks) { |
| @@ -71,6 +87,10 @@ Future<void> _runPendingHealthTasks( | @@ -71,6 +87,10 @@ Future<void> _runPendingHealthTasks( | ||
| 71 | final userPrefs = Get.find<UserPreferencesStorage>(); | 87 | final userPrefs = Get.find<UserPreferencesStorage>(); |
| 72 | final userId = userPrefs.preferences.value.meUserInfo?.id ?? 0; | 88 | final userId = userPrefs.preferences.value.meUserInfo?.id ?? 0; |
| 73 | final token = userPrefs.accessToken; | 89 | final token = userPrefs.accessToken; |
| 90 | + await _healthBackgroundLog( | ||
| 91 | + channel, | ||
| 92 | + 'login.check userId=$userId hasToken=${token.isNotEmpty}', | ||
| 93 | + ); | ||
| 74 | if (userId <= 0 || token.isEmpty) { | 94 | if (userId <= 0 || token.isEmpty) { |
| 75 | for (final task in tasks) { | 95 | for (final task in tasks) { |
| 76 | await channel.invokeMethod('healthBackgroundTaskFinished', { | 96 | await channel.invokeMethod('healthBackgroundTaskFinished', { |
| @@ -84,7 +104,9 @@ Future<void> _runPendingHealthTasks( | @@ -84,7 +104,9 @@ Future<void> _runPendingHealthTasks( | ||
| 84 | } | 104 | } |
| 85 | 105 | ||
| 86 | try { | 106 | try { |
| 107 | + await _healthBackgroundLog(channel, 'calculate.start'); | ||
| 87 | await Get.find<HealthRawDataCoreService>().startCoreCaculate(); | 108 | await Get.find<HealthRawDataCoreService>().startCoreCaculate(); |
| 109 | + await _healthBackgroundLog(channel, 'calculate.success'); | ||
| 88 | for (final task in tasks) { | 110 | for (final task in tasks) { |
| 89 | await channel.invokeMethod('healthBackgroundTaskFinished', { | 111 | await channel.invokeMethod('healthBackgroundTaskFinished', { |
| 90 | 'taskId': task.taskId, | 112 | 'taskId': task.taskId, |
| @@ -92,6 +114,7 @@ Future<void> _runPendingHealthTasks( | @@ -92,6 +114,7 @@ Future<void> _runPendingHealthTasks( | ||
| 92 | }); | 114 | }); |
| 93 | } | 115 | } |
| 94 | } catch (error) { | 116 | } catch (error) { |
| 117 | + await _healthBackgroundLog(channel, 'calculate.failed error=$error'); | ||
| 95 | for (final task in tasks) { | 118 | for (final task in tasks) { |
| 96 | await channel.invokeMethod('healthBackgroundTaskFinished', { | 119 | await channel.invokeMethod('healthBackgroundTaskFinished', { |
| 97 | 'taskId': task.taskId, | 120 | 'taskId': task.taskId, |
| @@ -103,6 +126,15 @@ Future<void> _runPendingHealthTasks( | @@ -103,6 +126,15 @@ Future<void> _runPendingHealthTasks( | ||
| 103 | } | 126 | } |
| 104 | } | 127 | } |
| 105 | 128 | ||
| 129 | +Future<void> _healthBackgroundLog(MethodChannel channel, String message) async { | ||
| 130 | + try { | ||
| 131 | + await channel.invokeMethod('healthBackgroundLog', { | ||
| 132 | + 'message': message, | ||
| 133 | + 'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000, | ||
| 134 | + }); | ||
| 135 | + } catch (_) {} | ||
| 136 | +} | ||
| 137 | + | ||
| 106 | List<_BackgroundHealthTask> _backgroundHealthTasksFromArguments( | 138 | List<_BackgroundHealthTask> _backgroundHealthTasksFromArguments( |
| 107 | Object? arguments, | 139 | Object? arguments, |
| 108 | ) { | 140 | ) { |
| @@ -821,4 +821,33 @@ class HealthKitRawDataHostApi { | @@ -821,4 +821,33 @@ class HealthKitRawDataHostApi { | ||
| 821 | return (pigeonVar_replyList[0] as bool?)!; | 821 | return (pigeonVar_replyList[0] as bool?)!; |
| 822 | } | 822 | } |
| 823 | } | 823 | } |
| 824 | + | ||
| 825 | + /// 让原生分享出来上传记录 | ||
| 826 | + Future<bool> shareUploadTaskRecord() async { | ||
| 827 | + final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareUploadTaskRecord$pigeonVar_messageChannelSuffix'; | ||
| 828 | + final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>( | ||
| 829 | + pigeonVar_channelName, | ||
| 830 | + pigeonChannelCodec, | ||
| 831 | + binaryMessenger: pigeonVar_binaryMessenger, | ||
| 832 | + ); | ||
| 833 | + final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null); | ||
| 834 | + final List<Object?>? pigeonVar_replyList = | ||
| 835 | + await pigeonVar_sendFuture as List<Object?>?; | ||
| 836 | + if (pigeonVar_replyList == null) { | ||
| 837 | + throw _createConnectionError(pigeonVar_channelName); | ||
| 838 | + } else if (pigeonVar_replyList.length > 1) { | ||
| 839 | + throw PlatformException( | ||
| 840 | + code: pigeonVar_replyList[0]! as String, | ||
| 841 | + message: pigeonVar_replyList[1] as String?, | ||
| 842 | + details: pigeonVar_replyList[2], | ||
| 843 | + ); | ||
| 844 | + } else if (pigeonVar_replyList[0] == null) { | ||
| 845 | + throw PlatformException( | ||
| 846 | + code: 'null-error', | ||
| 847 | + message: 'Host platform returned null value for non-null return value.', | ||
| 848 | + ); | ||
| 849 | + } else { | ||
| 850 | + return (pigeonVar_replyList[0] as bool?)!; | ||
| 851 | + } | ||
| 852 | + } | ||
| 824 | } | 853 | } |
| @@ -162,4 +162,8 @@ abstract class HealthKitRawDataHostApi { | @@ -162,4 +162,8 @@ abstract class HealthKitRawDataHostApi { | ||
| 162 | /// 让原生分享出来flutter的记录文件 | 162 | /// 让原生分享出来flutter的记录文件 |
| 163 | @async | 163 | @async |
| 164 | bool shareFlutterObserverRecord(); | 164 | bool shareFlutterObserverRecord(); |
| 165 | + | ||
| 166 | + /// 让原生分享出来上传记录 | ||
| 167 | + @async | ||
| 168 | + bool shareUploadTaskRecord(); | ||
| 165 | } | 169 | } |
-
Please register or login to post a comment