Skip to content

Commit 8292ae1

Browse files
authored
feat!: upgrade Nav SDKs to Android 7.6.0 and iOS 10.12.0 (#571)
BREAKING CHANGE: continueToNextDestination() now returns ContinueToNextDestinationResponse containing waypoint and routeStatus
1 parent 72069ca commit 8292ae1

File tree

15 files changed

+368
-88
lines changed

15 files changed

+368
-88
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ const {
628628
| `setDestinations(destinations: Waypoint[], routingOptions?, displayOptions?)` | `Promise<RouteStatus>` | Set navigation destinations |
629629
| `setDestination(waypoint: Waypoint, routingOptions?, displayOptions?)` | `Promise<RouteStatus>` | Set a single navigation destination |
630630
| `clearDestinations()` | `Promise<void>` | Clear all destinations |
631-
| `continueToNextDestination()` | `Promise<void>` | Navigate to the next destination in the list |
631+
| `continueToNextDestination()` | `Promise<ContinueToNextDestinationResponse>` | Navigate to the next destination in the list |
632632
| `startGuidance()` | `Promise<void>` | Start turn-by-turn navigation guidance |
633633
| `stopGuidance()` | `Promise<void>` | Stop navigation guidance |
634634
| `getCurrentTimeAndDistance()` | `Promise<TimeAndDistance \| null>` | Get time and distance to current destination |

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ dependencies {
5858
implementation "androidx.car.app:app:1.4.0"
5959
implementation "androidx.car.app:app-projected:1.4.0"
6060
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
61-
implementation "com.google.android.libraries.navigation:navigation:7.5.0"
61+
implementation "com.google.android.libraries.navigation:navigation:7.6.0"
6262
api 'com.google.guava:guava:31.0.1-android'
6363
}

android/src/main/java/com/google/android/react/navsdk/NavModule.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -670,8 +670,14 @@ public void continueToNextDestination(final Promise promise) {
670670
if (!ensureNavigatorAvailable(promise)) {
671671
return;
672672
}
673-
mNavigator.continueToNextDestination();
674-
promise.resolve(true);
673+
Waypoint nextWaypoint = mNavigator.continueToNextDestination();
674+
WritableMap result = Arguments.createMap();
675+
if (nextWaypoint != null) {
676+
result.putMap("waypoint", ObjectTranslationUtil.getMapFromWaypoint(nextWaypoint));
677+
} else {
678+
result.putNull("waypoint");
679+
}
680+
promise.resolve(result);
675681
}
676682

677683
@Override

example/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ dependencies {
153153
implementation "androidx.car.app:app-projected:1.4.0"
154154

155155
// Include the Google Navigation SDK.
156-
implementation 'com.google.android.libraries.navigation:navigation:7.5.0'
156+
implementation 'com.google.android.libraries.navigation:navigation:7.6.0'
157157
}
158158

159159
secrets {

example/src/controls/navigationControls.tsx

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@ import {
2929
type CameraPosition,
3030
type NavigationController,
3131
type DisplayOptions,
32-
RouteStatus,
3332
} from '@googlemaps/react-native-navigation-sdk';
3433
import SelectDropdown from 'react-native-select-dropdown';
3534

3635
import { ControlStyles } from '../styles/components';
36+
import {
37+
handleRouteStatus,
38+
handleContinueToNextDestination,
39+
} from '../helpers/navigationUtils';
3740

3841
export interface NavigationControlsProps {
3942
readonly navigationController: NavigationController;
@@ -106,35 +109,6 @@ const NavigationControls: React.FC<NavigationControlsProps> = ({
106109
const [latitude, onLatChanged] = useState('');
107110
const [longitude, onLngChanged] = useState('');
108111

109-
const handleRouteStatus = (routeStatus: RouteStatus) => {
110-
switch (routeStatus) {
111-
case RouteStatus.OK:
112-
showSnackbar('Route created successfully');
113-
break;
114-
case RouteStatus.ROUTE_CANCELED:
115-
Alert.alert('Error', 'Route Cancelled');
116-
break;
117-
case RouteStatus.NO_ROUTE_FOUND:
118-
Alert.alert('Error', 'No Route Found');
119-
break;
120-
case RouteStatus.NETWORK_ERROR:
121-
Alert.alert('Error', 'Network Error');
122-
break;
123-
case RouteStatus.LOCATION_DISABLED:
124-
Alert.alert('Error', 'Location Disabled');
125-
break;
126-
case RouteStatus.LOCATION_UNKNOWN:
127-
Alert.alert('Error', 'Location Unknown');
128-
break;
129-
case RouteStatus.DUPLICATE_WAYPOINTS_ERROR:
130-
Alert.alert('Error', 'Consecutive duplicate waypoints are not allowed');
131-
break;
132-
default:
133-
showSnackbar('Route status: ' + routeStatus);
134-
Alert.alert('Error', 'Starting Guidance Error');
135-
}
136-
};
137-
138112
const disposeNavigation = async () => {
139113
try {
140114
await navigationController.cleanup();
@@ -222,8 +196,9 @@ const NavigationControls: React.FC<NavigationControlsProps> = ({
222196
onFollowingPerspectiveChange?.(_index);
223197
};
224198

225-
const continueToNextDestination = () => {
226-
navigationController.continueToNextDestination();
199+
const continueToNextDestination = async () => {
200+
const response = await navigationController.continueToNextDestination();
201+
await handleContinueToNextDestination(navigationController, response);
227202
};
228203

229204
const startGuidance = () => {
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Copyright 2026 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { Alert } from 'react-native';
18+
import {
19+
RouteStatus,
20+
type NavigationController,
21+
type ContinueToNextDestinationResponse,
22+
} from '@googlemaps/react-native-navigation-sdk';
23+
import { showSnackbar } from './snackbar';
24+
25+
/**
26+
* Handles a RouteStatus result from setDestinations or continueToNextDestination.
27+
* Shows appropriate user feedback and returns whether the route was successful.
28+
*
29+
* @param routeStatus - The route status to handle.
30+
* @returns true if the route status is OK, false otherwise.
31+
*/
32+
export const handleRouteStatus = (routeStatus: RouteStatus): boolean => {
33+
switch (routeStatus) {
34+
case RouteStatus.OK:
35+
showSnackbar('Route created successfully');
36+
return true;
37+
case RouteStatus.ROUTE_CANCELED:
38+
Alert.alert('Error', 'Route Cancelled');
39+
return false;
40+
case RouteStatus.NO_ROUTE_FOUND:
41+
Alert.alert('Error', 'No Route Found');
42+
return false;
43+
case RouteStatus.NETWORK_ERROR:
44+
Alert.alert('Error', 'Network Error');
45+
return false;
46+
case RouteStatus.LOCATION_DISABLED:
47+
Alert.alert('Error', 'Location Disabled');
48+
return false;
49+
case RouteStatus.LOCATION_UNKNOWN:
50+
Alert.alert('Error', 'Location Unknown');
51+
return false;
52+
case RouteStatus.DUPLICATE_WAYPOINTS_ERROR:
53+
Alert.alert('Error', 'Consecutive duplicate waypoints are not allowed');
54+
return false;
55+
default:
56+
showSnackbar('Route status: ' + routeStatus);
57+
Alert.alert('Error', 'Starting Guidance Error');
58+
return false;
59+
}
60+
};
61+
62+
/**
63+
* Handles the response from continueToNextDestination.
64+
*
65+
* Checks the route status (if available, i.e. on iOS) and stops guidance
66+
* on failure. Returns the response for further processing.
67+
*
68+
* @param navigationController - The navigation controller instance.
69+
* @param response - The response from continueToNextDestination.
70+
* @returns true if navigation can continue, false if it was aborted.
71+
*/
72+
export const handleContinueToNextDestination = async (
73+
navigationController: NavigationController,
74+
response: ContinueToNextDestinationResponse
75+
): Promise<boolean> => {
76+
// If routeStatus is available (iOS), check for errors
77+
if (response.routeStatus !== undefined) {
78+
if (!handleRouteStatus(response.routeStatus)) {
79+
await navigationController.stopGuidance();
80+
return false;
81+
}
82+
}
83+
84+
if (response.waypoint === null) {
85+
showSnackbar('No more waypoints remaining');
86+
await navigationController.stopGuidance();
87+
return false;
88+
}
89+
90+
return true;
91+
};

example/src/screens/IntegrationTestsScreen.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ const IntegrationTestsScreen = () => {
8686
navigationController,
8787
setOnNavigationReady,
8888
setOnArrival,
89+
setOnLocationChanged,
8990
setOnRemainingTimeOrDistanceChanged,
9091
setOnRouteChanged,
9192
} = useNavigation();
@@ -219,6 +220,7 @@ const IntegrationTestsScreen = () => {
219220
setOnArrival,
220221
setOnRemainingTimeOrDistanceChanged,
221222
setOnRouteChanged,
223+
setOnLocationChanged,
222224
passTest,
223225
failTest,
224226
setDetoxStep,

example/src/screens/MultipleMapsScreen.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
import MapsControls from '../controls/mapsControls';
4343
import NavigationControls from '../controls/navigationControls';
4444
import OverlayModal from '../helpers/overlayModal';
45+
import { handleContinueToNextDestination } from '../helpers/navigationUtils';
4546
import { showSnackbar } from '../helpers/snackbar';
4647
import { CommonStyles, ControlStyles } from '../styles/components';
4748
import { MapStylingOptions } from '../styles/mapStyling';
@@ -123,14 +124,19 @@ const MultipleMapsScreen = () => {
123124

124125
// Set up callbacks that depend on navigationController
125126
useEffect(() => {
126-
setOnArrival((event: ArrivalEvent) => {
127+
setOnArrival(async (event: ArrivalEvent) => {
127128
if (event.isFinalDestination) {
128129
navigationController.stopGuidance();
130+
showSnackbar('Arrived at final destination');
129131
} else {
130-
navigationController.continueToNextDestination();
131-
navigationController.startGuidance();
132+
const response = await navigationController.continueToNextDestination();
133+
if (
134+
await handleContinueToNextDestination(navigationController, response)
135+
) {
136+
navigationController.startGuidance();
137+
showSnackbar('Arrived, continuing to next destination');
138+
}
132139
}
133-
showSnackbar('Arrived');
134140
});
135141

136142
setOnRemainingTimeOrDistanceChanged(timeAndDistance => {

example/src/screens/NavigationScreen.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import NavigationActionPath, {
4646
ActionPathStep,
4747
} from '../controls/NavigationActionPath';
4848
import OverlayModal from '../helpers/overlayModal';
49+
import { handleContinueToNextDestination } from '../helpers/navigationUtils';
4950
import { showSnackbar, Snackbar } from '../helpers/snackbar';
5051
import { CommonStyles, MapStyles } from '../styles/components';
5152
import { MapStylingOptions } from '../styles/mapStyling';
@@ -191,14 +192,19 @@ const NavigationScreen = () => {
191192

192193
// Set up callbacks that depend on navigationController
193194
useEffect(() => {
194-
setOnArrival((event: ArrivalEvent) => {
195+
setOnArrival(async (event: ArrivalEvent) => {
195196
if (event.isFinalDestination) {
196197
navigationController.stopGuidance();
198+
showSnackbar('Arrived at final destination');
197199
} else {
198-
navigationController.continueToNextDestination();
199-
navigationController.startGuidance();
200+
const response = await navigationController.continueToNextDestination();
201+
if (
202+
await handleContinueToNextDestination(navigationController, response)
203+
) {
204+
navigationController.startGuidance();
205+
showSnackbar('Arrived, continuing to next destination');
206+
}
200207
}
201-
showSnackbar('Arrived');
202208
});
203209

204210
setOnRemainingTimeOrDistanceChanged(timeAndDistance => {

0 commit comments

Comments
 (0)