diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 68ff8ef..ffb30bc 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -480,7 +480,7 @@ class _SettingsScreenState extends State { keyboardType: TextInputType.number, decoration: const InputDecoration( labelText: 'Seconds', - helperText: 'Valid range: 10 to 31 seconds', + helperText: 'Fixed at 60 seconds', ), ), actions: [ @@ -492,7 +492,7 @@ class _SettingsScreenState extends State { onPressed: () { final parsed = int.tryParse(controller.text.trim()); if (parsed == null) return; - Navigator.pop(context, parsed.clamp(10, 31)); + Navigator.pop(context, parsed.clamp(60, 60)); }, child: const Text('Save'), ), diff --git a/lib/services/location_tracking_service.dart b/lib/services/location_tracking_service.dart index efb4699..e593a86 100644 --- a/lib/services/location_tracking_service.dart +++ b/lib/services/location_tracking_service.dart @@ -22,12 +22,18 @@ import 'profiles_feature_service.dart'; class LocationTrackingService { static const double _defaultFastLocationMovementThresholdMeters = 10.0; static const double _minFastLocationMovementThresholdMeters = 10.0; - static const int _defaultFastLocationActiveCadenceSeconds = 10; - static const int _minFastLocationActiveCadenceSeconds = 10; - static const int _maxFastLocationActiveCadenceSeconds = 31; - static const Duration _fastLocationMinimumUpdateInterval = Duration( - seconds: 31, + static const int _defaultFastLocationActiveCadenceSeconds = 60; + static const int _minFastLocationActiveCadenceSeconds = 60; + static const int _maxFastLocationActiveCadenceSeconds = 60; + static const Duration _fastLocationSlowInterval = Duration( + seconds: 60, ); + static const Duration _fastLocationWalkingInterval = Duration(seconds: 30); + static const Duration _fastLocationFastInterval = Duration(seconds: 15); + static const Duration _fastLocationVeryFastInterval = Duration(seconds: 5); + static const double _fastLocationIdleSpeedMaxMetersPerSecond = 0.75; + static const double _fastLocationWalkingSpeedMaxMetersPerSecond = 1.8; + static const double _fastLocationFastSpeedMaxMetersPerSecond = 4.0; // ============================================================================ // Singleton Pattern // ============================================================================ @@ -599,11 +605,6 @@ class LocationTrackingService { final now = DateTime.now(); final previous = _lastFastLocationSentPosition; final previousTime = _lastFastLocationSentAt; - if (previousTime != null && - now.difference(previousTime) < _fastLocationMinimumUpdateInterval) { - return; - } - if (previous != null && previousTime != null) { final distance = Geolocator.distanceBetween( previous.latitude, @@ -612,9 +613,19 @@ class LocationTrackingService { position.longitude, ); final elapsedMs = now.difference(previousTime).inMilliseconds; + final minimumInterval = _fastLocationMinimumIntervalFor( + distanceMeters: distance, + elapsedMs: elapsedMs, + ); + if (elapsedMs < minimumInterval.inMilliseconds) { + return; + } if (distance < 1.0 && elapsedMs < 3000) { return; } + } else if (previousTime != null && + now.difference(previousTime) < _fastLocationSlowInterval) { + return; } _lastFastLocationSentPosition = position; @@ -622,6 +633,26 @@ class LocationTrackingService { onFastLocationUpdate?.call(position, reason); } + Duration _fastLocationMinimumIntervalFor({ + required double distanceMeters, + required int elapsedMs, + }) { + if (elapsedMs <= 0) { + return _fastLocationSlowInterval; + } + final speedMetersPerSecond = distanceMeters / (elapsedMs / 1000.0); + if (speedMetersPerSecond < _fastLocationIdleSpeedMaxMetersPerSecond) { + return _fastLocationSlowInterval; + } + if (speedMetersPerSecond < _fastLocationWalkingSpeedMaxMetersPerSecond) { + return _fastLocationWalkingInterval; + } + if (speedMetersPerSecond < _fastLocationFastSpeedMaxMetersPerSecond) { + return _fastLocationFastInterval; + } + return _fastLocationVeryFastInterval; + } + // ============================================================================ // Mesh Network Broadcasting // ============================================================================ diff --git a/test/services/location_tracking_service_test.dart b/test/services/location_tracking_service_test.dart index 34b4c99..3eac7c2 100644 --- a/test/services/location_tracking_service_test.dart +++ b/test/services/location_tracking_service_test.dart @@ -15,7 +15,7 @@ void main() { ); service.fastLocationUpdatesEnabled = false; service.fastLocationMovementThresholdMeters = 10.0; - service.fastLocationActiveCadenceSeconds = 10; + service.fastLocationActiveCadenceSeconds = 60; service.fastLocationChannelIdx = null; }); @@ -23,7 +23,7 @@ void main() { await service.loadSettings(); expect(service.fastLocationMovementThresholdMeters, 10.0); - expect(service.fastLocationActiveCadenceSeconds, 10); + expect(service.fastLocationActiveCadenceSeconds, 60); }); test('persists and restores fast location channel idx', () async { @@ -50,6 +50,6 @@ void main() { await service.updateFastLocationActiveCadenceSeconds(45); expect(service.fastLocationMovementThresholdMeters, 10.0); - expect(service.fastLocationActiveCadenceSeconds, 31); + expect(service.fastLocationActiveCadenceSeconds, 60); }); }