Skip to main content

Migrate to Navigation SDK v3

Mapbox Navigation SDK v3 for Android is a new generation of the core functionality that was available in Navigation SDK v2. To install the latest version of the SDK, follow the installation instructions and use this guide to update your application from v2 to v3. Note that the API of Mapbox Navigation SDK v3 is not stable yet, the guide describes migration to the latest version and will be updated in case of API changes.

Requirements changes

Navigation SDK v2 used to support NDK 21. The new Navigation SDK v3 is compatible with applications that use NDK 23. Other major versions of the NDK are not guaranteed to be compatible.

Artifacts

v2

In Navigation SDK v2, all features were available under one Maven artifact: com.mapbox.navigation:android:${version}.

Besides the one grouping artifact, there were also multiple granular ones that you were able to pick-and-choose:

  • com.mapbox.navigation:core
  • com.mapbox.navigation:copilot
  • com.mapbox.navigation:ui-maps
  • com.mapbox.navigation:ui-voice
  • com.mapbox.navigation:ui-maneuver
  • com.mapbox.navigation:ui-shields
  • com.mapbox.navigation:ui-speedlimit
  • com.mapbox.navigation:ui-tripprogress
  • com.mapbox.navigation:ui-status
  • com.mapbox.navigation:ui-dropin

v3

In the new SDK, the package structure remains unchanged in some areas, but significant modifications have been implemented in others. The most notable alterations were applied to the UI modules, see Migrate UI components section for more information.

As before, you can either add one artifact and use all the available features com.mapbox.navigationcore:android:${version} or choose multiple granular artifacts that you need. In the table below, you will find the previous module name and its corresponding counterpart in the Navigation SDK v3:

Navigation SDK v2Navigation SDK v3
com.mapbox.navigation:corecom.mapbox.navigationcore:navigation
com.mapbox.navigation:copilotcom.mapbox.navigationcore:copilot
com.mapbox.navigation:ui-mapscom.mapbox.navigationcore:ui-maps
com.mapbox.navigation:ui-shieldscom.mapbox.navigationcore:tripdata
com.mapbox.navigation:ui-voiceCore: com.mapbox.navigationcore:voice, UI: com.mapbox.navigationcore:ui-components
com.mapbox.navigation:ui-maneuverCore: com.mapbox.navigationcore:tripdata, UI: com.mapbox.navigationcore:ui-components
com.mapbox.navigation:ui-speedlimitCore: com.mapbox.navigationcore:tripdata, UI: com.mapbox.navigationcore:ui-components
com.mapbox.navigation:ui-tripprogressCore: com.mapbox.navigationcore:tripdata, UI: com.mapbox.navigationcore:ui-components
com.mapbox.navigation:ui-statuscom.mapbox.navigationcore:ui-components
com.mapbox.navigation:ui-androidautocom.mapbox.navigationcore:android-auto-components
com.mapbox.navigation:ui-dropinRemoved

Dependencies

Maps SDK

The Navigation SDK v3 uses the Mapbox Maps SDK v11, as opposed to Maps SDK v10 in the Navigation SDK v2. Maps SDK v11 offers the new Mapbox Standard and Standard Satellite styles support, new 3D features, improved performance and a lot more.

Maps SDK v11 is a SEMVER major release with breaking API changes. If the application you are migrating uses a map, make sure you read the Maps SDK migration guide before reading the navigation-specific content below.

GUIDE
Migrate to v11

Upgrade your application from the Mapbox Maps SDK for Android v10 to v11.

Kotlin

The Navigation SDK v3 only uses Kotlin, the official language recommended by Google for Android development. It was compiled using Kotlin 1.7.20, and has binary compatibility with Kotlin compiler 1.6 and above.

Major changes in the Navigation SDK v3 since Navigation SDK v2

Access token

NavigationOptions#accessToken parameter was removed. Now access token will be read from mapbox_access_token string resource. Add a mapbox_access_token.xml file to your project to the following location: src/main/res/values/mapbox_access_token.xml with the following contents:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="mapbox_access_token" translatable="false" tools:ignore="UnusedResources">YOUR_ACCESS_TOKEN</string>
</resources>

You can also set the token via:

MapboxOptions.accessToken = YOUR_TOKEN

and change it in runtime. First, the token from MapboxOptions will be used. If it's not set, it will be read from resources.

