feat: Add task execution callback registration to BackgroundTaskService and update geofence dispatcher to use it
This commit is contained in:
@@ -55,4 +55,16 @@ class BackgroundTaskService extends BaseDeviceService {
|
|||||||
Future<void> cancelAll() async {
|
Future<void> cancelAll() async {
|
||||||
return action(() => Workmanager().cancelAll());
|
return action(() => Workmanager().cancelAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Registers the task execution callback for the background isolate.
|
||||||
|
///
|
||||||
|
/// Must be called inside the top-level callback dispatcher function.
|
||||||
|
/// The [callback] receives the task name and optional input data, and
|
||||||
|
/// must return `true` on success or `false` on failure.
|
||||||
|
void executeTask(
|
||||||
|
Future<bool> Function(String task, Map<String, dynamic>? inputData)
|
||||||
|
callback,
|
||||||
|
) {
|
||||||
|
Workmanager().executeTask(callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// ignore_for_file: avoid_print
|
// ignore_for_file: avoid_print
|
||||||
import 'package:krow_core/core.dart';
|
import 'package:krow_core/core.dart';
|
||||||
import 'package:workmanager/workmanager.dart';
|
import 'package:krow_domain/src/core/models/device_location.dart';
|
||||||
|
|
||||||
/// Top-level callback dispatcher for background geofence tasks.
|
/// Top-level callback dispatcher for background geofence tasks.
|
||||||
///
|
///
|
||||||
@@ -13,7 +13,7 @@ import 'package:workmanager/workmanager.dart';
|
|||||||
/// is retained solely for this entry-point pattern.
|
/// is retained solely for this entry-point pattern.
|
||||||
@pragma('vm:entry-point')
|
@pragma('vm:entry-point')
|
||||||
void backgroundGeofenceDispatcher() {
|
void backgroundGeofenceDispatcher() {
|
||||||
Workmanager().executeTask(
|
const BackgroundTaskService().executeTask(
|
||||||
(String task, Map<String, dynamic>? inputData) async {
|
(String task, Map<String, dynamic>? inputData) async {
|
||||||
print('[BackgroundGeofence] Task triggered: $task');
|
print('[BackgroundGeofence] Task triggered: $task');
|
||||||
print('[BackgroundGeofence] Input data: $inputData');
|
print('[BackgroundGeofence] Input data: $inputData');
|
||||||
@@ -39,7 +39,7 @@ void backgroundGeofenceDispatcher() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const LocationService locationService = LocationService();
|
const LocationService locationService = LocationService();
|
||||||
final location = await locationService.getCurrentLocation();
|
final DeviceLocation location = await locationService.getCurrentLocation();
|
||||||
print(
|
print(
|
||||||
'[BackgroundGeofence] Current position: '
|
'[BackgroundGeofence] Current position: '
|
||||||
'lat=${location.latitude}, lng=${location.longitude}',
|
'lat=${location.latitude}, lng=${location.longitude}',
|
||||||
@@ -93,6 +93,15 @@ void backgroundGeofenceDispatcher() {
|
|||||||
/// Uses core services for foreground operations. The background isolate logic
|
/// Uses core services for foreground operations. The background isolate logic
|
||||||
/// lives in the top-level [backgroundGeofenceDispatcher] function above.
|
/// lives in the top-level [backgroundGeofenceDispatcher] function above.
|
||||||
class BackgroundGeofenceService {
|
class BackgroundGeofenceService {
|
||||||
|
|
||||||
|
/// Creates a [BackgroundGeofenceService] instance.
|
||||||
|
BackgroundGeofenceService({
|
||||||
|
required BackgroundTaskService backgroundTaskService,
|
||||||
|
required NotificationService notificationService,
|
||||||
|
required StorageService storageService,
|
||||||
|
}) : _backgroundTaskService = backgroundTaskService,
|
||||||
|
_notificationService = notificationService,
|
||||||
|
_storageService = storageService;
|
||||||
/// The core background task service for scheduling periodic work.
|
/// The core background task service for scheduling periodic work.
|
||||||
final BackgroundTaskService _backgroundTaskService;
|
final BackgroundTaskService _backgroundTaskService;
|
||||||
|
|
||||||
@@ -103,25 +112,25 @@ class BackgroundGeofenceService {
|
|||||||
final StorageService _storageService;
|
final StorageService _storageService;
|
||||||
|
|
||||||
/// Storage key for the target latitude.
|
/// Storage key for the target latitude.
|
||||||
static const _keyTargetLat = 'geofence_target_lat';
|
static const String _keyTargetLat = 'geofence_target_lat';
|
||||||
|
|
||||||
/// Storage key for the target longitude.
|
/// Storage key for the target longitude.
|
||||||
static const _keyTargetLng = 'geofence_target_lng';
|
static const String _keyTargetLng = 'geofence_target_lng';
|
||||||
|
|
||||||
/// Storage key for the shift identifier.
|
/// Storage key for the shift identifier.
|
||||||
static const _keyShiftId = 'geofence_shift_id';
|
static const String _keyShiftId = 'geofence_shift_id';
|
||||||
|
|
||||||
/// Storage key for the active tracking flag.
|
/// Storage key for the active tracking flag.
|
||||||
static const _keyTrackingActive = 'geofence_tracking_active';
|
static const String _keyTrackingActive = 'geofence_tracking_active';
|
||||||
|
|
||||||
/// Unique task name for the periodic background check.
|
/// Unique task name for the periodic background check.
|
||||||
static const taskUniqueName = 'geofence_background_check';
|
static const String taskUniqueName = 'geofence_background_check';
|
||||||
|
|
||||||
/// Task name identifier for the workmanager callback.
|
/// Task name identifier for the workmanager callback.
|
||||||
static const taskName = 'geofenceCheck';
|
static const String taskName = 'geofenceCheck';
|
||||||
|
|
||||||
/// Notification ID for clock-in greeting notifications.
|
/// Notification ID for clock-in greeting notifications.
|
||||||
static const _clockInNotificationId = 1;
|
static const int _clockInNotificationId = 1;
|
||||||
|
|
||||||
/// Notification ID for left-geofence warnings.
|
/// Notification ID for left-geofence warnings.
|
||||||
static const int leftGeofenceNotificationId = 2;
|
static const int leftGeofenceNotificationId = 2;
|
||||||
@@ -130,16 +139,7 @@ class BackgroundGeofenceService {
|
|||||||
static const double geofenceRadiusMeters = 500;
|
static const double geofenceRadiusMeters = 500;
|
||||||
|
|
||||||
/// Notification ID for clock-out notifications.
|
/// Notification ID for clock-out notifications.
|
||||||
static const _clockOutNotificationId = 3;
|
static const int _clockOutNotificationId = 3;
|
||||||
|
|
||||||
/// Creates a [BackgroundGeofenceService] instance.
|
|
||||||
BackgroundGeofenceService({
|
|
||||||
required BackgroundTaskService backgroundTaskService,
|
|
||||||
required NotificationService notificationService,
|
|
||||||
required StorageService storageService,
|
|
||||||
}) : _backgroundTaskService = backgroundTaskService,
|
|
||||||
_notificationService = notificationService,
|
|
||||||
_storageService = storageService;
|
|
||||||
|
|
||||||
/// Starts periodic 15-minute background geofence checks.
|
/// Starts periodic 15-minute background geofence checks.
|
||||||
///
|
///
|
||||||
@@ -150,7 +150,7 @@ class BackgroundGeofenceService {
|
|||||||
required double targetLng,
|
required double targetLng,
|
||||||
required String shiftId,
|
required String shiftId,
|
||||||
}) async {
|
}) async {
|
||||||
await Future.wait([
|
await Future.wait(<Future<bool>>[
|
||||||
_storageService.setDouble(_keyTargetLat, targetLat),
|
_storageService.setDouble(_keyTargetLat, targetLat),
|
||||||
_storageService.setDouble(_keyTargetLng, targetLng),
|
_storageService.setDouble(_keyTargetLng, targetLng),
|
||||||
_storageService.setString(_keyShiftId, shiftId),
|
_storageService.setString(_keyShiftId, shiftId),
|
||||||
@@ -161,7 +161,7 @@ class BackgroundGeofenceService {
|
|||||||
uniqueName: taskUniqueName,
|
uniqueName: taskUniqueName,
|
||||||
taskName: taskName,
|
taskName: taskName,
|
||||||
frequency: const Duration(seconds: 10),
|
frequency: const Duration(seconds: 10),
|
||||||
inputData: {
|
inputData: <String, dynamic>{
|
||||||
'targetLat': targetLat,
|
'targetLat': targetLat,
|
||||||
'targetLng': targetLng,
|
'targetLng': targetLng,
|
||||||
'shiftId': shiftId,
|
'shiftId': shiftId,
|
||||||
@@ -175,7 +175,7 @@ class BackgroundGeofenceService {
|
|||||||
Future<void> stopBackgroundTracking() async {
|
Future<void> stopBackgroundTracking() async {
|
||||||
await _backgroundTaskService.cancelByUniqueName(taskUniqueName);
|
await _backgroundTaskService.cancelByUniqueName(taskUniqueName);
|
||||||
|
|
||||||
await Future.wait([
|
await Future.wait(<Future<bool>>[
|
||||||
_storageService.remove(_keyTargetLat),
|
_storageService.remove(_keyTargetLat),
|
||||||
_storageService.remove(_keyTargetLng),
|
_storageService.remove(_keyTargetLng),
|
||||||
_storageService.remove(_keyShiftId),
|
_storageService.remove(_keyShiftId),
|
||||||
@@ -185,7 +185,7 @@ class BackgroundGeofenceService {
|
|||||||
|
|
||||||
/// Whether background tracking is currently active.
|
/// Whether background tracking is currently active.
|
||||||
Future<bool> get isTrackingActive async {
|
Future<bool> get isTrackingActive async {
|
||||||
final active = await _storageService.getBool(_keyTrackingActive);
|
final bool? active = await _storageService.getBool(_keyTrackingActive);
|
||||||
return active ?? false;
|
return active ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user