> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/navigation/v2/llms.txt)

# Route progress

Once turn-by-turn navigation begins, your project will need to follow the user's progress along the route to deliver contextual information in the correct way at the correct time. The Navigation SDK's `RouteProgress` object contains this information and this page teaches you about using it.

## Levels of route progress

The Mapbox Navigation SDK's model for tracking route progress has three pieces with different levels of granularity: the route, the leg, and the step.

**Route**: The blue line is a route. A route stretches between the origin and the final destination.

**Leg**: The *larger* circles with a pink stroke represent waypoints, or stops, along the route. A leg is the part of the route between two waypoints.

**Step**: The *smaller* circles with a green stroke represent maneuvers. A step is the part of the leg between two maneuvers.

The Navigation SDK uses three classes to communicate information on the user's progress at these three different levels: `RouteProgress`, `RouteLegProgress`, and `RouteStepProgress`.

### `RouteProgress`

The `RouteProgress` class contains all the progress information at any time during a navigation session. A new `RouteProgress` object is generated whenever there's a new valid `Location` update or if no new `Location` update is received in the past second.

`RouteProgress` information includes distance measurements, the percentage of the route that's been completed, the current step index, the remaining number of route legs, and much more. For further information on data encapsulated in `RouteProgress`, you can view the [API reference docs](https://docs.mapbox.com/android/navigation/v2/api/2.22.2/libnavigation-base/com.mapbox.navigation.base.trip.model/-route-progress/) here.

### `RouteLegProgress`

