2

I’m using the Google Navigation SDK for Android together with the Routes API - directions/v2:computeRoutes. From computeRoutes I get two routes: the default one and an alternate. I want to navigate using the alternate (not the fastest), so I take its routeToken and pass it to the navigator.

However, even when I redeem the token and start guidance, the SDK still navigates along what looks like the fastest route (highway) instead of the alternate route I picked.

Minimal code (simplified):

@SuppressLint("MissingPermission")
private fun startNavigationWithRouteToken(originLat: Double, originLng: Double) {
    val token = routeTokenArg ?: return toast("Missing route token")
    if (!::navigator.isInitialized) return toast("Navigator not ready yet")
    if (!mLocationPermissionGranted) return toast("Location permission required")

    val destLat = destLatArg ?: return toast("Missing destination lat")
    val destLng = destLngArg ?: return toast("Missing destination lng")

    val currentLatLng = getCurrentDeviceLatLng()
    val isNearOrigin = currentLatLng != null && metersBetween(
        currentLatLng.latitude, currentLatLng.longitude,
        originLat, originLng
    ) < 100 // Example threshold: 100 meters


    if (isNearOrigin) {
        // User is close to the route's original start. Redeem the token.
        Log.d(TAG, "User is near origin. Attempting to redeem route token.")

        val originWp = Waypoint.Builder().setLatLng(originLat, originLng).build()
        val destWp = Waypoint.Builder().setLatLng(destLat, destLng).build()

        val custom = CustomRoutesOptions.builder()
            .setRouteToken(token)
            .setTravelMode(CustomRoutesOptions.TravelMode.DRIVING)
            .build()

        navigator.setDestinations(listOf(originWp, destWp), custom)
            .setOnResultListener { code ->
                if (code == Navigator.RouteStatus.OK) {
                    Log.d(TAG, "Token redemption successful. Starting guidance.")
                    navigator.setAudioGuidance(Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE)
                    navigator.startGuidance()
                } else {
                    Log.e(TAG, "Token redemption failed ($code). Falling back to live route.")
                    toast("Failed to use preferred route. Starting live navigation.")
                }
            }
    } else {
        // User is NOT near the origin. Don't use the token;
        Log.d(TAG, "User is not near origin. Starting live navigation without token.")
        toast("Starting live navigation from current location.")
    }
}

What I expect: The Navigator follows the route described by the routeToken from the alternate route I selected.

What actually happens: Guidance starts, but the SDK appears to choose the fastest route instead of the alternative one.

Logs I see:

User is near origin. Attempting to redeem route token.

Token redemption successful. Starting guidance.

Difference between routes:

1st distance 79 kilometers, duration 52 min 34 sec

2nd (Alernate) distance 57 kilometers, duration 1 hour

What I’ve tried:

Using the routeToken from the alternate route with setDestinations(..., CustomRoutesOptions).

(Alternative approach) Converting the entire chosen polyline into many stopover waypoints and calling setDestinations(waypoints, RoutingOptions). This roughly forces the path, but I don’t like this solution—it's brittle, hits waypoint limits, and defeats the purpose of using route tokens.

Questions:

1.) Is setDestinations(listOf(origin, dest), CustomRoutesOptions(routeToken)) the correct way to redeem a token for a route that starts at that origin? Or should I pass only the destination waypoint when using a routeToken (i.e., origin comes from current GPS and must not be supplied as a waypoint)?

2.) Does the routeToken guarantee that the Navigator will follow the exact path, or is it only a plan/objective that the SDK can adjust (e.g., due to traffic, incidents, or slight start-location differences)?

3.) If I want to force the alternate route I picked (not the fastest), what is the supported way to do that with Navigation SDK?

Any guidance or official docs clarifying how to make the Navigator respect the selected route (vs. re-choosing the fastest) would be greatly appreciated.

4
  • Can you confirm whether the route token is used in Nav SDK immediately (within seconds) after being generated in the Routes API, or if there's a significant delay (minutes) between generation and use? Commented Aug 25 at 1:50
  • Thanks for the question. It’s only a few seconds from generating the route and token to starting navigation. I’d say at most 20 seconds, but I’ve also tried a shorter gap, like 5 seconds. Commented Aug 25 at 16:36
  • 1
    I believe there's already an existing report like this in the Google Issue Tracker and is currently being handled. You may refer to this link instead: issuetracker.google.com/issues/434092486 Commented Aug 27 at 2:00
  • Yes, that's the same issue I'm facing. Thanks! Commented Aug 27 at 11:01

1 Answer 1

0

Use of setDestinations with a Route Token

Yes—passing both origin and destination waypoints alongside the CustomRoutesOptions containing your route token is the correct pattern

code:

navigator.setDestinations(listOf(originWp, destWp), customRoutesOptions)

As confirmed in the official Plan a route guide, you must use the same destination waypoints that were used when generating the token via computeRoutes

Sign up to request clarification or add additional context in comments.

1 Comment

There’s a small gap between them, so I added 'isNearOrigin', but the gap is less than a few meters. I also refactored the code to use the 'placeId' to generate routes and start navigation, but it didn’t help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.