Similarly, access token parameter was removed from the following APIs:

  • MapboxManeuverApi#getRoadShields method;
  • MapboxJunctionApi constructor;
  • MapboxRestAreaApi constructor;
  • MapboxSignboardApi constructor;
  • MapboxRouteShieldApi#getRouteShields method;
  • MapboxSpeechApi constructor.

Location API

Location options

NavigationOptions#locationEngine and NavigationOptions#locationEngineRequest were replaced with NavigationOptions#locationOptions. Here's how you can migrate in different cases:

  1. If you want to use everything that is default, don't set location options. Default request is:

    LocationProviderRequest.Builder()
    .interval(
    IntervalSettings.Builder()
    .minimumInterval(500)
    .interval(1000L)
    .build()
    )
    .accuracy(AccuracyLevel.HIGH)
    .build()
  2. If you want to customize the request and use the default location provider, set the options in the following way:

    NavigationOptions.Builder()
    .locationOptions(
    LocationOptions.Builder()
    .request(myRequest)
    .build()
    )
  3. If you want to use a custom provider, do this:

    NavigationOptions.Builder()
    .locationOptions(
    LocationOptions.Builder()
    .locationProviderFactory(
    DeviceLocationProviderFactory { request ->
    ExpectedFactory.createValue(MyLocationProvider(request))
    },
    LocationProviderType.<YOUR_TYPE>
    )
    .build()
    )

Here MyLocationProvider implements DeviceLocationProvider. Note that together with DeviceLocationProviderFactory, you have to pass a LocationProviderType. It can be either REAL, MOCKED or MIXED.

Use REAL if your location provider emits only real locations, where the device really is.

Use MOCKED if your location provider emits only mocked/simulated locations. Can be used for cases with location simulations, replay, etc.

Use MIXED if your provider emits both mocked and real locations. Can be used for cases when you need to switch location providers in runtime, for example, if you have a toggle that enables/disables location simulation.

Note that if you have MOCKED or MIXED type, the non-real locations must have isMock extra flag set to true. Real locations must either have it set to false or not set at all. To set this flag, use:

Location.Builder()
.extra(
Value.valueOf(
hashMapOf(
LocationExtraKeys.IS_MOCK to Value.valueOf(true/false)
)
)
)
  1. If you want the locations to be replayed by the NavSDK, you used to have:
val mapboxReplayer = MapboxReplayer()
...
NavigationOptions.Builder(context)
.locationEngine(ReplayLocationEngine(mapboxReplayer))
...
mapboxNavigation.startTripSession()

Now you can replace it with:

// use the mapboxReplayer instance that NavSDK created for you:
val mapboxReplayer = mapboxNavigation.mapboxReplayer
...
NavigationOptions.Builder(context)
// no location options
...
// this is important: this invocation will tell NavSDK to start using mapboxReplayer instead of real location engine
mapboxNavigation.startReplayTripSession()
..
// you can use the mapboxReplayer in the same way you used to, neither its API nor its behaviour have changed

Puck

Location component puck bearing enabled property (MapView.location.puckBearingEnabled) has been changed to false by default. Enable it manually when setting up the puck. For example, if you had:

binding.mapView.location.apply {
setLocationProvider(navigationLocationProvider)
enabled = true
}

Change it to:

binding.mapView.location.apply {
setLocationProvider(navigationLocationProvider)
puckBearingEnabled = true
enabled = true
}
  • NavigationOptions#locationEngine and NavigationOptions#locationEngineRequest were replaced with NavigationOptions#locationOptions.
  • android.location.Location was replaced with com.mapbox.common.location.Location everywhere in the public API.
  • ReplayLocationEngine was replaced with ReplayLocationProvider.
  • context parameter was removed from MapboxReplayer#pushRealLocation method.

Custom Router

In the Navigation SDK v3 you can no longer use a custom router implementation. Navigation SDK v3 will now define the way routes are built. It has a hybrid router implementation that works the following way:

  1. It requests the route from the Mapbox Directions API if the connectivity is available.
  2. It generates the route locally on the device if the SDK had a chance to cache the routing resources. This is a fallback if there's no connectivity.

