Maneuver instructions
The Mapbox Navigation SDK allows you to provide voice and text instructions to your users at defined locations along a user's route.
In the Navigation UI SDK banner and voice instructions are triggered by the route's waypoints. There are default styling rules for banner instructions and default settings for voice instructions. Instructions can be customized to an extent including overriding default behaviors when instructions are triggered and customizing the style of banner instructions.
Use the NavigationView
in your XML to listen to different updates or events that may occur during navigation.
Voice instructions
The Navigation SDK uses the Mapbox Java SDK's VoiceInstructions
class to hold information that should be announced out loud by the device (for example, the street that the user should stay on for a certain distance).
Request voice instructions
To include voice instructions in your route request response, your directions route request must pass true
through the RouteOptions.builder()
's voiceInstructions()
method. Read more about the Directions API's voice instructions information.
Listen to voice instructions
The VoiceInstructionsObserver
observer interface provides a VoiceInstructions
object whenever it's time to announce instructions as the user moves along a DirectionsRoute
. To listen to voice instructions:
- Create the interface object:
val voiceInstructionsObserver = object : VoiceInstructionsObserver {
override fun onNewVoiceInstructions(voiceInstructions: VoiceInstructions) {
}
}
- Register the interface object with your already-instantiated
MapboxNavigation
object:
mapboxNavigation.registerVoiceInstructionsObserver(voiceInstructionsObserver)
- Don’t forget to unregister the
VoiceInstructionsObserver
interface!:
override fun onStop() {
super.onStop()
mapView.onStop()
mapboxNavigation.unregisterVoiceInstructionsObserver(voiceInstructionsObserver)
}
The SpeechAnnouncementListener
fires when a voice announcement should be voiced out loud. The listener gives you the option to override any values and pass as the return value, which will be the value used for the voice announcement. You can return null
and the announcement will be ignored.
Create the SpeechAnnouncementListener
interface object:
val speechAnnouncementListener = object: SpeechAnnouncementListener {
override fun willVoice(announcement: VoiceInstructions?): VoiceInstructions? {
return announcement!!
}
}
Pass the SpeechAnnouncementListener
interface object to the NavigationViewOptions.builder()
:
val optionsBuilder = NavigationViewOptions.builder()
optionsBuilder.navigationListener(this)
optionsBuilder.speechAnnouncementListener(speechAnnouncementListener)
navigationView.startNavigation(optionsBuilder.build())
Customize voice instructions
Whenever the onNewVoiceInstructions
is called, you can customize the voiceInstructions
to match your need. You may replace part or all announcement text.
val voiceInstructionsObserver = object : VoiceInstructionsObserver {
override fun onNewVoiceInstructions(voiceInstructions: VoiceInstructions) {
// Replace part of the announcement text
speechPlayer.play(
VoiceInstructions.builder()
.announcement(voiceInstructions.announcement()?.replace("You have arrived", "Arrival"))
.build()
)
// Replace all announcement text
// speechPlayer.play(VoiceInstructions.builder().announcement("This is your customized announcement.").build())
}
}
Banner instructions
The Navigation SDK uses the Mapbox Java SDK's BannerInstructions
class to hold information about the next step along a directions route. The Navigation SDK uses this information to display instructions on the device's screen (for example, the name of the street a user should turn left on to and the remaining distance until that turn left maneuver).
Request banner instructions
To include banner text instructions in your route request response, your directions route request must pass true
through the RouteOptions.builder()
's bannerInstructions()
method. This will instruct the Navigation SDK to make the correct call to the Directions API. See the Directions API documentation for more information on route step and step maneuver.
Listen to banner instructions
The BannerInstructionsObserver
observer interface provides a BannerInstructions
object whenever it's time to display instructions as the user moves along a DirectionsRoute
. To listen to banner instructions:
- Create the
BannerInstructionsObserver
observer:
val bannerInstructionsObserver = object: BannerInstructionsObserver{
override fun willDisplay(bannerInstructions: BannerInstructions) {
}
}
- Register the
BannerInstructionsObserver
with the Navigation SDK'sMapboxNavigation
class:
mapboxNavigation.registerBannerInstructionsObserver(bannerInstructionsObserver)
- Don’t forget to unregister the
BannerInstructionsObserver
interface:
override fun onStop() {
super.onStop()
mapView.onStop()
mapboxNavigation.unregisterBannerInstructionsObserver(bannerInstructionsObserver)
}
The BannerInstructionsListener
fires when new text instructions are about to be displayed. The listener gives you the option to override any values and pass as the return value, which will be the value used for the voice announcement. You can return null
and the announcement will be ignored.
Create the BannerInstructionsListener
interface object:
val bannerInstructionsListener = object: BannerInstructionsListener {
override fun willDisplay(instructions: BannerInstructions?): BannerInstructions {
return instructions!!
}
}
Pass the BannerInstructionsListener
interface object to the NavigationViewOptions.builder()
:
val optionsBuilder = NavigationViewOptions.builder()
optionsBuilder.navigationListener(this)
optionsBuilder.bannerInstructionsListener(bannerInstructionsListener)
navigationView.startNavigation(optionsBuilder.build())
Style banner instructions
You also have the option to add the custom View
s used in the turn-by-turn UI to your XML. The InstructionView
is the parent View
that displays the maneuver image and instruction text.
<com.mapbox.navigation.ui.instruction.InstructionView
android:id="@+id/instructionView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Once inflated in your layout, the InstructionView
can be updated with RouteProgress
information via the RouteProgressObserver
callback.
override fun onRouteProgressChanged(routeProgress: RouteProgress) {
instructionView.updateDistanceWith(routeProgress)
}
Update banner instruction text with the BannerInstructionsObserver
interface:
override fun onNewBannerInstructions(bannerInstructions: BannerInstructions) {
instructionView.updateBannerInstructionsWith(bannerInstructions)
}
Guidance views
As the user approaches junctions in specific geographies, the Navigation UI SDK can show an enlarged illustration of the junction to help the user understand a complex maneuver. These guidance views require some additional setup and appear when the relevant data is available.
You can show the guidance views in two different ways:
Using InstructionView
Add the InstructionView
to your XML layout file.
<com.mapbox.navigation.ui.instruction.InstructionView
android:id="@+id/instructionView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Create the BannerInstructionsObserver
observer and register it as shown above. Inside onNewBannerInstructions
do the following:
public void onNewBannerInstructions(BannerInstructions bannerInstructions) {
instructionView.toggleGuidanceView(bannerInstructions);
}
override fun onNewBannerInstructions(bannerInstructions: BannerInstructions) {
instructionView.toggleGuidanceView(bannerInstructions)
}
Using GuidanceViewImageProvider
Create an instance of the complex object GuidanceViewImageProvider
:
private GuidanceViewImageProvider imageProvider = new GuidanceViewImageProvider();
private val imageProvider = GuidanceViewImageProvider()
Create an instance of the complex object GuidanceViewImageProvider.OnGuidanceImageDownload
:
private GuidanceViewImageProvider.OnGuidanceImageDownload callback = new GuidanceViewImageProvider.OnGuidanceImageDownload() {
@Override
public void onGuidanceImageReady(@NotNull Bitmap bitmap) {
// Show guidance view image here
}
@Override
public void onNoGuidanceImageUrl() {
}
@Override
public void onFailure(@Nullable String message) {
}
}
private val callback = object: GuidanceViewImageProvider.OnGuidanceImageDownload() {
override fun onGuidanceImageReady(bitmap: Bitmap) {
// Show guidance view image here
}
override fun onNoGuidanceImageUrl() {
}
override fun onFailure(message: String?) {
}
}
Inside your activity where you have created the BannerInstructionsObserver
, invoke the appropriate API:
public void onNewBannerInstructions(BannerInstructions bannerInstructions) {
if (bannerInstructions != null && imageProvider != null) {
imageProvider.renderGuidanceView(bannerInstructions, callback);
}
}
override fun onNewBannerInstructions(bannerInstructions: BannerInstructions) {
if (bannerInstructions != null && imageProvider != null) {
imageProvider.renderGuidanceView(bannerInstructions, callback)
}
}
BannerInstructions
contain the guidance image URL as an object. You can parse the banner instruction to get the URL and render it using any image rendering library. But, the URL obtained from BannerInstruction
is not enough to request the image on its own. There are appropriate headers and other parameters that are required to be added to the URL so you need to use either InstructionView
or GuidanceViewImageProvider
to render the guidance images.See a complete working example of how to show guidance view using InstructionView