- Removed
NavigationOptions#accessToken. Now access token will be read frommapbox_access_tokenstring resource. Add amapbox_access_token.xmlfile to your project to the following location:src/main/res/values/mapbox_access_token.xmlwith 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, removed access token parameter from the following APIs:
NavigationViewconstructor. Also, it's not possible to set it via xml anymore, i. e.app:access_tokenattribute is removed from<com.mapbox.navigation.dropin.NavigationView>xml tag.MapboxManeuverApi#getRoadShieldsmethod.MapboxJunctionApiconstructor.MapboxAreaApiconstructor.MapboxSignboardApiconstructor.MapboxRouteShieldApi#getRouteShieldsmethod.MapboxSpeechApiconstructor.
- Replaced
NavigationOptions#locationEngineandNavigationOptions#locationEngineRequestwithNavigationOptions#locationOptions.
- If you want to use everything that is default, just don't set location options. Default request is:
LocationProviderRequest.Builder()
.interval(
IntervalSettings.Builder()
.minimumInterval(500)
.interval(1000L)
.build()
)
.accuracy(AccuracyLevel.HIGH)
.build()
- If you want to customize the request and use default provider, set the options in the following way:
NavigationOptions.Builder()
.locationOptions(
LocationOptions.Builder()
.request(myRequest)
.build()
)
- 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()
)
, where 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 actually is.
Use MOCKED if you 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))))
- 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
and
- Replaced
android.location.Locationwithcom.mapbox.common.location.Locationeverywhere in the public API. - Replaced
ReplayLocationEnginewithReplayLocationProvider. - Removed
contextparameter fromMapboxReplayer#pushRealLocationmethod. BuildingValue#buildingsnow returnsList<QueriedRenderedFeature>instead ofList<QueriedFeature>.MapboxBuildingView#highlightBuildingnow accepts a listList<QueriedRenderedFeature>instead ofList<QueriedFeature>. No app-side migration is required when this method is used together withMapboxBuildingsApi.- Removed
contextparameter fromLocationPuckOptions.Builder#regularPuckmethod. MapboxSpeedInfoApi#updatePostedAndCurrentSpeednow returns a nullable a 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) }
- 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
}
- Use
CustomRouterRulein order to setup test routes in instrumentation tests instead of custom implementation ofRouter. AddTest routerdependency to your tests:
androidTestImplementation(com.mapbox.navigationcore:testing-router:${navigation_core_version})
Add custom router rule to your test:
@get:Rule
val navigationRouterRule = createNavigationRouterRule()
Set get route and get router refresh handlers:
navigationRouterRule.setRouter(object : MapboxNavigationTestRouter {
override fun getRoute(routeOptions: RouteOptions, callback: RouterCallback) {
if (routeOptions == testRouteOptions) {
callback.onRoutesReady(mockRoute.routeResponse)
} else {
callback.onFailure(TestRouterFailure.noRoutesFound())
}
}
})
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())
}
}
})
Now all online route and route refresh requests to Mapbox Directions API will be intercepted by provided MapboxNavigationTestRouter and MapboxNavigationTestRouteRefresher.
CustomRouterRule lets users mock only online routes.
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.
-
Deprecated classes, functions and fields have been removed. See Nav SDK v2 documentation for more information about missing parts and migration guides.
-
com.mapbox.navigation.core.reroute.NavigationRerouteControllerhas been merged withcom.mapbox.navigation.core.reroute.RerouteController. -
MapboxNavigationconstructor andonDestroymethods are now internal. To create or destroy an instance ofMapboxNavigationuseMapboxNavigationProvider. For example, if you used to have:
val mapboxNavigation = MapboxNavigation(options)
...
mapboxNavigation.onDestroy(), replace it with:
val mapboxNavigation = MapboxNavigationProvider.create(options)
...
MapboxNavigationProvider.destroy()- Introduced support of Mapbox Map Matching API on Nav SDK level. If you navigated using map matched routes, replace usage of Mapbox Java API by the usage of Nav 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.matches)
}
override fun failure(failure: MapMatchingFailure) {
}
override fun onCancel() {
}
}
)-
NavigationRoutecan be created only viaMapboxNavigation. Consider requesting routes from Mapbox Directions API usingMapboxNavigation#requestRoutesor from Mapbox Map Matching API. If you need to passNavigationRouteinstance between processes which use the same version of Navigation Core Framework, consider usingNavigationRoute#serializeandNavigationRoute#deserializeFrom. -
UI functionality from
libnavui-maps,libnavui-voice,libnavui-tripprogress,libnavui-maneuver,libnavui-speedlimit,libnavui-statushas been moved into new modulelibnavui-ui-components. -
Core functionality from
libnavui-shield,libnavui-tripprogress,libnavui-maneuver,libnavui-speedlimithas been moved into new moduletripdata. -
Modules
libnavui-app,libnavui-dropinhave been removed. See Navigation SDK v2 repository if you need to copy UI sources to your projects. -
Module
libnavui-voicehas been renamed tovoice. Package name has been changed tocom.mapbox.navigation.voice. -
Added "mbx.RouteLine" history events. They will be collected automatically by Core Framework for both manual recorder and Copilot recorder when the recording is started. You can enable route line events collection for Copilot using
CopilotOptions#shouldRecordRouteLineEventsoption. It is disabled by default. -
Made
RouteShieldError#urlandRouteShieldOrigin#originalUrlnullable. They can be null in case the request had been cancelled before the URL was formed.
- Split
MapboxRouteLineOptionsintoMapboxRouteLineApiOptionsandMapboxRouteLineViewOptions. If you used to have:
val options = MapboxRouteLineOptions.Builder(this)
.withRouteLineResources(
RouteLineResources.Builder()
.routeLineColorResources(
RouteLineColorResources.Builder()
.inActiveRouteLegsColor(Color.YELLOW)
.inactiveRouteLegCasingColor(Color.RED)
.routeLineTraveledColor(Color.CYAN)
.routeLineTraveledCasingColor(Color.BLACK)
.lowCongestionRange(0..29)
.moderateCongestionRange(30..49)
.heavyCongestionRange(50..79)
.severeCongestionRange(80..100)
.build()
)
.trafficBackfillRoadClasses(backfillRoadClasses)
.originWaypointIcon(R.drawable.origin)
.destinationWaypointIcon(R.drawable.destination)
.routeLineScaleExpression(routeLineScaleExpression)
.restrictedRoadDashArray(dashArray)
.restrictedRoadOpacity(0.7)
.restrictedRoadLineWidth(2.1)
.build()
)
.withRouteLineBelowLayerId("road-label-navigation")
.styleInactiveRouteLegsIndependently(true)
.withVanishingRouteLineEnabled(true)
.vanishingRouteLineUpdateInterval(interval)
.withTolerance(tolerance)
.displayRestrictedRoadSections(true)
.softGradientTransition(30)
.displaySoftGradientForTraffic(true)
.iconPitchAlignment(IconPitchAlignment.MAP)
.waypointLayerIconOffset(offset)
.waypointLayerIconAnchor(IconAnchor.BOTTOM_LEFT)
.shareLineGeometrySources(true)
.lineDepthOcclusionFactor(0.85)
.build()
val routeLineApi = MapboxRouteLineApi(options)
val routeLineView = MapboxRouteLineView(options)change it to:
val apiOptions = MapboxRouteLineApiOptions.Builder()
.lowCongestionRange(0..29)
.moderateCongestionRange(30..49)
.heavyCongestionRange(50..79)
.severeCongestionRange(80..100)
.styleInactiveRouteLegsIndependently(true)
.vanishingRouteLineEnabled(true)
.vanishingRouteLineUpdateIntervalNano(interval)
.calculateRestrictedRoadSections(true)
.trafficBackfillRoadClasses(backfillRoadClasses)
.build()
val viewOptions = MapboxRouteLineViewOptions.Builder(context)
.routeLineColorResources(
RouteLineColorResources.Builder()
.inActiveRouteLegsColor(Color.YELLOW)
.inactiveRouteLegCasingColor(Color.RED)
.routeLineTraveledColor(Color.CYAN)
.routeLineTraveledCasingColor(Color.BLACK)
.build()
)
.originWaypointIcon(R.drawable.origin)
.destinationWaypointIcon(R.drawable.destination)
.scaleExpressions(routeLineScaleExpression)
.restrictedRoadDashArray(dashArray)
.restrictedRoadOpacity(0.7)
.restrictedRoadLineWidth(2.1)
.routeLineBelowLayerId("road-label-navigation")
.tolerance(tolerance)
.displayRestrictedRoadSections(true)
.softGradientTransition(30.0)
.displaySoftGradientForTraffic(true)
.iconPitchAlignment(IconPitchAlignment.MAP)
.waypointLayerIconOffset(offset)
.waypointLayerIconAnchor(IconAnchor.BOTTOM_LEFT)
.shareLineGeometrySources(true)
.lineDepthOcclusionFactor(0.85)
.build()
val routeLineApi = MapboxRouteLineApi(apiOptions)
val routeLineView = MapboxRouteLineView(viewOptions)Note that if you had MapboxRouteLineOptions#displayRestrictedRoadSections set to true, you must set it to true for both MapboxRouteLineApiOptions#calculateRestrictedRoadSections and MapboxRouteLineViewOptions#displayRestricetdRoadSections.
You can have a set-up where some of your MapboxRouteLineViews display the restricted data and others don't. Set MapboxRouteLineApiOptions#calculateRestrictedRoadSections if at least one of your MapboxRouteLineViews will display the restricted data. Set MapboxRouteLineViewOptions#displayRestrictedRoadSections only to those views, who are going to display it.
Removed API:
RouteLineResources#roundedLineCapMapboxRouteLineOptions#routeStyleDescriptors- Removed the possibility of modify and reading data from
RouteLineSetValue,RouteLineClearValueandRouteLineUpdateValue. Do not use these classes on your side, just pass the objects betweenMapboxRouteLineAPIandMapboxRouteLineView. MapboxRouteLineAPI#optionsandMapboxRouteLineView#optionsproperties are no longer public.- Made
RouteLineExpressionProviderandRouteLineTrimExpressionProviderinternal. MapboxRouteLineApi#showRouteWithLegIndexHighlightedMapboxRouteLineApi#setPrimaryTrafficColor- useMapboxRouteLineView#updateDynamicOptionsto change primary traffic color.MapboxRouteLineApi#setAlternativeTrafficColor- useMapboxRouteLineView#updateDynamicOptionsto change alternative traffic color.
- Added a possibility to change a subset of
MapboxRouteLineViewOptionsin runtime without the need to recreate the components. The subset that can be changed is defined inMapboxRouteLineViewDynamicOptionsBuilder. To change the dynamic options in runtime, use the following code:
routeLineView.updateDynamicOptions(style) {
routeLineColorResources(newColors)
// ...
}
routeLineApi.getRouteDrawData {
routeLineView.renderRouteDrawData(style, it)
}
Similarly, split RouteLineConfig#options into RouteLineConfig#apiOptions and RouteLineConfig#viewOptions and added RouteLineConfig#viewOptionsUpdates.