deviceLocationProvider top-level property
Resolves the current device location with reverse geocoding. Handles permission requests and gracefully degrades if location is unavailable.
Implementation
final deviceLocationProvider = FutureProvider<DeviceLocation>((ref) async {
// Gather locale info (always available, no permissions needed)
final platformLocale = ui.PlatformDispatcher.instance.locale;
final language = platformLocale.languageCode;
final locale = platformLocale.toLanguageTag();
final timezone = DateTime.now().timeZoneName;
final platformName = _getPlatformName();
// Attempt to get GPS coordinates
Position? position;
String? locationError;
try {
// Check if location services are enabled
final serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
locationError = 'Location services disabled';
} else {
// Check and request permission
var permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
}
if (permission == LocationPermission.denied ||
permission == LocationPermission.deniedForever) {
locationError = 'Location permission denied';
} else {
// Get position with timeout
position = await Geolocator.getCurrentPosition(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.medium,
timeLimit: Duration(seconds: 10),
),
);
}
}
} catch (e) {
locationError = 'Location unavailable: ${e.runtimeType}';
}
// Reverse geocode if we have coordinates
String? country,
countryCode,
adminArea,
subAdminArea,
locality,
subLocality,
postalCode;
if (position != null) {
try {
final placemarks = await placemarkFromCoordinates(
position.latitude,
position.longitude,
);
if (placemarks.isNotEmpty) {
final place = placemarks.first;
country = place.country;
countryCode = place.isoCountryCode;
adminArea = place.administrativeArea;
subAdminArea = place.subAdministrativeArea;
locality = place.locality;
subLocality = place.subLocality;
postalCode = place.postalCode;
}
} catch (e) {
// Reverse geocoding failed — we still have coordinates
debugPrint('Reverse geocoding failed: $e');
}
}
return DeviceLocation(
latitude: position?.latitude,
longitude: position?.longitude,
accuracy: position?.accuracy,
country: country,
countryCode: countryCode,
administrativeArea: adminArea,
subAdministrativeArea: subAdminArea,
locality: locality,
subLocality: subLocality,
postalCode: postalCode,
timezone: timezone,
language: language,
locale: locale,
platformName: platformName,
error: locationError,
);
});