The `RouteLegProgress` class is specific to the current leg the user is on. For further information on data encapsulated in `RouteLegProgress`, you can view the [API reference docs](https://docs.mapbox.com/android/navigation/v2/api/2.22.2/libnavigation-base/com.mapbox.navigation.base.trip.model/-route-leg-progress/) here.

### `RouteStepProgress`

The `RouteStepProgress` class is a progress object specific to the current step the user is on. For further information on data encapsulated in `RouteStepProgress`, you can view the [API reference docs](https://docs.mapbox.com/android/navigation/v2/api/2.22.2/libnavigation-base/com.mapbox.navigation.base.trip.model/-route-step-progress/) here.

## Route progress and UI components

Several of the Navigation SDK's default UI components use route progress data to present guidance information to your users. Here's how each component uses route progress data:

-   **Maneuvers**: Invoke the Maneuver API when route progress changes to receive updated banner instruction data any time the route progress changes. Read more in the [Maneuver instructions](https://docs.mapbox.com/android/navigation/v2/guides/ui-components/maneuver/) guide.
-   **Trip progress**: Invoke the Trip Progress API when route progress changes to keep the estimated arrival time, distance remaining, and time remaining up to date as the user progresses along the route. Read more in the [Trip progress](https://docs.mapbox.com/android/navigation/v2/guides/ui-components/trip-progress/) guide.
-   **Route line**: Invoke the Route Line API to render a route line on a map.
-   **Route arrow**: Invoke the Route Arrow API when route progress changes to determine when to show an arrow on the route line.
-   **Buildings:** Invoke the Buildings API when route progress changes to highlight the building upon arrival at a waypoint or final destination.
-   **Notifications:** Invoke the `MapboxNavigation#updateNotification` when route progress changes to receive updated maneuver instructions when the app is running in background. Read more in the [Notifications](https://docs.mapbox.com/android/navigation/v2/guides/ui-components/notifications/) guide.

Beyond using route progress to power the UI components provided by the SDK, you can customize how your application behaves as the user progresses along the route by listening to progress change, determining the route progress state, and implementing custom code.

## Listen to progress change

Tracking a user's progress along a route is key to providing helpful and prompt navigation instructions. Implement the Navigation SDK's `RouteProgressObserver` interface to receive a `RouteProgress` object every time the user's location changes.

The `RouteProgressObserver` can typically be used to refresh most of your application's user interface when a change occurs. For example, if you're displaying the user's current progress until the user needs to do the next maneuver. Every time this interface's `onRouteProgressChanged()` method fires, you can update your view with the new information inside the `RouteProgress` object.

```kotlin
private val routeProgressObserver = object : RouteProgressObserver {
  override fun onRouteProgressChanged(routeProgress: RouteProgress) {

  }
}
```

If you've created your own `RouteProgressObserver` object, you'll need to:

1.  Register the `RouteProgressObserver` with [your already-instantiated `MapboxNavigation` object](https://docs.mapbox.com/android/navigation/v2/guides/get-started/initialization/#create-the-mapboxnavigation-object).

```kotlin
mapboxNavigation.registerRouteProgressObserver(routeProgressObserver)
```

2.  Don't forget to unregister the observer with `mapboxNavigation.unregisterRouteProgressObserver(routeProgressObserver)`. This line isn't needed if you're already running [`MapboxNavigation`'s `onDestroy()`](https://docs.mapbox.com/android/navigation/v2/api/2.2.0/libnavigation-core/-core/com.mapbox.navigation.core/-mapbox-navigation/#%5Bcom.mapbox.navigation.core%2FMapboxNavigation%2FonDestroy%2F%23%2FPointingToDeclaration%2F%5D%2FFunctions%2F965895564) method, which automatically unregisters the observer for you.

```kotlin
mapboxNavigation.unregisterRouteProgressObserver(routeProgressObserver)
```

## `RouteProgressState`

The Navigation SDK's `RouteProgressState` is an `enum` that contains various states that can occur while navigating. Using `RouteProgressState` helps you gain a better understanding of what's happening in the navigation experience.

The [`RouteProgressObserver`](#listen-to-progress-change) returns a [`RouteProgress` object](#routeprogress). Check the current state with the `RouteProgressState` object inside the returned `RouteProgress` object:

```kotlin
private val routeProgressObserver = object : RouteProgressObserver {
  override fun onRouteProgressChanged(routeProgress: RouteProgress) {
    routeProgress.currentState()?.let { currentState ->
      val state = currentState
    }
  }
}
```

There are five possible states: `INITIALIZED`, `TRACKING`, `COMPLETE`, `OFF_ROUTE`, and `UNCERTAIN`.

### Initialized

When a new route is first loaded and the `DirectionsRoute` JSON is valid, route-following will start in the `RouteProgressState.INITIALIZED` state. From there, route-following will try to gain confidence that the `Location` objects being passed to the device are the user's location. To show this trust, at least a few location updates need to be delivered and they must be consecutively coherent in both time and space. While it is establishing this trust, the route-following logic will report that it's still in the `RouteProgressState.INITIALIZED` state.

### Tracking

Once `MapboxNavigation` is confidently tracking the `Location` updates and processing them against the `DirectionsRoute`. The state will change to `RouteProgressState.TRACKING`.

### Complete

When the user has arrived at the destination of the given `RouteLeg`, the state will be `RouteProgressState.COMPLETE`.

### Off Route

The `RouteProgressState.OFF_ROUTE` occurs when the navigation system determines the user has deviated from the established route.

### Uncertain

The `RouteProgressState.UNCERTAIN` state occurs when the Navigation SDK has already been tracking location updates (`RouteProgressState.TRACKING`), but the route-snapping algorithm has temporarily lost confidence. For example, due to a re-route when the device strays off the turn-by-turn directions route. After a couple of `Location` updates after the re-route, `RouteProgressState` would return back to `RouteProgressState.TRACKING`.

## Visualizing the route progress state

The route progress state can be communicated to users by updating the style of the puck during navigation. In your `RouteProgressObserver` check the state and update the drawable used for the puck. You can design your own custom drawables and use them as shown below.

```kotlin
private val routeProgressObserver = object : RouteProgressObserver {
  override fun onRouteProgressChanged(routeProgress: RouteProgress) {
    routeProgress.currentState.let { currentState ->
      val puckDrawable = when (currentState) {
      	RouteProgressState.INITIALIZED -> R.drawable.your_drawable_for_initialized_state
      	RouteProgressState.TRACKING -> R.drawable.your_drawable_for_tracking_state
      	RouteProgressState.COMPLETE -> R.drawable.your_drawable_for_complete_state
      	RouteProgressState.OFF_ROUTE -> R.drawable.your_drawable_for_off_route_state
      	RouteProgressState.UNCERTAIN -> R.drawable.your_drawable_for_uncertain_state
      	else -> R.drawable.your_drawable_for_uncertain_state
      }
      mapView.location.apply {
      	this.locationPuck = LocationPuck2D(
        	bearingImage = ContextCompat.getDrawable(context, puckDrawable)
        )
      }
    }  
  }
}      
```