import 'dart:async'; import 'package:geolocator/geolocator.dart'; import 'package:permission_handler/permission_handler.dart'; import 'config/gps_constants.dart'; class GpsService { static double? _lastValidHeading; /// Create a position stream with dynamic accuracy setting static Stream createPositionStream({ LocationAccuracy accuracy = LocationAccuracy.high, }) { return Geolocator.getPositionStream( locationSettings: LocationSettings( accuracy: accuracy, distanceFilter: 0, ), ); } /// Deprecated: Use createPositionStream() instead @Deprecated('Use createPositionStream(accuracy: LocationAccuracy.bestForNavigation) instead') static Stream get positionStream { return createPositionStream(accuracy: LocationAccuracy.bestForNavigation); } static Future requestPermissions() async { final permission = await Permission.locationWhenInUse.request(); return permission.isGranted; } static Future isLocationServiceEnabled() async { return await Geolocator.isLocationServiceEnabled(); } static double getCachedHeading(double heading) { if (heading >= GpsConfig.VALID_HEADING_MIN && heading <= GpsConfig.VALID_HEADING_MAX) { _lastValidHeading = heading; return heading; } return _lastValidHeading ?? 0.0; } static String getCompassDirection(double heading) { final cachedHeading = getCachedHeading(heading); const directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']; final index = ((cachedHeading + 22.5) / 45).floor() % 8; return directions[index]; } static String formatHeading(double heading) { final cachedHeading = getCachedHeading(heading); return '${cachedHeading.round()} ${getCompassDirection(heading)}'; // don't add that degree symbol, this is cooler } }