import 'dart:async'; import 'package:fforte/l10n/app_localizations.dart'; import 'package:fforte/services/notification_service.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:latlong2/latlong.dart'; class TrackingService { static final TrackingService _instance = TrackingService._internal(); factory TrackingService() => _instance; TrackingService._internal(); List pathList = []; StreamSubscription? positionStream; bool isTracking = false; final _positionController = StreamController.broadcast(); Stream get positionStream$ => _positionController.stream; Future startTracking(BuildContext context) async { if (isTracking) return; await NotificationService().initNotification(); if (context.mounted) { NotificationService().showNotification( title: AppLocalizations.of(context)!.trackingRunningInBackground, ); } positionStream = Geolocator.getPositionStream( locationSettings: AndroidSettings( accuracy: LocationAccuracy.high, distanceFilter: 0, foregroundNotificationConfig: ForegroundNotificationConfig( notificationTitle: context.mounted ? AppLocalizations.of(context)!.trackingRunningInBackground : "Tracking", notificationText: "", ), ), ).listen((Position? position) { if (position != null) { pathList.add(LatLng(position.latitude, position.longitude)); _positionController.add(position); } }); positionStream!.onError((e) { NotificationService().deleteNotification(); NotificationService().showNotification(title: "ERROR: $e"); }); isTracking = true; } void pauseTracking() { positionStream?.pause(); isTracking = false; } void resumeTracking() { positionStream?.resume(); isTracking = true; } void stopTracking() { positionStream?.cancel(); NotificationService().deleteNotification(); isTracking = false; } void clearPath() { pathList.clear(); } String getPathAsString() { return pathList.map((pos) => "${pos.latitude},${pos.longitude}").join(";"); } void dispose() { stopTracking(); _positionController.close(); } }