85 lines
2.3 KiB
Dart
85 lines
2.3 KiB
Dart
import 'dart:async';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:latlong2/latlong.dart';
|
|
|
|
class LocationService {
|
|
static final LocationService _instance = LocationService._internal();
|
|
factory LocationService() => _instance;
|
|
LocationService._internal();
|
|
|
|
static LocationService get instance => _instance;
|
|
|
|
LatLng? _currentLocation;
|
|
Timer? _locationTimer;
|
|
bool _isLocationPermissionGranted = false;
|
|
final StreamController<LatLng?> _locationStreamController =
|
|
StreamController<LatLng?>.broadcast();
|
|
|
|
Stream<LatLng?> get locationStream => _locationStreamController.stream;
|
|
LatLng? get currentLocation => _currentLocation;
|
|
bool get isLocationPermissionGranted => _isLocationPermissionGranted;
|
|
|
|
Future<void> initialize() async {
|
|
await _requestLocationPermission();
|
|
if (_isLocationPermissionGranted) {
|
|
await _getCurrentLocation();
|
|
_startLocationUpdates();
|
|
}
|
|
}
|
|
|
|
Future<void> _requestLocationPermission() async {
|
|
try {
|
|
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
|
if (!serviceEnabled) {
|
|
return;
|
|
}
|
|
|
|
LocationPermission permission = await Geolocator.checkPermission();
|
|
if (permission == LocationPermission.denied) {
|
|
permission = await Geolocator.requestPermission();
|
|
}
|
|
|
|
if (permission == LocationPermission.deniedForever) {
|
|
return;
|
|
}
|
|
|
|
_isLocationPermissionGranted = true;
|
|
} catch (e) {}
|
|
}
|
|
|
|
Future<void> _getCurrentLocation() async {
|
|
if (!_isLocationPermissionGranted) return;
|
|
|
|
try {
|
|
Position position = await Geolocator.getCurrentPosition(
|
|
desiredAccuracy: LocationAccuracy.high,
|
|
forceAndroidLocationManager: true,
|
|
);
|
|
|
|
_currentLocation = LatLng(position.latitude, position.longitude);
|
|
_locationStreamController.add(_currentLocation);
|
|
} catch (e) {}
|
|
}
|
|
|
|
void _startLocationUpdates() {
|
|
_locationTimer?.cancel();
|
|
_locationTimer = Timer.periodic(const Duration(seconds: 30), (timer) {
|
|
if (_isLocationPermissionGranted) {
|
|
_getCurrentLocation();
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> forceUpdateLocation() async {
|
|
if (!_isLocationPermissionGranted) {
|
|
await _requestLocationPermission();
|
|
}
|
|
await _getCurrentLocation();
|
|
}
|
|
|
|
void dispose() {
|
|
_locationTimer?.cancel();
|
|
_locationStreamController.close();
|
|
}
|
|
}
|