deviceLocationProvider top-level property

FutureProvider<DeviceLocation> deviceLocationProvider
final

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,
  );
});