diff --git a/lib/screens/excursion/widgets/tracking.dart b/lib/screens/excursion/widgets/tracking.dart index c846fe6..b2ccdb3 100644 --- a/lib/screens/excursion/widgets/tracking.dart +++ b/lib/screens/excursion/widgets/tracking.dart @@ -22,7 +22,7 @@ class Tracking extends StatefulWidget { class _TrackingState extends State { final TrackingService _trackingService = TrackingService(); - LocationMarkerPosition? locationMarkerPosition; + Position? currentPosition; MapController mapController = MapController(); StreamSubscription? _positionSubscription; StreamSubscription? _statsSubscription; @@ -48,11 +48,7 @@ class _TrackingState extends State { } } - locationMarkerPosition = LocationMarkerPosition( - latitude: widget.startPosition.latitude, - longitude: widget.startPosition.longitude, - accuracy: widget.startPosition.accuracy, - ); + currentPosition = widget.startPosition; // Initialisiere die Statistiken sofort setState(() { @@ -62,11 +58,7 @@ class _TrackingState extends State { _positionSubscription = _trackingService.positionStream$.listen((position) { setState(() { - locationMarkerPosition = LocationMarkerPosition( - latitude: position.latitude, - longitude: position.longitude, - accuracy: position.accuracy, - ); + currentPosition = position; }); }); @@ -163,11 +155,7 @@ class _TrackingState extends State { if (_trackingService.isTracking) { _trackingService.pauseTracking(); } else { - if (_trackingService.positionStream == null) { - _trackingService.startTracking(context); - } else { - _trackingService.resumeTracking(); - } + _trackingService.startTracking(context); } }); }, @@ -181,8 +169,8 @@ class _TrackingState extends State { onPressed: () { mapController.move( LatLng( - locationMarkerPosition!.latitude, - locationMarkerPosition!.longitude, + currentPosition!.latitude, + currentPosition!.longitude, ), 16, ); @@ -218,6 +206,31 @@ class _TrackingState extends State { ), ], ), + if (currentPosition != null) + CircleLayer( + circles: [ + CircleMarker( + point: LatLng( + currentPosition!.latitude, + currentPosition!.longitude, + ), + radius: currentPosition!.accuracy, + color: Colors.blue.withOpacity(0.2), + borderColor: Colors.blue, + borderStrokeWidth: 2, + ), + CircleMarker( + point: LatLng( + currentPosition!.latitude, + currentPosition!.longitude, + ), + radius: 5, + color: Colors.blue, + borderColor: Colors.white, + borderStrokeWidth: 2, + ), + ], + ), CurrentLocationLayer(), ], ), diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 93cd967..71ba5d8 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -10,36 +10,75 @@ class Settings extends StatefulWidget { } class _SettingsState extends State { + int _trackingInterval = 60; + @override + void initState() { + super.initState(); + _loadSettings(); + } + + Future _loadSettings() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + setState(() { + _trackingInterval = prefs.getInt('trackingInterval') ?? 60; + }); + } + + Future _saveTrackingInterval(int value) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setInt('trackingInterval', value); + setState(() { + _trackingInterval = value; + }); + } Future _getSaveDir() async { SharedPreferences prefs = await SharedPreferences.getInstance(); - final String saveDir = prefs.getString('saveDir') ?? ""; - return saveDir; } - - @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(AppLocalizations.of(context)!.settings),), - body: Center( + body: Padding( + padding: const EdgeInsets.all(16.0), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(AppLocalizations.of(context)!.filelocation, style: const TextStyle(fontSize: 20),), - FutureBuilder(future: _getSaveDir(), builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return Text(snapshot.data ?? ""); - } else { - return const CircularProgressIndicator(); + FutureBuilder( + future: _getSaveDir(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return Text(snapshot.data ?? ""); + } else { + return const CircularProgressIndicator(); + } } - }), - ElevatedButton(onPressed: () { - - }, child: Text(AppLocalizations.of(context)!.open)) + ), + ElevatedButton( + onPressed: () {}, + child: Text(AppLocalizations.of(context)!.open) + ), + const SizedBox(height: 24), + const Text( + 'Tracking Interval (Sekunden)', + style: TextStyle(fontSize: 20), + ), + Slider( + value: _trackingInterval.toDouble(), + min: 10, + max: 300, + divisions: 29, + label: _trackingInterval.toString(), + onChanged: (double value) { + _saveTrackingInterval(value.round()); + }, + ), + Text('Aktuelles Intervall: $_trackingInterval Sekunden'), ], ), ), diff --git a/lib/services/tracking_service.dart b/lib/services/tracking_service.dart index 0de03db..75c11fe 100644 --- a/lib/services/tracking_service.dart +++ b/lib/services/tracking_service.dart @@ -6,6 +6,7 @@ import 'package:fforte/services/notification_service.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:latlong2/latlong.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class TrackingService { static final TrackingService _instance = TrackingService._internal(); @@ -14,8 +15,9 @@ class TrackingService { List pathList = []; List accuracyList = []; - StreamSubscription? positionStream; + Timer? _positionTimer; bool isTracking = false; + BuildContext? _lastContext; final _positionController = StreamController.broadcast(); final _statsController = StreamController.broadcast(); @@ -44,34 +46,49 @@ class TrackingService { Future startTracking(BuildContext context) async { if (isTracking) return; + _lastContext = context; await NotificationService().initNotification(); NotificationService().showNotification( title: AppLocalizations.of(context)!.trackingRunningInBackground, ); - positionStream = Geolocator.getPositionStream( - locationSettings: AndroidSettings( - accuracy: LocationAccuracy.high, - distanceFilter: 0, - foregroundNotificationConfig: ForegroundNotificationConfig( - notificationTitle: AppLocalizations.of(context)!.trackingRunningInBackground, - notificationText: "", - ), - ), - ).listen((Position? position) { - if (position != null) { + // Get tracking interval from settings + final prefs = await SharedPreferences.getInstance(); + final intervalSeconds = prefs.getInt('trackingInterval') ?? 60; + + // Create a timer that triggers position updates + _positionTimer = Timer.periodic(Duration(seconds: intervalSeconds), (_) async { + try { + final Position position = await Geolocator.getCurrentPosition( + desiredAccuracy: LocationAccuracy.high, + ); + pathList.add(LatLng(position.latitude, position.longitude)); accuracyList.add(position.accuracy); currentAccuracy = position.accuracy; _positionController.add(position); _updateStats(); + } catch (e) { + NotificationService().deleteNotification(); + NotificationService().showNotification(title: "ERROR: $e"); } }); - positionStream!.onError((e) { + // Get initial position immediately + try { + final Position position = await Geolocator.getCurrentPosition( + desiredAccuracy: LocationAccuracy.high, + ); + + pathList.add(LatLng(position.latitude, position.longitude)); + accuracyList.add(position.accuracy); + currentAccuracy = position.accuracy; + _positionController.add(position); + _updateStats(); + } catch (e) { NotificationService().deleteNotification(); NotificationService().showNotification(title: "ERROR: $e"); - }); + } isTracking = true; } @@ -131,21 +148,24 @@ class TrackingService { } void pauseTracking() { - positionStream?.pause(); + _positionTimer?.cancel(); isTracking = false; } void resumeTracking() { - positionStream?.resume(); + if (!isTracking && _lastContext != null) { + startTracking(_lastContext!); + } isTracking = true; } void stopTracking() { - positionStream?.cancel(); + _positionTimer?.cancel(); NotificationService().deleteNotification(); isTracking = false; accuracyList.clear(); currentAccuracy = null; + _lastContext = null; } void clearPath() {