76 lines
2.6 KiB
Dart
76 lines
2.6 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
|
import 'package:workmanager/workmanager.dart';
|
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
|
|
|
/// Unique task name for the background location update.
|
|
const _taskName = 'com.tasq.backgroundLocationUpdate';
|
|
|
|
/// Top-level callback required by Workmanager. Must be a top-level or static
|
|
/// function.
|
|
@pragma('vm:entry-point')
|
|
void callbackDispatcher() {
|
|
Workmanager().executeTask((task, inputData) async {
|
|
try {
|
|
// Re-initialize Supabase in the isolate
|
|
await dotenv.load();
|
|
final url = dotenv.env['SUPABASE_URL'] ?? '';
|
|
final anonKey = dotenv.env['SUPABASE_ANON_KEY'] ?? '';
|
|
if (url.isEmpty || anonKey.isEmpty) return Future.value(true);
|
|
|
|
await Supabase.initialize(url: url, anonKey: anonKey);
|
|
final client = Supabase.instance.client;
|
|
|
|
// Must have an active session
|
|
final session = client.auth.currentSession;
|
|
if (session == null) return Future.value(true);
|
|
|
|
final serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
|
if (!serviceEnabled) return Future.value(true);
|
|
|
|
final permission = await Geolocator.checkPermission();
|
|
if (permission == LocationPermission.denied ||
|
|
permission == LocationPermission.deniedForever) {
|
|
return Future.value(true);
|
|
}
|
|
|
|
final position = await Geolocator.getCurrentPosition(
|
|
locationSettings: const LocationSettings(
|
|
accuracy: LocationAccuracy.high,
|
|
),
|
|
);
|
|
|
|
await client.rpc(
|
|
'update_live_position',
|
|
params: {'p_lat': position.latitude, 'p_lng': position.longitude},
|
|
);
|
|
} catch (e) {
|
|
debugPrint('Background location update error: $e');
|
|
}
|
|
return Future.value(true);
|
|
});
|
|
}
|
|
|
|
/// Initialize Workmanager and register periodic background location task.
|
|
Future<void> initBackgroundLocationService() async {
|
|
await Workmanager().initialize(callbackDispatcher);
|
|
}
|
|
|
|
/// Register a periodic task to report location every ~15 minutes
|
|
/// (Android minimum for periodic Workmanager tasks).
|
|
Future<void> startBackgroundLocationUpdates() async {
|
|
await Workmanager().registerPeriodicTask(
|
|
_taskName,
|
|
_taskName,
|
|
frequency: const Duration(minutes: 15),
|
|
constraints: Constraints(networkType: NetworkType.connected),
|
|
existingWorkPolicy: ExistingPeriodicWorkPolicy.keep,
|
|
);
|
|
}
|
|
|
|
/// Cancel the periodic background location task.
|
|
Future<void> stopBackgroundLocationUpdates() async {
|
|
await Workmanager().cancelByUniqueName(_taskName);
|
|
}
|