If you want to mock routes in tests, you can use our new Test Router artifact:

  1. Add a dependency:
    androidTestImplementation("com.mapbox.navigationcore:test-router:${version}")
  2. Add a custom router rule to your test:
    @get:Rule
    val navigationRouterRule = createNavigationRouterRule()
  3. (Optionally) set a getRoute handler:
    navigationRouterRule.setRouter(
    object : MapboxNavigationTestRouter {
    override fun getRoute(
    routeOptions: RouteOptions,
    callback: RouterCallback
    ) {
    if (routeOptions == testRouteOptions) {
    callback.onRoutesReady(mockRoute.routeResponse)
    } else {
    callback.onFailure(TestRouterFailure.noRoutesFound())
    }
    }
    }
    )
  4. (Optionally) Set a getRouteRefresh handler:
    navigationRouterRule.setRouteRefresher(
    object : MapboxNavigationTestRouteRefresher {
    override fun getRouteRefresh(
    options: RefreshOptions,
    callback: RouteRefreshCallback
    ) {
    if (options.responseUUID == mockRoute.routeResponse.uuid()) {
    callback.onRefresh(mockRoute.routeResponse.routes()[options.routeIndex])
    } else {
    callback.onFailure(TestRefresherFailure.serverError())
    }
    }
    }
    )
Custom routerTest router
Where it is usedanywheretests only
Can mock route responsesyesyes
Can mock route refresh responsesyesyes
Can mock online routesyesyes
Can mock offline routesyesno

The old and the new approaches are compared in the table above. Now all online route and route refresh requests to Mapbox Directions API will be intercepted by provided MapboxNavigationTestRouter and MapboxNavigationTestRouteRefresher. To test offline scenarios, you need to download tiles and build real offline routes onboard. This way you will make sure that your app is compatible with the SDK's offline logic.

RouterOrigin

RouterOrigin is now an annotation which defines possible string values for router origin. RouterOrigin.Offboard and RouterOrigin.Onboard have been renamed to RouterOrigin.ONLINE and RouterOrigin.OFFLINE respectively. RouterOrigin.Custom has been removed.

Removed API

UI/UX modules

The com.mapbox.navigation:ui-status and com.mapbox.navigation:ui-dropin artifacts were removed. UI widgets were removed from the com.mapbox.navigation:ui-maps, com.mapbox.navigation:ui-voice, com.mapbox.navigation:ui-maneuver, com.mapbox.navigation:ui-shields, com.mapbox.navigation:ui-speedlimit, com.mapbox.navigation:ui-tripprogress.

You can look at the Navigation SDK v2 repository and copy some of the UI-related source code to your project.

  • Removed OnlineRouteAlternativesSwitch. Use NavigationRouteAlternativesObserver to receive an online alternative for the current offline route. Unlike OnlineRouteAlternativesSwitch, NavigationRouteAlternativesObserver doesn't switch to an online alternative automatically, so you have to do it yourself.

Deprecations

Deprecated classes, functions and fields have been removed. See the Navigation SDK v2 documentation for more information about missing parts and migration guides.

Alternatives Observer

NavigationRouteAlternativesObserver, RouteAlternativesObserver, NavigationRouteAlternativesRequestCallback, MapboxNavigation#registerRouteAlternativesObserver, MapboxNavigation#requestAlternativeRoutes were removed in favor of automatic alternatives update.

Now Navigation SDK automatically updates alternative routes and switches to an online alternative in case of an offline primary route. Register RoutesObserver to keep track of current routes. Use MapboxNavigation#setContinuousAlternativesEnabled to enable/disable automatic update.

Buildings API

  1. BuildingValue#buildings now returns List<QueriedRenderedFeature> instead of List<QueriedFeature>.
  2. MapboxBuildingView#highlightBuilding now accepts a List<QueriedRenderedFeature> instead of List<QueriedFeature>. No app-side migration is required when this method is used together with MapboxBuildingsApi.

Speed Limit API

MapboxSpeedInfoApi#updatePostedAndCurrentSpeed now returns a nullable value when current speed information is not available. Replace:

val value = speedInfoApi.updatePostedAndCurrentSpeed(
locationMatcherResult,
distanceFormatterOptions
)
speedInfoView.render(value)

with:

val value = speedInfoApi.updatePostedAndCurrentSpeed(
locationMatcherResult,
distanceFormatterOptions
)
value?.let { speedInfoView.render(it) }

Routes generation

NavigationRoute#create function have been removed, now Navigation SDK doesn't allow to create NavigationRoute from JSON or from custom DirectionsRoute object anymore. Use MapboxNavigation#requestRoutes and MapboxNavigation#requestMapMatching to request NavigationRoutes from Mapbox Services.

Bring your own route

