|
...
|
...
|
@@ -3,11 +3,14 @@ import 'dart:async'; |
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:intl/date_symbol_data_local.dart';
|
|
|
|
|
|
|
|
import 'app/bootstrap/app_bootstrap.dart';
|
|
|
|
import 'app/double_feel_app.dart';
|
|
|
|
import 'core/services/health_raw_data_core_service.dart';
|
|
|
|
import 'core/theme/app_theme.dart';
|
|
|
|
import 'data/local/user_preferences_storage.dart';
|
|
|
|
|
|
|
|
Future<void> main() async {
|
|
|
|
runZonedGuarded<Future<Null>>(
|
|
...
|
...
|
@@ -29,3 +32,99 @@ Future<void> main() async { |
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
@pragma('vm:entry-point')
|
|
|
|
Future<void> healthBackgroundMain() async {
|
|
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
const channel = MethodChannel('doublefeel_flutter_health_background_channel');
|
|
|
|
|
|
|
|
await AppBootstrap.init();
|
|
|
|
|
|
|
|
channel.setMethodCallHandler((call) async {
|
|
|
|
switch (call.method) {
|
|
|
|
case 'runPendingHealthTasks':
|
|
|
|
await _runPendingHealthTasks(channel, call.arguments);
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
await channel.invokeMethod('healthBackgroundTaskReady', {
|
|
|
|
'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _runPendingHealthTasks(
|
|
|
|
MethodChannel channel,
|
|
|
|
Object? arguments,
|
|
|
|
) async {
|
|
|
|
final tasks = _backgroundHealthTasksFromArguments(arguments);
|
|
|
|
if (tasks.isEmpty) return;
|
|
|
|
|
|
|
|
for (final task in tasks) {
|
|
|
|
await channel.invokeMethod('healthBackgroundTaskReceived', {
|
|
|
|
'taskId': task.taskId,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
final userPrefs = Get.find<UserPreferencesStorage>();
|
|
|
|
final userId = userPrefs.preferences.value.meUserInfo?.id ?? 0;
|
|
|
|
final token = userPrefs.accessToken;
|
|
|
|
if (userId <= 0 || token.isEmpty) {
|
|
|
|
for (final task in tasks) {
|
|
|
|
await channel.invokeMethod('healthBackgroundTaskFinished', {
|
|
|
|
'taskId': task.taskId,
|
|
|
|
'success': false,
|
|
|
|
'retryable': true,
|
|
|
|
'error': 'missingLogin',
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
await Get.find<HealthRawDataCoreService>().startCoreCaculate();
|
|
|
|
for (final task in tasks) {
|
|
|
|
await channel.invokeMethod('healthBackgroundTaskFinished', {
|
|
|
|
'taskId': task.taskId,
|
|
|
|
'success': true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
for (final task in tasks) {
|
|
|
|
await channel.invokeMethod('healthBackgroundTaskFinished', {
|
|
|
|
'taskId': task.taskId,
|
|
|
|
'success': false,
|
|
|
|
'retryable': true,
|
|
|
|
'error': error.toString(),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
List<_BackgroundHealthTask> _backgroundHealthTasksFromArguments(
|
|
|
|
Object? arguments,
|
|
|
|
) {
|
|
|
|
final rawTasksValue =
|
|
|
|
arguments is Map<Object?, Object?> ? arguments['tasks'] : null;
|
|
|
|
final rawTasks =
|
|
|
|
rawTasksValue is List ? rawTasksValue.cast<Object?>() : const <Object?>[];
|
|
|
|
return rawTasks
|
|
|
|
.whereType<Map<Object?, Object?>>()
|
|
|
|
.map(_BackgroundHealthTask.fromMap)
|
|
|
|
.whereType<_BackgroundHealthTask>()
|
|
|
|
.toList(growable: false);
|
|
|
|
}
|
|
|
|
|
|
|
|
class _BackgroundHealthTask {
|
|
|
|
const _BackgroundHealthTask({required this.taskId});
|
|
|
|
|
|
|
|
final String taskId;
|
|
|
|
|
|
|
|
static _BackgroundHealthTask? fromMap(Map<Object?, Object?> map) {
|
|
|
|
final taskId = map['taskId'];
|
|
|
|
if (taskId is! String || taskId.isEmpty) return null;
|
|
|
|
return _BackgroundHealthTask(taskId: taskId);
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|