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>
9.8 KiB
Google Navigation Flutter Setup Guide
This document provides detailed instructions for completing the Google Navigation Flutter implementation.
Overview
The implementation includes:
- Location permissions handling with user dialogs
- Google Navigation session management
- Turn-by-turn navigation for delivery destinations
- Terms and Conditions acceptance for navigation services
- i18n support (English/French)
- Proper error handling and logging
Prerequisites
Before implementing, you need:
- Google Cloud Project with Navigation SDK enabled
- API Keys for both Android and iOS platforms
- Configuration in Android and iOS native files
Part 1: API Key Configuration
Android Setup
- Open
android/app/build.gradle.kts - Add your Android API key to the metadata section in
AndroidManifest.xml:
<application>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_ANDROID_API_KEY" />
</application>
Alternatively, use Secrets Gradle Plugin for better security:
// In android/app/build.gradle.kts
android {
buildTypes {
debug {
manifestPlaceholders = [googleMapsApiKey: "YOUR_ANDROID_API_KEY"]
}
release {
manifestPlaceholders = [googleMapsApiKey: "YOUR_ANDROID_API_KEY_RELEASE"]
}
}
}
Then in AndroidManifest.xml:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${googleMapsApiKey}" />
iOS Setup
- Open
ios/Runner/AppDelegate.swift - The API key is already configured in the
provideAPIKey()method:
import GoogleMaps
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("YOUR_IOS_API_KEY")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Replace YOUR_IOS_API_KEY with your actual Google Cloud Navigation API key.
Part 2: Integration with Deliveries Page
To add navigation button to deliveries, update lib/pages/deliveries_page.dart:
import '../pages/navigation_page.dart';
// In your delivery item or action menu:
ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => NavigationPage(
delivery: delivery,
destinationLatitude: delivery.latitude,
destinationLongitude: delivery.longitude,
onNavigationComplete: () {
// Handle navigation completion
// Update delivery status
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
AppLocalizations.of(context)?.navigationArrived ??
'Navigation completed',
),
),
);
},
onNavigationCancelled: () {
// Handle cancellation
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
AppLocalizations.of(context)?.cancel ?? 'Navigation cancelled',
),
),
);
},
),
),
);
},
child: Text(AppLocalizations.of(context)?.navigateToAddress ?? 'Navigate'),
)
Part 3: Location Permissions
The app uses the permission_handler package for location permissions. Permissions are already configured in:
-
Android:
android/app/src/main/AndroidManifest.xml- Required:
INTERNET,ACCESS_FINE_LOCATION,ACCESS_COARSE_LOCATION - Optional background modes for continuous navigation
- Required:
-
iOS:
ios/Runner/Info.plistNSLocationWhenInUseUsageDescription: When app is activeNSLocationAlwaysAndWhenInUseUsageDescription: AlwaysNSLocationAlwaysUsageDescription: Background location- Background mode: "location" enabled
Part 4: Available Classes and Services
NavigationPage
Main UI widget for turn-by-turn navigation.
NavigationPage(
delivery: deliveryObject,
destinationLatitude: 33.5731,
destinationLongitude: -7.5898,
onNavigationComplete: () { /* Handle arrival */ },
onNavigationCancelled: () { /* Handle cancellation */ },
)
LocationPermissionService
Handles location permission requests and checks.
final permissionService = LocationPermissionService();
// Check current permission status
final hasPermission = await permissionService.hasLocationPermission();
// Request permission
final result = await permissionService.requestLocationPermission();
result.when(
granted: () { /* Permission granted */ },
denied: () { /* Permission denied */ },
permanentlyDenied: () { /* Need to open settings */ },
error: (message) { /* Handle error */ },
);
NavigationSessionService
Manages the Google Navigation session lifecycle.
final sessionService = NavigationSessionService();
// Initialize session
await sessionService.initializeSession();
// Set controller from the navigation view
await sessionService.setController(navigationViewController);
// Calculate and set route
final route = await sessionService.calculateRoute(
startLatitude: 33.5731,
startLongitude: -7.5898,
destinationLatitude: 33.5745,
destinationLongitude: -7.5850,
);
// Listen to events
sessionService.addArrivalListener((info) {
print('Arrived at destination');
});
sessionService.addLocationListener((location) {
print('Location: ${location.latitude}, ${location.longitude}');
});
// Start/stop navigation
await sessionService.startNavigation();
await sessionService.stopNavigation();
// Cleanup when done
await sessionService.cleanup();
NavigationTermsAndConditionsDialog
Dialog component to show T&C for navigation services.
showDialog(
context: context,
builder: (context) => NavigationTermsAndConditionsDialog(
onAccept: () {
// Save acceptance and proceed with navigation
},
onDecline: () {
// User declined, don't start navigation
},
),
);
Part 5: Error Handling
The implementation includes comprehensive error handling for:
-
Location Permission Errors
- Permission denied
- Permission permanently denied
- System errors
-
Navigation Initialization Errors
- Session initialization failure
- Controller not available
- Route calculation failure
-
Runtime Errors
- Network issues
- Location acquisition timeout
- Navigation start/stop failures
All errors are displayed through user-friendly dialogs with action buttons.
Part 6: Internationalization
Navigation strings are available in English and French:
navigationTcTitle,navigationTcDescriptionlocationPermissionRequired,locationPermissionMessagenavigationArrived,navigatingTo
Add custom translations to lib/l10n/app_*.arb files as needed.
Part 7: Testing Checklist
Android Testing
- Test on API level 23+ device
- Verify minSdk=23 is set
- Check desugaring is enabled
- Test location permissions request
- Verify navigation starts correctly
- Test with GPS disabled/enabled
- Verify Terms & Conditions dialog shows
iOS Testing
- Test on iOS 16.0+ device
- Verify Info.plist has all location keys
- Test location permissions request
- Verify background location mode is enabled
- Test navigation with map open
- Verify arrival notification
- Check attribution text is visible
Common Issues and Solutions
Issue: "Navigation SDK not available"
- Solution: Verify API key is correctly added and Navigation SDK is enabled in Google Cloud Console
Issue: "Location permission always denied"
- Solution: Clear app data and reinstall, or open app settings and manually enable location
Issue: "Navigation session fails to initialize"
- Solution: Check that controller is properly created before calling methods
Issue: "Routes not calculating"
- Solution: Ensure start and destination coordinates are valid and within service areas
Part 8: Production Considerations
Before releasing to production:
-
API Key Security
- Use separate API keys for Android and iOS
- Restrict API keys by platform and package name
- Rotate keys periodically
-
Analytics
- Track navigation start/completion rates
- Monitor location permission denial rates
- Log any navigation errors
-
User Experience
- Provide clear instructions for permission requests
- Show progress during initialization
- Handle network failures gracefully
-
Compliance
- Ensure proper attribution to Google
- Display Terms & Conditions for navigation
- Comply with EEA data regulations if applicable
Files Created/Modified
Created Files
lib/services/location_permission_service.dart- Permission handlinglib/services/navigation_session_service.dart- Session managementlib/pages/navigation_page.dart- Navigation UIlib/components/navigation_tc_dialog.dart- T&C dialog
Modified Files
android/app/build.gradle.kts- Added minSdk=23, desugaringios/Podfile- iOS configuration (already set)ios/Runner/Info.plist- Location permissions (updated)lib/l10n/app_en.arb- English translationslib/l10n/app_fr.arb- French translations
Next Steps
- Add your API keys to Android and iOS configurations
- Test location permissions flow
- Integrate navigation button into delivery items
- Test navigation on real devices
- Monitor and handle edge cases in production
For more information, refer to: