import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:geolocator/geolocator.dart'; import '../models/gps_coordinate.dart'; /// خدمة GPS الحقيقي مع دعم التتبع المستمر class GpsService extends GetxService { StreamSubscription? _positionSub; final _isTracking = false.obs; final _currentPosition = Rxn(); final _lastError = ''.obs; bool get isTracking => _isTracking.value; Position? get currentPosition => _currentPosition.value; String get lastError => _lastError.value; Function(GpsCoordinate)? onNewCoordinate; Future checkAndRequestPermissions() async { if (!await Geolocator.isLocationServiceEnabled()) { _lastError.value = 'Location services disabled'; return false; } var perm = await Geolocator.checkPermission(); if (perm == LocationPermission.denied) { perm = await Geolocator.requestPermission(); if (perm == LocationPermission.denied) { _lastError.value = 'Permission denied'; return false; } } if (perm == LocationPermission.deniedForever) { _lastError.value = 'Permission permanently denied'; return false; } return true; } Future getCurrentPosition() async { try { if (!await checkAndRequestPermissions()) return null; final pos = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, timeLimit: const Duration(seconds: 15), ); _currentPosition.value = pos; return _toCoord(pos); } catch (e) { _lastError.value = e.toString(); return null; } } Future startTracking({int distanceFilter = 5}) async { if (_isTracking.value) return true; if (!await checkAndRequestPermissions()) return false; try { late LocationSettings settings; if (defaultTargetPlatform == TargetPlatform.android) { settings = AndroidSettings( accuracy: LocationAccuracy.high, distanceFilter: distanceFilter, intervalDuration: const Duration(seconds: 3), foregroundNotificationConfig: const ForegroundNotificationConfig( notificationText: 'SportPath is tracking your workout', notificationTitle: 'Workout Active', enableWakeLock: true, ), ); } else if (defaultTargetPlatform == TargetPlatform.iOS) { settings = AppleSettings( accuracy: LocationAccuracy.high, distanceFilter: distanceFilter, activityType: ActivityType.fitness, pauseLocationUpdatesAutomatically: false, showBackgroundLocationIndicator: true, ); } else { settings = LocationSettings( accuracy: LocationAccuracy.high, distanceFilter: distanceFilter, ); } _positionSub = Geolocator.getPositionStream( locationSettings: settings, ).listen(_onPosition, onError: (e) { _lastError.value = e.toString(); }); _isTracking.value = true; return true; } catch (e) { _lastError.value = e.toString(); return false; } } Future stopTracking() async { await _positionSub?.cancel(); _positionSub = null; _isTracking.value = false; } void _onPosition(Position pos) { _currentPosition.value = pos; final coord = _toCoord(pos); if (coord.isAccurate && coord.isValid) { onNewCoordinate?.call(coord); } } GpsCoordinate _toCoord(Position p) => GpsCoordinate( latitude: p.latitude, longitude: p.longitude, altitude: p.altitude, accuracy: p.accuracy, speed: p.speed >= 0 ? p.speed : null, heading: p.heading >= 0 ? p.heading : null, timestamp: p.timestamp, ); @override void onClose() { stopTracking(); super.onClose(); } }