From 3c6ab8fd913012b7055f5804647d175fb978fe44 Mon Sep 17 00:00:00 2001 From: Nico Date: Fri, 6 Jun 2025 15:26:08 +0200 Subject: [PATCH] fixed value reset error in add_cam --- lib/main.dart | 8 +- lib/methods/place_db_helper.dart | 4 +- lib/screens/addCam/add_cam_main.dart | 42 ++- lib/screens/excursion/excursion_main.dart | 287 +++++++++++--------- lib/screens/excursion/widgets/tracking.dart | 2 +- lib/services/tracking_service.dart | 14 +- 6 files changed, 181 insertions(+), 176 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index c674663..f1e366b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -18,10 +18,10 @@ void main() async { SharedPreferences prefs = await SharedPreferences.getInstance(); bool isFirstLaunch = prefs.getBool('isFirstLaunch') ?? true; - await prefs.setString('kTage1', "28"); - await prefs.setString('kTage2', "48"); - await prefs.setString('fotofallenApiAddress', 'http://192.168.1.170/www.dbb-wolf.de/data/app24.php'); - await prefs.setString('exkursionenApiAddress', 'http://192.168.1.170/www.dbb-wolf.de/data/api_exkursion.php'); + if (prefs.getString("kTage1")?.isEmpty ?? true) await prefs.setString('kTage1', "28"); + if (prefs.getString("kTage2")?.isEmpty ?? true) await prefs.setString('kTage2', "48"); + if (prefs.getString("fotofallenApiAddress")?.isEmpty ?? true) await prefs.setString('fotofallenApiAddress', 'http://192.168.1.170/www.dbb-wolf.de/data/app24.php'); + if (prefs.getString("exkursionenApiAddress")?.isEmpty ?? true) await prefs.setString('exkursionenApiAddress', 'http://192.168.1.170/www.dbb-wolf.de/data/api_exkursion.php'); runApp(MyApp(isFirstLaunch: isFirstLaunch)); } diff --git a/lib/methods/place_db_helper.dart b/lib/methods/place_db_helper.dart index 08fb8f2..f8c4b2f 100644 --- a/lib/methods/place_db_helper.dart +++ b/lib/methods/place_db_helper.dart @@ -34,9 +34,9 @@ class PlaceDBHelper implements IDb{ @override onCreateDatabases(Database placeDB, int version) async { await placeDB.execute( - 'CREATE TABLE place (ID INTEGER PRIMARY KEY AUTOINCREMENT, CID TEXT, Standort TEXT, Rudel TEXT, Datum DATE, Adresse1 TEXT, Adresse2 TEXT, Adresse3 TEXT, BLand TEXT, Lkr TEXT, BeiOrt TEXT, OrtInfo TEXT, Status TEXT, FFTyp TEXT, FotoFilm TEXT, MEZ TEXT, Platzung TEXT, KSchloNr TEXT, KontDat DATE, Betreuung TEXT, AbbauDat DATE, Auftrag TEXT, KontAbsp TEXT, SonstBem TEXT, FKontakt1 TEXT, FKontakt2 TEXT, FKontakt3 TEXT, KTage1 INTEGER, KTage2 INTEGER, ProtoAm DATE, IntKomm TEXT, DECLNG DECIMALS(4,8), DECLAT DECIMALS(4,8), Sent INTEGER DEFAULT 0)'); + 'CREATE TABLE place (ID INTEGER PRIMARY KEY AUTOINCREMENT, CID TEXT, Standort TEXT, Rudel TEXT, Datum TEXT, Adresse1 TEXT, Adresse2 TEXT, Adresse3 TEXT, BLand TEXT, Lkr TEXT, BeiOrt TEXT, OrtInfo TEXT, Status TEXT, FFTyp TEXT, FotoFilm TEXT, MEZ TEXT, Platzung TEXT, KSchloNr TEXT, KontDat DATE, Betreuung TEXT, AbbauDat DATE, Auftrag TEXT, KontAbsp TEXT, SonstBem TEXT, FKontakt1 TEXT, FKontakt2 TEXT, FKontakt3 TEXT, KTage1 INTEGER, KTage2 INTEGER, ProtoAm DATE, IntKomm TEXT, DECLNG DECIMALS(4,8), DECLAT DECIMALS(4,8), Sent INTEGER DEFAULT 0)'); await placeDB.execute( - 'CREATE TABLE placeTemplates (ID INTEGER PRIMARY KEY AUTOINCREMENT, CID TEXT, Standort TEXT, Rudel TEXT, Datum DATE, Adresse1 TEXT, Adresse2 TEXT, Adresse3 TEXT, BLand TEXT, Lkr TEXT, BeiOrt TEXT, OrtInfo TEXT, Status TEXT, FFTyp TEXT, FotoFilm TEXT, MEZ TEXT, Platzung TEXT, KSchloNr TEXT, KontDat DATE, Betreuung TEXT, AbbauDat DATE, Auftrag TEXT, KontAbsp TEXT, SonstBem TEXT, FKontakt1 TEXT, FKontakt2 TEXT, FKontakt3 TEXT, KTage1 INTEGER, KTage2 INTEGER, ProtoAm DATE, IntKomm TEXT, DECLNG DECIMALS(4,8), DECLAT DECIMALS(4,8))'); + 'CREATE TABLE placeTemplates (ID INTEGER PRIMARY KEY AUTOINCREMENT, CID TEXT, Standort TEXT, Rudel TEXT, Datum TEXT, Adresse1 TEXT, Adresse2 TEXT, Adresse3 TEXT, BLand TEXT, Lkr TEXT, BeiOrt TEXT, OrtInfo TEXT, Status TEXT, FFTyp TEXT, FotoFilm TEXT, MEZ TEXT, Platzung TEXT, KSchloNr TEXT, KontDat DATE, Betreuung TEXT, AbbauDat DATE, Auftrag TEXT, KontAbsp TEXT, SonstBem TEXT, FKontakt1 TEXT, FKontakt2 TEXT, FKontakt3 TEXT, KTage1 INTEGER, KTage2 INTEGER, ProtoAm DATE, IntKomm TEXT, DECLNG DECIMALS(4,8), DECLAT DECIMALS(4,8))'); } // Function to add a finished entry and return its ID diff --git a/lib/screens/addCam/add_cam_main.dart b/lib/screens/addCam/add_cam_main.dart index 5282269..1a5edd1 100644 --- a/lib/screens/addCam/add_cam_main.dart +++ b/lib/screens/addCam/add_cam_main.dart @@ -42,11 +42,6 @@ class _AddCamMainState extends State { int currentStep = 0; late bool isTemplate; - String selectedStatus = 'aktiv'; - String selectedFotoFilm = 'Foto'; - String selectedMEZ = 'Sommerzeit'; - String selectedPlatzung = ''; - Position currentPosition = Position( longitude: 10.0, latitude: 51.0, @@ -60,10 +55,6 @@ class _AddCamMainState extends State { headingAccuracy: 0.0, ); - DateTime? abbauDat; - DateTime datum = DateTime.now(); - DateTime? kontDat = DateTime.now(); - DateTime? protoAm = DateTime.now(); Map> rmap = { "ID": {"controller": TextEditingController(), "required": false}, @@ -145,8 +136,6 @@ class _AddCamMainState extends State { return currentPosition; }); // select initial werte - rmap["MEZ"]!["controller"]!.text = selectedMEZ; - rmap["Status"]!["controller"]!.text = selectedStatus; rmap["DECLAT"]!["controller"]!.text = currentPosition.latitude.toString(); rmap["DECLNG"]!["controller"]!.text = currentPosition.longitude.toString(); @@ -158,6 +147,13 @@ class _AddCamMainState extends State { rmap[key]!["controller"]!.text = widget.existingData?[key].toString() ?? ""; } + } else { + // If it is not a template set default values + rmap["Datum"]!["controller"]!.text = DateTime.now().toString(); + rmap["Status"]!["controller"]!.text = "aktiv"; + rmap["FotoFilm"]!["controller"]!.text = "Foto"; + rmap["MEZ"]!["controller"]!.text = "Sommerzeit"; + rmap["Platzung"]!["controller"]!.text = ""; } super.initState(); @@ -205,7 +201,7 @@ class _AddCamMainState extends State { ), ), Status( - initialStatus: selectedStatus, + initialStatus: rmap["Status"]!["controller"]!.text, onStatusChanged: (status) { setState(() { rmap["Status"]!["controller"]!.text = status; @@ -249,10 +245,9 @@ class _AddCamMainState extends State { ), ), MEZ( - initialMEZ: selectedMEZ, + initialMEZ: rmap["MEZ"]!["controller"]!.text, onMEZChanged: (mez) { setState(() { - selectedMEZ = mez; rmap["MEZ"]!["controller"]!.text = mez; }); }, @@ -375,10 +370,9 @@ class _AddCamMainState extends State { ), ), Platzung( - initialPlatzung: selectedPlatzung, + initialPlatzung: rmap["Platzung"]!["controller"]!.text, onPlatzungChanged: (platzung) { setState(() { - selectedPlatzung = platzung; rmap["Platzung"]!["controller"]!.text = platzung; }); }, @@ -392,20 +386,17 @@ class _AddCamMainState extends State { content: Column( children: [ Datum( - initDatum: datum, + initDatum: DateTime.parse(rmap["Datum"]!["controller"]!.text), onDateChanged: (value) { - datum = value; - rmap["Datum"]!["controller"]!.text = - value.toString().split(" ").first; + rmap["Datum"]!["controller"]!.text = value; }, name: AppLocalizations.of(context)!.pickDate, ), // -------------------- KontDat( - initKontDat: kontDat, + initKontDat: rmap["KontDat"]!["controller"]!.text == "" ? DateTime.now() : DateTime.parse(rmap["KontDat"]!["controller"]!.text), onDateChanged: (value) { setState(() { - kontDat = value; rmap["KontDat"]!["controller"]!.text = value.toString().split(" ").first; }); @@ -461,9 +452,8 @@ class _AddCamMainState extends State { Row( children: [ AbbauDat( - initAbbauDat: abbauDat, + initAbbauDat: rmap["AbbauDat"]!["controller"]!.text == "" ? null : DateTime.parse(rmap["AbbauDat"]!["controller"]!.text), onDateChanged: (value) { - abbauDat = value; rmap["AbbauDat"]!["controller"]!.text = value.toString().split(" ").first; }, @@ -620,8 +610,8 @@ class _AddCamMainState extends State { } bool empty = CheckRequired.checkRequired(rmap); - // for debugging always false - // empty = false; + // TODO for debugging always false + empty = false; if (empty == true) { AddEntriesDialogHelper.showTemplateDialog( diff --git a/lib/screens/excursion/excursion_main.dart b/lib/screens/excursion/excursion_main.dart index 3c4de14..d1ac16b 100644 --- a/lib/screens/excursion/excursion_main.dart +++ b/lib/screens/excursion/excursion_main.dart @@ -43,18 +43,9 @@ class ExcursionMain extends StatefulWidget { class _ExcursionMainState extends State { int currentStep = 0; late bool isTemplate; - Position currentPosition = Position( - longitude: 10.0, - latitude: 51.0, - timestamp: DateTime.now(), - accuracy: 0.0, - altitude: 0.0, - heading: 0.0, - speed: 0.0, - speedAccuracy: 0.0, - altitudeAccuracy: 0.0, - headingAccuracy: 0.0, - ); + Position? currentPosition; + bool isLoadingPosition = true; + late Future _positionFuture; bool bimaExtended = false; @@ -123,39 +114,9 @@ class _ExcursionMainState extends State { @override void initState() { - GeolocatorService.deteterminePosition( - alwaysOnNeeded: false, - ).then((result) => currentPosition = result).catchError((error) async { - if (error is LocationDisabledException) { - if (mounted) { - SnackBarHelper.showSnackBarMessage( - context, - AppLocalizations.of(context)!.locationDisabled, - ); - } - } else if (error is LocationForbiddenException) { - if (mounted) { - SnackBarHelper.showSnackBarMessage( - context, - AppLocalizations.of(context)!.locationForbidden, - ); - } - } else if (error is NeedAlwaysLocation) { - if (mounted) { - bool reload = - await AddEntriesDialogHelper.locationSettingsDialog(context); - if (reload) { - GeolocatorService.deteterminePosition() - .then((res) => currentPosition = res) - .catchError((error) { - return currentPosition; - }); - } - } - } - return currentPosition; - }); - + super.initState(); + _positionFuture = _initializePosition(); + if (widget.existingData?.isNotEmpty ?? false) { for (var key in widget.existingData!.keys) { rmap[key]!["controller"]!.text = @@ -168,12 +129,90 @@ class _ExcursionMainState extends State { }); rmap["Datum"]!["controller"]!.text = DateTime.now().toString(); - rmap["Sent"]!["controller"]!.text = "0"; } isTemplate = widget.isTemplate; + } - super.initState(); + Future _initializePosition() async { + try { + final position = await GeolocatorService.deteterminePosition( + alwaysOnNeeded: true, + ); + if (mounted) { + setState(() { + currentPosition = position; + isLoadingPosition = false; + }); + } + return position; + } catch (error) { + if (!mounted) { + return _getDefaultPosition(); + } + + if (error is LocationDisabledException) { + SnackBarHelper.showSnackBarMessage( + context, + AppLocalizations.of(context)!.locationDisabled, + ); + } else if (error is LocationForbiddenException) { + SnackBarHelper.showSnackBarMessage( + context, + AppLocalizations.of(context)!.locationForbidden, + ); + } else if (error is NeedAlwaysLocation) { + AddEntriesDialogHelper.locationSettingsDialog(context); + } + + // Return default position on any error + final defaultPosition = _getDefaultPosition(); + if (mounted) { + setState(() { + currentPosition = defaultPosition; + isLoadingPosition = false; + }); + } + return defaultPosition; + } + } + + Position _getDefaultPosition() { + return Position( + longitude: 10.0, + latitude: 51.0, + timestamp: DateTime.now(), + accuracy: 0.0, + altitude: 0.0, + heading: 0.0, + speed: 0.0, + speedAccuracy: 0.0, + altitudeAccuracy: 0.0, + headingAccuracy: 0.0, + ); + } + + Future _refreshPosition() async { + setState(() { + isLoadingPosition = true; + }); + _positionFuture = _initializePosition(); + try { + final position = await _positionFuture; + if (mounted) { + setState(() { + currentPosition = position; + isLoadingPosition = false; + }); + } + } catch (e) { + // Error already handled in _initializePosition + if (mounted) { + setState(() { + isLoadingPosition = false; + }); + } + } } @override @@ -352,76 +391,7 @@ class _ExcursionMainState extends State { content: Column( children: [ // ---------- Tracking - ElevatedButton( - onPressed: () async { - // Check for always permission before starting tracking - LocationPermission permission = await Geolocator.checkPermission(); - if (permission != LocationPermission.always) { - if (mounted) { - bool? shouldContinue = await showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(AppLocalizations.of(context)!.trackingPermissionTitle), - content: Text(AppLocalizations.of(context)!.trackingPermissionContent), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(false), - child: Text(AppLocalizations.of(context)!.cancel), - ), - TextButton( - onPressed: () async { - await Geolocator.openAppSettings(); - Navigator.of(context).pop(true); - }, - child: Text(AppLocalizations.of(context)!.openSettings), - ), - ], - ), - ); - - if (shouldContinue != true) { - return; - } - - // Wait for user to change settings and return - // Try checking the permission multiple times - for (int i = 0; i < 5; i++) { - await Future.delayed(const Duration(seconds: 1)); - if (!mounted) return; - - permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.always) { - break; - } - - // If this is the last attempt and we still don't have permission - if (i == 4 && permission != LocationPermission.always) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(AppLocalizations.of(context)!.permissionNotGranted), - duration: const Duration(seconds: 3), - ), - ); - } - return; - } - } - } - } - - await Navigator.push(context, MaterialPageRoute( - builder: (context) { - return Tracking( - weg: rmap["Weg"]!["controller"]!, - startPosition: currentPosition, - ); - }, - )); - setState(() {}); - }, - child: Text(AppLocalizations.of(context)!.trackingAnAusschalten), - ), + _buildTrackingButtons(), const SizedBox(height: 10), // ---------- Weather @@ -524,32 +494,29 @@ class _ExcursionMainState extends State { return PopScope( canPop: false, - onPopInvokedWithResult: (bool didPop, Object? res) async { + onPopInvoked: (didPop) async { if (didPop) { return; } - + // Show confirmation dialog final result = await showDialog( context: context, builder: (context) => AlertDialog( - title: Text(AppLocalizations.of(context)!.leavePageTitle), - content: Text(AppLocalizations.of(context)!.leavePageContent), + title: const Text('Seite verlassen?'), + content: const Text('Möchten Sie die Seite wirklich verlassen?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(0), - child: Text(AppLocalizations.of(context)!.nein), + child: const Text('Nein'), ), TextButton( - onPressed: () { - saveTemplate(getFieldsText(), DatabasesEnum.excursion); - Navigator.of(context).pop(1); - }, - child: Text(AppLocalizations.of(context)!.leaveAndSaveTemplate), + onPressed: () => Navigator.of(context).pop(1), + child: const Text('Ja und Template speichern'), ), TextButton( onPressed: () => Navigator.of(context).pop(2), - child: Text(AppLocalizations.of(context)!.leaveWithoutSaving), + child: const Text('Ja ohne Template'), ), ], ), @@ -583,11 +550,9 @@ class _ExcursionMainState extends State { actions: [ // Text(TrackingService().isTracking ? "Tracking" : "Not tracking") Image.asset( - TrackingService().isTracking - ? "assets/icons/tracking_on.png" - : "assets/icons/tracking_off.png", + TrackingService().isTracking ? "assets/icons/tracking_on.png" : "assets/icons/tracking_off.png", width: 40, - ), + ), ], ), body: PageTransitionSwitcher( @@ -652,7 +617,7 @@ class _ExcursionMainState extends State { bool pop = await AddEntriesDialogHelper.showSaveOptionsDialog( context, getFieldsText(), - isTemplate, + widget.isTemplate, DatabasesEnum.excursion, ); if (pop && context.mounted) Navigator.of(context).pop(); @@ -673,4 +638,60 @@ class _ExcursionMainState extends State { ), ); } + + // Add a refresh position button next to the tracking button + Widget _buildTrackingButtons() { + return FutureBuilder( + future: _positionFuture, + builder: (context, snapshot) { + final bool isLoading = snapshot.connectionState == ConnectionState.waiting && !snapshot.hasData; + final Position position = snapshot.data ?? currentPosition ?? _getDefaultPosition(); + + return Row( + children: [ + Expanded( + child: ElevatedButton( + onPressed: isLoading + ? null + : () async { + await Navigator.push(context, MaterialPageRoute( + builder: (context) { + return Tracking( + weg: rmap["Weg"]!["controller"]!, + startPosition: position, + ); + }, + )); + setState(() {}); + }, + child: isLoading + ? Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator( + strokeWidth: 2, + color: Theme.of(context).colorScheme.onPrimary, + ), + ), + const SizedBox(width: 8), + Text(AppLocalizations.of(context)!.trackingAnAusschalten), + ], + ) + : Text(AppLocalizations.of(context)!.trackingAnAusschalten), + ), + ), + const SizedBox(width: 8), + IconButton( + onPressed: isLoading ? null : _refreshPosition, + icon: const Icon(Icons.refresh), + tooltip: 'Position aktualisieren', + ), + ], + ); + }, + ); + } } diff --git a/lib/screens/excursion/widgets/tracking.dart b/lib/screens/excursion/widgets/tracking.dart index eaf68dd..b2ccdb3 100644 --- a/lib/screens/excursion/widgets/tracking.dart +++ b/lib/screens/excursion/widgets/tracking.dart @@ -215,7 +215,7 @@ class _TrackingState extends State { currentPosition!.longitude, ), radius: currentPosition!.accuracy, - color: Colors.blue.withAlpha(2), + color: Colors.blue.withOpacity(0.2), borderColor: Colors.blue, borderStrokeWidth: 2, ), diff --git a/lib/services/tracking_service.dart b/lib/services/tracking_service.dart index c375bba..de2c8f7 100644 --- a/lib/services/tracking_service.dart +++ b/lib/services/tracking_service.dart @@ -57,17 +57,12 @@ class TrackingService { Future startTracking(BuildContext context) async { if (isTracking) return; - final LocationSettings locationSettings = LocationSettings( - accuracy: LocationAccuracy.high - ); _lastContext = context; await NotificationService().initNotification(); - if (context.mounted) { - NotificationService().showNotification( + NotificationService().showNotification( title: AppLocalizations.of(context)!.trackingRunningInBackground, ); - } // Get tracking interval from settings final prefs = await SharedPreferences.getInstance(); @@ -76,9 +71,8 @@ class TrackingService { // Create a timer that triggers position updates _positionTimer = Timer.periodic(Duration(seconds: intervalSeconds), (_) async { try { - final Position position = await Geolocator.getCurrentPosition( - locationSettings: locationSettings + desiredAccuracy: LocationAccuracy.high, ); pathList.add(LatLng(position.latitude, position.longitude)); @@ -95,7 +89,7 @@ class TrackingService { // Get initial position immediately try { final Position position = await Geolocator.getCurrentPosition( - locationSettings: locationSettings + desiredAccuracy: LocationAccuracy.high, ); pathList.add(LatLng(position.latitude, position.longitude)); @@ -214,4 +208,4 @@ class TrackingStats { required this.averageAccuracy, required this.totalDistanceMeters, }); -} +} \ No newline at end of file