# Maneuver instructions

> **Note (legacy): A newer version of the Navigation SDK is available**
> 
> This page uses v1.6.2 of the Mapbox Navigation SDK. A newer version of the SDK is available. Learn about the latest version, v2.22.2, in the [Navigation SDK documentation](https://docs.mapbox.com/android/navigation/v2/guides/ui-components/maneuver/).

The Mapbox Navigation SDK allows you to provide voice and text instructions to your users at defined locations along a user's route.

 Navigation UI SDK

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.

> **Note**
> 
> For customizing the language used in instructions, see [Localization](https://docs.mapbox.com/android/legacy/navigation/guides/).

> **Note**
> 
> To take advantage of the Navigation SDK's observers and logic, you need to [request the location permissions](https://docs.mapbox.com/android/core/guides/#permissionsmanager) and start the trip session. Read more about managing the trip session in the [Trips guide](https://docs.mapbox.com/android/legacy/navigation/guides/trip-session/).

## Voice instructions

The Navigation SDK uses the [Mapbox Java SDK's](https://docs.mapbox.com/android/java/guides/) `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](https://docs.mapbox.com/android/legacy/navigation/guides/route-generation/) must pass `true` through the `RouteOptions.builder()`'s `voiceInstructions()` method. Read more about the [Directions API's voice instructions information](https://docs.mapbox.com/api/navigation/#voice-instruction-object).

### 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:

1.  Create the interface object:

```kotlin
val voiceInstructionsObserver = object : VoiceInstructionsObserver {
    override fun onNewVoiceInstructions(voiceInstructions: VoiceInstructions) {

    }
}
```

2.  Register the interface object with [your already-instantiated `MapboxNavigation` object](https://docs.mapbox.com/android/legacy/navigation/guides/install/#create-a-mapboxnavigation-object):

```kotlin
mapboxNavigation.registerVoiceInstructionsObserver(voiceInstructionsObserver)
```

3.  Don't forget to unregister the `VoiceInstructionsObserver` interface!:

```kotlin
override fun onStop() {
  super.onStop()
  mapView.onStop()

  mapboxNavigation.unregisterVoiceInstructionsObserver(voiceInstructionsObserver)
}
```

 Navigation UI SDK

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:

```kotlin
val speechAnnouncementListener = object: SpeechAnnouncementListener {
    override fun willVoice(announcement: VoiceInstructions?): VoiceInstructions? {
        return announcement!!
    }
}
```

Pass the `SpeechAnnouncementListener` interface object to the `NavigationViewOptions.builder()`:

```kotlin
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.

```kotlin
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](https://docs.mapbox.com/android/java/guides/) `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](https://docs.mapbox.com/api/navigation/#route-step-object) and [step maneuver](https://docs.mapbox.com/api/navigation/#step-maneuver-object).

### 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:

1.  Create the `BannerInstructionsObserver` observer:

```kotlin
val bannerInstructionsObserver = object: BannerInstructionsObserver{
  override fun willDisplay(bannerInstructions: BannerInstructions) {

  }
}
```

2.  Register the `BannerInstructionsObserver` with the Navigation SDK's `MapboxNavigation` class:

```kotlin
mapboxNavigation.registerBannerInstructionsObserver(bannerInstructionsObserver)
```

3.  Don't forget to unregister the `BannerInstructionsObserver` interface:

```kotlin
override fun onStop() {
  super.onStop()
  mapView.onStop()

  mapboxNavigation.unregisterBannerInstructionsObserver(bannerInstructionsObserver)
}
```

 Navigation UI SDK

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:

```kotlin
val bannerInstructionsListener = object: BannerInstructionsListener {
    override fun willDisplay(instructions: BannerInstructions?): BannerInstructions {
    	return instructions!!
    }
}
```

Pass the `BannerInstructionsListener` interface object to the `NavigationViewOptions.builder()`:

```kotlin
val optionsBuilder = NavigationViewOptions.builder()
optionsBuilder.navigationListener(this)
optionsBuilder.bannerInstructionsListener(bannerInstructionsListener)
navigationView.startNavigation(optionsBuilder.build())
```

### Style banner instructions

 Navigation UI SDK

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.

```xml
<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.

```kotlin
override fun onRouteProgressChanged(routeProgress: RouteProgress) {
    instructionView.updateDistanceWith(routeProgress)
}
```

Update banner instruction text with the `BannerInstructionsObserver` interface:

```kotlin
override fun onNewBannerInstructions(bannerInstructions: BannerInstructions) {
	instructionView.updateBannerInstructionsWith(bannerInstructions)
}
```

## Guidance views

 Navigation UI SDK

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.

```xml
<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:

**Java**

```java

public void onNewBannerInstructions(BannerInstructions bannerInstructions) {
  instructionView.toggleGuidanceView(bannerInstructions);
}
```

**Kotlin**

```kt

override fun onNewBannerInstructions(bannerInstructions: BannerInstructions) {
  instructionView.toggleGuidanceView(bannerInstructions)
}
```

**Using `GuidanceViewImageProvider`**

Create an instance of the complex object `GuidanceViewImageProvider`:

**Java**

```java

private GuidanceViewImageProvider imageProvider = new GuidanceViewImageProvider();
```

**Kotlin**

```kt

private val imageProvider = GuidanceViewImageProvider()
```

Create an instance of the complex object `GuidanceViewImageProvider.OnGuidanceImageDownload`:

**Java**

```java

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) {

  }
}
```

**Kotlin**

```kt

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:

**Java**

```java

public void onNewBannerInstructions(BannerInstructions bannerInstructions) {
  if (bannerInstructions != null && imageProvider != null) {
    imageProvider.renderGuidanceView(bannerInstructions, callback);
  }
}
```

**Kotlin**

```kt

override fun onNewBannerInstructions(bannerInstructions: BannerInstructions) {
  if (bannerInstructions != null && imageProvider != null) {
    imageProvider.renderGuidanceView(bannerInstructions, callback)
  }
}
```

> **Note**
> 
> `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.

> **Related content (example): [Guidance View](https://github.com/mapbox/mapbox-navigation-android/blob/v1.6.0/examples/src/main/java/com/mapbox/navigation/examples/core/GuidanceViewActivity.kt)**
> 
> See a complete working example of how to show guidance view using `InstructionView`