Adds complete Google Navigation support with: - LocationPermissionService for runtime location permissions - NavigationSessionService for session and route management - NavigationPage for full-screen turn-by-turn navigation UI - NavigationTermsAndConditionsDialog for service acceptance - Comprehensive i18n support (English/French) - Android minSdk=23 with Java NIO desugaring - iOS location permissions in Info.plist - Error handling with user-friendly dialogs - Location update and arrival notifications Includes detailed setup guide and implementation documentation with API key configuration instructions, integration examples, and testing checklist. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
71 lines
2.0 KiB
Dart
71 lines
2.0 KiB
Dart
import 'package:permission_handler/permission_handler.dart';
|
|
|
|
class LocationPermissionService {
|
|
static const String _tcKey = 'navigation_tc_accepted';
|
|
|
|
Future<LocationPermissionResult> requestLocationPermission() async {
|
|
final status = await Permission.location.request();
|
|
|
|
return switch (status) {
|
|
PermissionStatus.granted => LocationPermissionResult.granted(),
|
|
PermissionStatus.denied => LocationPermissionResult.denied(),
|
|
PermissionStatus.permanentlyDenied =>
|
|
LocationPermissionResult.permanentlyDenied(),
|
|
_ => LocationPermissionResult.error(
|
|
message: 'Unexpected permission status: $status',
|
|
),
|
|
};
|
|
}
|
|
|
|
Future<bool> hasLocationPermission() async {
|
|
final status = await Permission.location.status;
|
|
return status.isGranted;
|
|
}
|
|
|
|
Future<void> openAppSettings() async {
|
|
await openAppSettings();
|
|
}
|
|
}
|
|
|
|
sealed class LocationPermissionResult {
|
|
const LocationPermissionResult();
|
|
|
|
factory LocationPermissionResult.granted() => _Granted();
|
|
factory LocationPermissionResult.denied() => _Denied();
|
|
factory LocationPermissionResult.permanentlyDenied() =>
|
|
_PermanentlyDenied();
|
|
factory LocationPermissionResult.error({required String message}) =>
|
|
_Error(message);
|
|
|
|
R when<R>({
|
|
required R Function() granted,
|
|
required R Function() denied,
|
|
required R Function() permanentlyDenied,
|
|
required R Function(String message) error,
|
|
}) {
|
|
return switch (this) {
|
|
_Granted() => granted(),
|
|
_Denied() => denied(),
|
|
_PermanentlyDenied() => permanentlyDenied(),
|
|
_Error(:final message) => error(message),
|
|
};
|
|
}
|
|
}
|
|
|
|
final class _Granted extends LocationPermissionResult {
|
|
const _Granted();
|
|
}
|
|
|
|
final class _Denied extends LocationPermissionResult {
|
|
const _Denied();
|
|
}
|
|
|
|
final class _PermanentlyDenied extends LocationPermissionResult {
|
|
const _PermanentlyDenied();
|
|
}
|
|
|
|
final class _Error extends LocationPermissionResult {
|
|
final String message;
|
|
const _Error(this.message);
|
|
}
|