Navigation SDK v3 doesn't accept custom DirectionsRoute objects anymore, but there are still a few options for bringing a route with custom geometry in Nav SDK v3:

  1. Mapbox Directions API request with silent waypoints, see MapboxNavigation#requestRoutes and RouteOptions.Builder#waypointIndicesList. This parameter can be used to guide the path of the route without introducing additional legs and arrival or departure instructions.
  2. Mapbox Map Matching API request, see MapboxNavigation#requestMapMatching. This tool allows you to generate a route that directly matches a custom path or a trace to the road network.

Creation and destroy of MapboxNavigation

MapboxNavigation constructor and onDestroy methods are now internal. To create or destroy an instance of MapboxNavigation use MapboxNavigationProvider. For example, if you used to have:

val mapboxNavigation = MapboxNavigation(options)
...
mapboxNavigation.onDestroy()

, replace it with:

val mapboxNavigation = MapboxNavigationProvider.create(options)
...
MapboxNavigationProvider.destroy()

Mapbox Map Matching API support on the SDK level

Mapbox Map Matching API is supported on the SDK level. If you navigated using map matched routes, replace usage of Mapbox Java API by the usage of the SDK API. Instead of:

val mapMatching = MapboxMapMatching.builder()
.accessToken(getMapboxAccessTokenFromResources())
.coordinates(
listOf(
Point.fromLngLat(-117.17282, 32.71204),
Point.fromLngLat(-117.17288, 32.71225),
Point.fromLngLat(-117.17293, 32.71244),
)
)
.build()
mapMatching.enqueueCall(object : Callback<MapMatchingResponse> {
override fun onResponse(
call: Call<MapMatchingResponse>,
response: Response<MapMatchingResponse>
) {
mapboxNavigation.setRoutes(
response.body()?.matchings()?.map { it.toDirectionRoute() }
?: emptyList()
)
}

override fun onFailure(call: Call<MapMatchingResponse>, throwable: Throwable) {

}
})

do:

val options = MapMatchingOptions.Builder()
.coordinates("-117.17282,32.71204;-117.17288,32.71225;-117.17293,32.71244")
.build()
mapboxNavigation.requestMapMatching(
options,
object : MapMatchingAPICallback {
override fun success(result: MapMatchingSuccessfulResult) {
mapboxNavigation.setNavigationRoutes(result.navigationRoutes)
}

override fun failure(failure: MapMatchingFailure) {
}
override fun onCancel() {
}
}
)

Mapbox Map Matching API requests made by the Navigation SDK during an Active Guidance or Free Drive navigation session are included free of charge.

Related API changes:

  • NavigationRoute#directionsResponse has been removed. Use NavigationRoute#waypoints and NavigationRoute#responseUUID to access data which used to be available via NavigationRoute#directionsResponse.
  • NavigationRoute#routeOptions has been removed. Try to use data available in NavigationRoute, for example instead of using coordinates from route options, use NavigationRoute#waypoints.
  • Temporary property NavigationRoute#evMaxCharge has been added to access maximum possible charge for the vehicle the route was requested for instead of navigationRoute.routeOptions.getUnrecognizedProperty("ev_max_charge").

MapboxRouteLineApi

  1. MapboxRouteLineOptions.Builder#withRouteLineBelowLayerId to MapboxRouteLineViewOptions.Builder#routeLineBelowLayerId;
  2. MapboxRouteLineOptions.Builder#withTolerance to MapboxRouteLineViewOptions.Builder#tolerance;
  3. MapboxRouteLineOptions.Builder#withVanishingRouteLineEnabled to MapboxRouteLineApiOptions.Builder#vanishingRouteLineEnabled;
  4. MapboxRouteLineOptions#styleInactiveRouteLegsIndependently, MapboxRouteLineOptions#vanishingRouteLineEnabled and MapboxRouteLineOptions#vanishingRouteLineUpdateIntervalNano to MapboxRouteLineApiOptions.
  5. MapboxRouteLineOptions#softGradientTransition, MapboxRouteLineOptions#displaySoftGradientForTraffic, MapboxROuteLineOptions#shareLineGeometrySources, MapboxRouteLineOptions#lineDepthOcclusionFactor, MapboxRouteLineOptions#waypointLayerIconOffset, MapboxRouteLineOptions#waypointLayerIconAnchor and MapboxRouteLineOptions#iconPitchAlignment to MapboxRouteLineViewOptions.
  • Removed RouteLineResources class:
  1. routeLineColorResources, originWaypointIcon, destinationWaypointIcon, restrictedRoadDashArray, restrictedRoadOpacity and restrictedRoadLineWidth were moved to MapboxRouteLineViewOptions
  2. trafficBackfillRoadClasses was moved to MapboxRouteLineApiOptions
  3. scaleExpression properties were moved to MapboxRouteLineViewOptions#scaleExpressions wrapper of type RouteLineScaleExpressions
  4. roundedLineCap property was removed
  • Moved congestionRange properties from RouteLineColorResources to MapboxRouteLineApiOptions.
  • Removed MapboxRouteLineOptions#routeStyleDescriptors option.
  • Removed the possibility of modify and reading data from RouteLineSetValue, RouteLineClearValue and RouteLineUpdateValue. Do not use these classes on your side, pass the objects between MapboxRouteLineApi and MapboxRouteLineView instead.
  • MapboxRouteLineAPI#options and MapboxRouteLineView#options properties are no longer public.
  • Made RouteLineExpressionProvider and RouteLineTrimExpressionProvider internal.
  • Added a possibility to change a subset of MapboxRouteLineViewOptions in runtime without the need to recreate the components. The subset that can be changed is defined in MapboxRouteLineViewDynamicOptionsBuilder. To change the dynamic options in runtime, use the following code:
