gps_speed_controller.dart 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import 'dart:async';
  2. import 'package:flutter/foundation.dart';
  3. import '../../data/models/gps_speed.dart';
  4. import '../../data/services/telemetry_bridge.dart';
  5. /// Polls the native GPS speed snapshot. Starting never asks for permission; it
  6. /// simply returns false when precise location is not already allowed or GPS is
  7. /// disabled.
  8. class GpsSpeedController extends ChangeNotifier {
  9. GpsSpeedController(this._platform, {DateTime Function()? clock})
  10. : _clock = clock ?? DateTime.now;
  11. final TelemetryPlatform _platform;
  12. final DateTime Function() _clock;
  13. GpsSpeed _state = const GpsSpeed();
  14. Timer? _timer;
  15. bool _active = false;
  16. bool _polling = false;
  17. bool _disposed = false;
  18. bool get hasPermission => _state.hasPermission;
  19. bool get hasSpeed => _state.isFresh(_clock());
  20. double? get speedKmh => hasSpeed ? _state.speedKmh : null;
  21. Future<void> start() async {
  22. if (_active) return;
  23. _active = true;
  24. final started = await _platform.startGpsSpeed();
  25. if (!started) {
  26. _notify();
  27. return;
  28. }
  29. _timer = Timer.periodic(const Duration(seconds: 1), (_) => _poll());
  30. await _poll();
  31. }
  32. void stop() {
  33. _active = false;
  34. _timer?.cancel();
  35. _timer = null;
  36. _state = const GpsSpeed();
  37. unawaited(_platform.stopGpsSpeed());
  38. _notify();
  39. }
  40. Future<void> _poll() async {
  41. if (!_active || _polling) return;
  42. _polling = true;
  43. try {
  44. final next = await _platform.getGpsSpeed();
  45. if (next != _state) {
  46. _state = next;
  47. _notify();
  48. }
  49. } finally {
  50. _polling = false;
  51. }
  52. }
  53. void _notify() {
  54. if (!_disposed) notifyListeners();
  55. }
  56. @override
  57. void dispose() {
  58. _disposed = true;
  59. _timer?.cancel();
  60. unawaited(_platform.stopGpsSpeed());
  61. super.dispose();
  62. }
  63. }