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

# Directions to selected location

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/android/android/assets/medias/java-example-dashed-line-directions-picker-activity-feb72a84dd8d73ab3db69b2f0747d387.mp4).

> **Note**
> 
> This example is a part of the [Mapbox Android Demo app](https://github.com/mapbox/mapbox-android-demo). You can find the values for all referenced resources in the [`res`](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/res) directory. For example, see [`res/values/activity_strings.xml`](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/res/values/activity_strings.xml) for `R.string.*` references used in this example. The dependencies can be found [here.](https://github.com/mapbox/mapbox-navigation-android-examples/blob/main/app/build.gradle) The examples use View binding. [See setup documention if necessary.](https://developer.android.com/topic/libraries/view-binding)

> **Note: Directions API pricing**
> 
> Products used within the Mapbox Java SDK, including the Directions API, are individually billed. For pricing information, see the documentation for the [Directions API](https://docs.mapbox.com/api/navigation/directions/#directions-api-pricing).

Title: `activity_place_picker_dashed_directions_route`

[View on GitHub](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/res/layout/activity_place_picker_dashed_directions_route.xml)

```xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:mapbox="http://schemas.android.com/apk/res-auto"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

    <com.mapbox.mapboxsdk.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        mapbox:mapbox_cameraTargetLat="60.1698556"
        mapbox:mapbox_cameraTargetLng="24.9383791"
        mapbox:mapbox_cameraZoom="12"
        mapbox:mapbox_cameraZoomMin="11"/>

</FrameLayout>
```

**Java**

Title: `DashedLineDirectionsPickerActivity.java`

[View on GitHub](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/labs/DashedLineDirectionsPickerActivity.java)

```java
package com.mapbox.mapboxandroiddemo.examples.labs;

import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

import com.mapbox.api.directions.v5.DirectionsCriteria;
import com.mapbox.api.directions.v5.MapboxDirections;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.LineString;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxandroiddemo.R;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.LineLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import timber.log.Timber;

import static com.mapbox.core.constants.Constants.PRECISION_6;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineDasharray;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineTranslate;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth;

/**
 * Drag the map to automatically draw a directions route to wherever the map is centered.
 */
public class DashedLineDirectionsPickerActivity extends AppCompatActivity
  implements OnMapReadyCallback, MapboxMap.OnCameraIdleListener {

  private static final String DIRECTIONS_LAYER_ID = "DIRECTIONS_LAYER_ID";
  private static final String LAYER_BELOW_ID = "road-label-small";
  private static final String SOURCE_ID = "SOURCE_ID";
  private MapView mapView;
  private MapboxMap mapboxMap;
  private FeatureCollection dashedLineDirectionsFeatureCollection;
  private Point directionsOriginPoint = Point.fromLngLat(24.9383791, 60.1698556);

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Mapbox access token is configured here. This needs to be called either in your application
    // object or in the same activity which contains the mapview.
    Mapbox.getInstance(this, getString(R.string.access_token));

    // This contains the MapView in XML and needs to be called after the access token is configured.
    setContentView(R.layout.activity_place_picker_dashed_directions_route);

    // Initialize the mapboxMap view
    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(this);
  }

  @SuppressWarnings( {"MissingPermission"})
  @Override
  public void onMapReady(@NonNull final MapboxMap mapboxMap) {
    DashedLineDirectionsPickerActivity.this.mapboxMap = mapboxMap;

    mapboxMap.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {
      @Override
      public void onStyleLoaded(@NonNull Style style) {

        // Add a marker on the map's center/"target" for the place picker UI
        ImageView hoveringMarker = new ImageView(DashedLineDirectionsPickerActivity.this);
        hoveringMarker.setImageResource(R.drawable.red_marker);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
          ViewGroup.LayoutParams.WRAP_CONTENT,
          ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
        hoveringMarker.setLayoutParams(params);
        mapView.addView(hoveringMarker);

        // Add the layer for the dashed directions route line
        initDottedLineSourceAndLayer(style);

        // Add the camera idle listener
        mapboxMap.addOnCameraIdleListener(DashedLineDirectionsPickerActivity.this);

        Toast.makeText(
          DashedLineDirectionsPickerActivity.this,
          getString(R.string.move_map_around_instruction),
          Toast.LENGTH_LONG
        ).show();
      }
    });
  }

  @Override
  public void onCameraIdle() {
    if (mapboxMap != null) {
      Point destinationPoint = Point.fromLngLat(
        mapboxMap.getCameraPosition().target.getLongitude(),
        mapboxMap.getCameraPosition().target.getLatitude());
      getRoute(destinationPoint);
    }
  }

  /**
   * Set up a GeoJsonSource and LineLayer in order to show the directions route from the device location
   * to the place picker location
   */
  private void initDottedLineSourceAndLayer(@NonNull Style loadedMapStyle) {
    loadedMapStyle.addSource(new GeoJsonSource(SOURCE_ID));
    loadedMapStyle.addLayerBelow(
      new LineLayer(
          DIRECTIONS_LAYER_ID, SOURCE_ID).withProperties(
        lineWidth(4.5f),
        lineColor(Color.BLACK),
        lineTranslate(new Float[] {0f, 4f}),
        lineDasharray(new Float[] {1.2f, 1.2f})
      ), LAYER_BELOW_ID);
  }

  /**
   * Make a call to the Mapbox Directions API to get the route from the device location to the
   * place picker location
   *
   * @param destination the location chosen by moving the map to the desired destination location
   */
  @SuppressWarnings( {"MissingPermission"})
  private void getRoute(Point destination) {
    MapboxDirections client = MapboxDirections.builder()
      .origin(directionsOriginPoint)
      .destination(destination)
      .overview(DirectionsCriteria.OVERVIEW_FULL)
      .profile(DirectionsCriteria.PROFILE_WALKING)
      .accessToken(getString(R.string.access_token))
      .build();
    client.enqueueCall(new Callback<DirectionsResponse>() {
      @Override
      public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
        if (response.body() == null) {
          Timber.d( "No routes found, make sure you set the right user and access token.");
          return;
        } else if (response.body().routes().size() < 1) {
          Timber.d( "No routes found");
          return;
        }
        drawNavigationPolylineRoute(response.body().routes().get(0));
      }

      @Override
      public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
        Timber.d("Error: %s", throwable.getMessage());
        if (!throwable.getMessage().equals("Coordinate is invalid: 0,0")) {
          Toast.makeText(DashedLineDirectionsPickerActivity.this,
            "Error: " + throwable.getMessage(), Toast.LENGTH_SHORT).show();
        }
      }
    });
  }

  /**
   * Update the GeoJson data that's part of the LineLayer.
   *
   * @param route The route to be drawn in the map's LineLayer that was set up above.
   */
  private void drawNavigationPolylineRoute(final DirectionsRoute route) {
    if (mapboxMap != null) {
      mapboxMap.getStyle(new Style.OnStyleLoaded() {
        @Override
        public void onStyleLoaded(@NonNull Style style) {
          List<Feature> directionsRouteFeatureList = new ArrayList<>();
          LineString lineString = LineString.fromPolyline(route.geometry(), PRECISION_6);
          List<Point> coordinates = lineString.coordinates();
          for (int i = 0; i < coordinates.size(); i++) {
            directionsRouteFeatureList.add(Feature.fromGeometry(LineString.fromLngLats(coordinates)));
          }
          dashedLineDirectionsFeatureCollection = FeatureCollection.fromFeatures(directionsRouteFeatureList);
          GeoJsonSource source = style.getSourceAs(SOURCE_ID);
          if (source != null) {
            source.setGeoJson(dashedLineDirectionsFeatureCollection);
          }
        }
      });
    }
  }

  @Override
  @SuppressWarnings( {"MissingPermission"})
  protected void onStart() {
    super.onStart();
    mapView.onStart();
  }

  @Override
  protected void onResume() {
    super.onResume();
    mapView.onResume();
  }

  @Override
  protected void onPause() {
    super.onPause();
    mapView.onPause();
  }

  @Override
  protected void onStop() {
    super.onStop();
    mapView.onStop();
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    mapView.onDestroy();
  }

  @Override
  public void onLowMemory() {
    super.onLowMemory();
    mapView.onLowMemory();
  }
}
```