routeLineView.updateDynamicOptions(style) {
routeLineColorResources(newColors)
// ...
}
routeLineApi.getRouteDrawData {
routeLineView.renderRouteDrawData(style, it)
}

Android Auto

The Android Auto was moved to the new package com.mapbox.navigation.ui.androidauto.

A version of Android Auto artifact is matched with Nav SDK artifact, they are released at the same time.

Migrate UI components

In Navigation SDK v3 for Android the structure and organization of the UI components have been changed:

  • UI Components Consolidation: UI components that were available via multiple modules in v2 have been consolidated into a single module called ui-components in v3.
  • Logic Separation: In v3, the UI components logic has been extracted into a new module called tripdata. This module provides convenient API to request trip related data and can be used as a standalone tool alongside custom UI components tailored to specific use cases.
  • Drop-In UI is not available in Navigation SDK v3 for Android. Reach out to our support team if you need any help.

Migration Steps

1. Update Dependencies.

  • UI widgets from com.mapbox.navigation:ui-maneuver, com.mapbox.navigation:ui-speedlimit, com.mapbox.navigation:ui-tripprogress, com.mapbox.navigation:ui-status modules have been moved to the new com.mapbox.navigationcore:ui-components module, core logic has been moved to com.mapbox.navigationcore:tripdata.
  • com.mapbox.navigation:ui-shields did not provide any UI widgets in v2, its core logic has been moved to com.mapbox.navigationcore:tripdata module.
  • UI widgets like MapboxRecenterButton and MapboxRouteOverviewButton from com.mapbox.navigation:ui-maps module have been moved to com.mapbox.navigationcore:ui-components module, other functionality like MapboxRouteLineView is now available in com.mapbox.navigationcore:ui-maps module.
  • UI widgets from com.mapbox.navigation:ui-voice have been moved to com.mapbox.navigationcore:ui-components module. Voice-related core functionality is available in com.mapbox.navigationcore:voice module.

See artifacts table to find the previous module name and its corresponding counterpart in the Navigation SDK v3, and installation guide for more information on how to properly set up repositories to access SDK artifacts and add required dependencies.

2. Package structure change in Navigation SDK v3.

  • Base package for UI components classes has been changed from com.mapbox.navigation.ui to com.mapbox.navigation.ui.components. For example, com.mapbox.navigation.ui.maneuver.view.MapboxManeuverView has been moved to com.mapbox.navigation.ui.components.maneuver.view.MapboxManeuverView.
  • Base package for core related classes is also changed from com.mapbox.navigation.ui to com.mapbox.navigation.tripdata. For example, com.mapbox.navigation.ui.maneuver.api.MapboxLaneIconsApi, has been moved to com.mapbox.navigation.tripdata.maneuver.api.MapboxLaneIconsApi
  • Base package for voice-related core functionality from ui-voice package is now com.mapbox.navigation.voice. For example, com.mapbox.navigation.ui.voice.api.MapboxSpeechApi has been moved to com.mapbox.navigation.voice.api.MapboxSpeechApi.

3. Replace deprecated UI Components.

Review your existing code that uses deprecated UI components and functions from v2 and replace them with their equivalents in v3.

4. Centralized access token handling.

Navigation SDK v3 now uses a centralized approach for accessing the Mapbox access token. Update your implementation to use the new method of providing the access token. See Access token section for more information.

Was this page helpful?