feat(04-01): add timestamp to ProcessedGpsData and precision/lifecycle constants
- Add timestamp field to ProcessedGpsData with copyWith support - Add precision switching thresholds: 3.33 m/s (12 km/h) up, 2.22 m/s (8 km/h) down - Add PRECISION_SWITCH_FIRST_FIX_DELAY (5s) to prevent early switching - Add BACKGROUND_GRACE_PERIOD (7s) for lifecycle-aware GPS management - Mark GPS_GRACE_PERIOD as deprecated in favor of BACKGROUND_GRACE_PERIOD - Change GpsService.positionStream to createPositionStream() with dynamic accuracy - Keep deprecated positionStream getter for backward compatibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,4 +19,13 @@ abstract class GpsConfig {
|
|||||||
|
|
||||||
/// Speed threshold below which heading is considered unreliable (m/s)
|
/// Speed threshold below which heading is considered unreliable (m/s)
|
||||||
static const double LOW_SPEED_THRESHOLD = 1.0;
|
static const double LOW_SPEED_THRESHOLD = 1.0;
|
||||||
|
|
||||||
|
/// Speed threshold for switching to HIGH precision (m/s) - 12 km/h
|
||||||
|
static const double PRECISION_UP_THRESHOLD_MPS = 3.33;
|
||||||
|
|
||||||
|
/// Speed threshold for switching to BALANCED precision (m/s) - 8 km/h
|
||||||
|
static const double PRECISION_DOWN_THRESHOLD_MPS = 2.22;
|
||||||
|
|
||||||
|
/// Minimum time after first fix before precision switching starts
|
||||||
|
static const Duration PRECISION_SWITCH_FIRST_FIX_DELAY = Duration(seconds: 5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,5 +15,9 @@ abstract class TimingConfig {
|
|||||||
static const Duration LONG_PRESS_SIGNAL_DELAY = Duration(milliseconds: 50);
|
static const Duration LONG_PRESS_SIGNAL_DELAY = Duration(milliseconds: 50);
|
||||||
|
|
||||||
/// GPS grace period - continues for 30s after overlay close when backgrounded
|
/// GPS grace period - continues for 30s after overlay close when backgrounded
|
||||||
|
/// DEPRECATED: Replaced by BACKGROUND_GRACE_PERIOD (7s) for lifecycle management
|
||||||
static const Duration GPS_GRACE_PERIOD = Duration(seconds: 30);
|
static const Duration GPS_GRACE_PERIOD = Duration(seconds: 30);
|
||||||
|
|
||||||
|
/// Background grace period - time before GPS stops when app backgrounded without overlay
|
||||||
|
static const Duration BACKGROUND_GRACE_PERIOD = Duration(seconds: 7);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-3
@@ -6,15 +6,24 @@ import 'config/gps_constants.dart';
|
|||||||
class GpsService {
|
class GpsService {
|
||||||
static double? _lastValidHeading;
|
static double? _lastValidHeading;
|
||||||
|
|
||||||
static Stream<Position> get positionStream {
|
/// Create a position stream with dynamic accuracy setting
|
||||||
|
static Stream<Position> createPositionStream({
|
||||||
|
LocationAccuracy accuracy = LocationAccuracy.high,
|
||||||
|
}) {
|
||||||
return Geolocator.getPositionStream(
|
return Geolocator.getPositionStream(
|
||||||
locationSettings: const LocationSettings(
|
locationSettings: LocationSettings(
|
||||||
accuracy: LocationAccuracy.bestForNavigation,
|
accuracy: accuracy,
|
||||||
distanceFilter: 0,
|
distanceFilter: 0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deprecated: Use createPositionStream() instead
|
||||||
|
@Deprecated('Use createPositionStream(accuracy: LocationAccuracy.bestForNavigation) instead')
|
||||||
|
static Stream<Position> get positionStream {
|
||||||
|
return createPositionStream(accuracy: LocationAccuracy.bestForNavigation);
|
||||||
|
}
|
||||||
|
|
||||||
static Future<bool> requestPermissions() async {
|
static Future<bool> requestPermissions() async {
|
||||||
final permission = await Permission.locationWhenInUse.request();
|
final permission = await Permission.locationWhenInUse.request();
|
||||||
return permission.isGranted;
|
return permission.isGranted;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ class ProcessedGpsData {
|
|||||||
final String displayHeading; // Formatted heading text
|
final String displayHeading; // Formatted heading text
|
||||||
final bool isSpeedValid; // True if from recent GPS
|
final bool isSpeedValid; // True if from recent GPS
|
||||||
final bool isHeadingValid; // True if from recent GPS
|
final bool isHeadingValid; // True if from recent GPS
|
||||||
|
final DateTime timestamp; // Timestamp for staleness detection
|
||||||
|
|
||||||
const ProcessedGpsData({
|
const ProcessedGpsData({
|
||||||
required this.speed,
|
required this.speed,
|
||||||
@@ -13,6 +14,7 @@ class ProcessedGpsData {
|
|||||||
required this.displayHeading,
|
required this.displayHeading,
|
||||||
required this.isSpeedValid,
|
required this.isSpeedValid,
|
||||||
required this.isHeadingValid,
|
required this.isHeadingValid,
|
||||||
|
required this.timestamp,
|
||||||
});
|
});
|
||||||
|
|
||||||
ProcessedGpsData copyWith({
|
ProcessedGpsData copyWith({
|
||||||
@@ -22,6 +24,7 @@ class ProcessedGpsData {
|
|||||||
String? displayHeading,
|
String? displayHeading,
|
||||||
bool? isSpeedValid,
|
bool? isSpeedValid,
|
||||||
bool? isHeadingValid,
|
bool? isHeadingValid,
|
||||||
|
DateTime? timestamp,
|
||||||
}) {
|
}) {
|
||||||
return ProcessedGpsData(
|
return ProcessedGpsData(
|
||||||
speed: speed ?? this.speed,
|
speed: speed ?? this.speed,
|
||||||
@@ -30,6 +33,7 @@ class ProcessedGpsData {
|
|||||||
displayHeading: displayHeading ?? this.displayHeading,
|
displayHeading: displayHeading ?? this.displayHeading,
|
||||||
isSpeedValid: isSpeedValid ?? this.isSpeedValid,
|
isSpeedValid: isSpeedValid ?? this.isSpeedValid,
|
||||||
isHeadingValid: isHeadingValid ?? this.isHeadingValid,
|
isHeadingValid: isHeadingValid ?? this.isHeadingValid,
|
||||||
|
timestamp: timestamp ?? this.timestamp,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user