MobilApp/lib/services/phone_gps_source.dart

94 lines
2.8 KiB
Dart
Raw Normal View History

2026-05-10 02:31:27 +02:00
import 'dart:async';
import 'package:geolocator/geolocator.dart';
import 'location_source.dart';
/// Telefon beépített GPS-ét használó helymeghatározási forrás.
///
/// Android háttér-működéshez a [flutter_foreground_task] kezeli
/// az előtér-szolgáltatást (notification), ez az osztály csak
/// a Geolocator streamet konfigurálja.
class PhoneGpsSource implements LocationSource {
@override
String get displayName => 'Telefon GPS';
StreamController<SourcePosition>? _controller;
StreamSubscription<Position>? _positionSub;
/// Frissítési intervallum ms-ban.
final int intervalMs;
/// Minimális elmozdulás méterben új pont előtt.
final double distanceFilter;
PhoneGpsSource({
this.intervalMs = 1000,
this.distanceFilter = 1.0,
});
@override
bool get isAvailable => _controller != null && !(_controller!.isClosed);
@override
Stream<SourcePosition> get positionStream {
_controller = StreamController<SourcePosition>.broadcast();
_startListening();
return _controller!.stream;
}
Future<void> _startListening() async {
// Engedélyek ellenőrzése
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
}
if (permission == LocationPermission.deniedForever ||
permission == LocationPermission.denied) {
_controller?.addError(
Exception('Helymeghatározási engedély megtagadva. '
'Kérjük, engedélyezze a beállításokban.'),
);
return;
}
final settings = AndroidSettings(
accuracy: LocationAccuracy.high,
distanceFilter: distanceFilter.toInt(),
intervalDuration: Duration(milliseconds: intervalMs),
// Háttér-helymeghatározáshoz szükséges — a foreground_task
// notification biztosítja a jogszerű háttér-használatot.
foregroundNotificationConfig: const ForegroundNotificationConfig(
notificationText: 'Track rögzítése folyamatban',
notificationTitle: 'Terepi Segéd Nyomvonal',
enableWakeLock: true,
),
);
_positionSub = Geolocator.getPositionStream(
locationSettings: settings,
).listen(
(Position pos) {
_controller?.add(SourcePosition(
latitude: pos.latitude,
longitude: pos.longitude,
altitude: pos.altitude,
accuracy: pos.accuracy,
verticalAccuracy: pos.altitudeAccuracy,
speed: pos.speed,
heading: pos.heading,
timestamp: pos.timestamp,
source: displayName,
));
},
onError: (e) => _controller?.addError(e),
);
}
@override
Future<void> dispose() async {
await _positionSub?.cancel();
await _controller?.close();
_controller = null;
}
}