Track látszik a terepi bejárás térképen is, gps log jelvesztéskor.

This commit is contained in:
torok.istvan 2026-07-02 15:49:23 +02:00
parent e126f340c6
commit f130f583ba
6 changed files with 116 additions and 16 deletions

View File

@ -86,7 +86,8 @@ class MapSurveyView extends GetView<MapSurveyController> {
const ImportedLayerOverlay(),
// Track polyline
Obx(() {
final inTrackMode = controller.mode.value == MapSurveyMode.track;
final inTrackMode = controller.mode.value == MapSurveyMode.track ||
controller.mode.value == MapSurveyMode.fieldWalk;
if (!inTrackMode) return const SizedBox.shrink();
final ids = TrackingController.to.overlayTrackIds;
if (ids.isEmpty) return const SizedBox.shrink();

View File

@ -88,6 +88,13 @@ class TrackingController extends GetxController {
final _db = TrackDatabase.instance;
final _exporter = GpxExporter();
// Timer
DateTime? _lastPositionTime;
Timer? _watchdogTimer;
final gpsSignalLost = false.obs;
static const _gpsTimeoutSec = 10;
// Inicializálás
@override
@ -191,6 +198,7 @@ class TrackingController extends GetxController {
isRecording.value = true;
isPaused.value = false;
_startWatchdog();
}
void pauseRecording() {
@ -245,6 +253,10 @@ class TrackingController extends GetxController {
isPaused.value = false;
await loadSavedTracks();
_watchdogTimer?.cancel();
_watchdogTimer = null;
gpsSignalLost.value = false;
}
Future<void> loadSavedTracks() async {
@ -281,11 +293,24 @@ class TrackingController extends GetxController {
Future<void> _onPosition(SourcePosition pos) async {
try {
if (isPaused.value) return;
_lastPositionTime = DateTime.now();
gpsSignalLost.value = false;
final sw = Stopwatch()..start();
final trackId = currentTrack.value?.id;
if (trackId == null) return;
final point = TrackPoint(
trackId: trackId,
latitude: pos.latitude,
longitude: pos.longitude,
altitude: pos.altitude,
accuracy: pos.accuracy,
speed: pos.speed,
heading: pos.heading,
timestamp: pos.timestamp,
);
// Távolság a legutóbbi ponttól
double segmentDist = 0;
if (_lastPoint != null) {
@ -296,7 +321,14 @@ class TrackingController extends GetxController {
pos.longitude,
);
// Szűrés: ugrásszerű változás (pl. GPS lock elvesztése) ignorálása
if (segmentDist > 100) return;
if (segmentDist > 100) {
AppLogger.w(
'_onPosition',
'GPS ugrás kiszűrve: ${segmentDist.toStringAsFixed(0)}m '
'(pts: ${livePoints.length})');
_lastPoint = point; // reset következő pont ettől mér
return;
}
}
_accumulatedDistance += segmentDist;
@ -306,16 +338,6 @@ class TrackingController extends GetxController {
currentSpeedKmh.value = (pos.speed ?? 0) * 3.6;
// Pont mentése
final point = TrackPoint(
trackId: trackId,
latitude: pos.latitude,
longitude: pos.longitude,
altitude: pos.altitude,
accuracy: pos.accuracy,
speed: pos.speed,
heading: pos.heading,
timestamp: pos.timestamp,
);
await _db.addPoint(point, _accumulatedDistance);
sw.stop();
@ -398,4 +420,61 @@ class TrackingController extends GetxController {
_trackCoords[trackId] = pts.map((p) => LatLng(p.lat, p.lon)).toList();
overlayTrackIds.refresh(); // térkép frissítés
}
void _startWatchdog() {
_watchdogTimer = Timer.periodic(
const Duration(seconds: 5),
(_) => _checkGpsTimeout(),
);
}
void _checkGpsTimeout() {
if (!isRecording.value || isPaused.value) return;
final last = _lastPositionTime;
if (last == null) return;
final elapsedSec = DateTime.now().difference(last).inSeconds;
if (elapsedSec < _gpsTimeoutSec) return;
if (!gpsSignalLost.value) {
gpsSignalLost.value = true;
AppLogger.w(
'watchdog',
'GPS jel elveszett: ${elapsedSec}s óta nincs pozíció '
'(pts: ${livePoints.length}, '
'táv: ${_formatDistance(_accumulatedDistance)})');
AppLogger.w(
'gps_signal_lost',
'elapsed_sec: ${elapsedSec}'
'point_count: ${livePoints.length}'
'distance_m: ${_accumulatedDistance.round()}');
// Foreground notification frissítése
FlutterForegroundTask.updateService(
notificationTitle: '⚠ GPS jel elveszett',
notificationText: 'Track szünetel — folytatódik ha visszajön a jel',
);
// Snackbar ha előtérben van az app
if (!isInBackground.value) {
Get.snackbar(
'GPS jel elveszett',
'Valószínűleg alagút vagy lefedettség hiány.\n'
'A rögzítés automatikusan folytatódik.',
duration: const Duration(seconds: 6),
backgroundColor: Colors.orange.shade700,
colorText: Colors.white,
icon: const Icon(Icons.gps_off, color: Colors.white),
snackPosition: SnackPosition.TOP,
);
}
}
// Folyamatosan logol amíg nincs jel (percenként egyszer)
if (elapsedSec % 60 == 0) {
AppLogger.w('watchdog', 'GPS még mindig hiányzik: ${elapsedSec}s');
}
}
}

View File

@ -25,7 +25,7 @@ class AppLogger extends GetxService {
// Konfiguráció
/// Csak fejlesztési módban logol (release build-ben kikapcsol)
static const bool _enableInRelease = false;
static const bool _enableInRelease = true;
/// Max log fájl méret MB-ban felette rotál
static const int _maxSizeMb = 5;

View File

@ -36,7 +36,8 @@ class FirebaseLogger extends GetxService {
_analytics = FirebaseAnalytics.instance;
// Crashlytics engedélyezése release-ben mindig, debug-ban opcionális
await _crashlytics.setCrashlyticsCollectionEnabled(!kDebugMode);
//await _crashlytics.setCrashlyticsCollectionEnabled(!kDebugMode);
await _crashlytics.setCrashlyticsCollectionEnabled(true);
// Eszközazonosító beállítása ha már elérhető
_setDeviceInfo();

View File

@ -1,3 +1,4 @@
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart';
@ -154,9 +155,17 @@ class AppDrawer extends StatelessWidget {
ListTile(
leading: const Icon(Icons.volume_up_outlined),
title: const Text('Hang és rezgés'),
onTap: () {
Get.back();
onTap: () async {
// Get.back();
// Get.to(() => const FeedbackSettingsView());
await FirebaseCrashlytics.instance.recordError(
Exception('Teszt hiba - breadcrumb ellenőrzés'),
StackTrace.current,
reason: 'Manuális teszt',
fatal: false);
await FirebaseCrashlytics.instance.sendUnsentReports();
Get.back();
},
),

View File

@ -70,6 +70,16 @@ class _RecordingContent extends StatelessWidget {
letterSpacing: 0.5,
),
),
const SizedBox(width: 5),
Obx(() {
if (!ctrl.gpsSignalLost.value) return const SizedBox.shrink();
return Row(children: [
Icon(Icons.gps_off, size: 12, color: Colors.orange),
const SizedBox(width: 4),
Text('GPS-ejl elveszett',
style: TextStyle(color: Colors.orange, fontSize: 10))
]);
}),
const Spacer(),
// Kártya bezárása (csak megkisebbíti, nem állítja le)
GestureDetector(