Files
rootandClaude Sonnet 5 e3aa088bc2 Notrufnummern-Datenbasis, Ländererkennung, State-Management und Lokalisierung (AP1-AP7)
Implementiert den kompletten Kern-Flow der Emergency App gemäß docs/plan.md:
- Notrufnummern-Datenbasis für 199 Länder + Modelle/Repository (AP1)
- DialerService für tel:-Notrufe ohne Auto-Dial (AP2)
- Statisches UI mit Panik-Button-Fallback (AP3)
- Priorisierte Ländererkennung: SIM/Netz -> GPS/Geocoding -> Cache (AP4)
- EmergencyProvider verdrahtet Repository/LocationService mit der UI (AP5)
- Manuelle Länderauswahl als Fallback samt eigener Priorität (AP6)
- UI-Lokalisierung (de/en/fr/es), an erkanntes Land gekoppelt (AP7)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 11:29:38 +02:00

65 lines
2.2 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'country_code_source.dart';
/// Ermittelt den ISO-Ländercode per GPS-Position + Reverse-Geocoding
/// (`docs/plan.md`, Abschnitt 6, Fallback-Quelle Nr. 2 insbesondere auf
/// iOS 16+ wichtig, da die SIM-Quelle dort eingeschränkt ist, siehe
/// Abschnitt 9).
///
/// Nutzt bewusst nur die in `geolocator` eingebaute Berechtigungs-API
/// (`checkPermission()` / `requestPermission()`) ein zusätzlicher Einsatz
/// von `permission_handler` wäre redundant (AP4-Vorgabe).
///
/// Liefert `null`, sobald irgendein Schritt scheitert: verweigerte/dauerhaft
/// verweigerte Berechtigung, deaktivierte Standortdienste, kein GPS-Fix
/// innerhalb des Zeitlimits, oder ein Netzwerkfehler beim Reverse-Geocoding
/// (`placemarkFromCoordinates` braucht ggf. Netz). Wirft dabei nie eine
/// Exception das ist im Plan als Edge Case vorgesehen (Abschnitt 7): Die
/// Kette fällt dann weiter auf den Cache zurück.
class GpsCountryCodeSource implements CountryCodeSource {
GpsCountryCodeSource({Geocoding? geocoding}) : _geocoding = geocoding ?? Geocoding();
final Geocoding _geocoding;
static const _timeout = Duration(seconds: 10);
@override
Future<String?> resolve() async {
try {
if (!await _hasPermission()) return null;
final position = await Geolocator.getCurrentPosition(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.low,
timeLimit: _timeout,
),
);
final placemarks = await _geocoding.placemarkFromCoordinates(
position.latitude,
position.longitude,
);
for (final placemark in placemarks) {
final code = placemark.isoCountryCode?.trim();
if (code != null && code.isNotEmpty) {
return code.toUpperCase();
}
}
return null;
} catch (_) {
return null;
}
}
Future<bool> _hasPermission() async {
var permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
}
return permission == LocationPermission.whileInUse || permission == LocationPermission.always;
}
}