package com.mapbox.services.android.navigation.testapp.activity.navigationui; import android.content.DialogInterface; import android.location.Location; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import com.mapbox.api.directions.v5.models.DirectionsResponse; import com.mapbox.api.directions.v5.models.DirectionsRoute; import com.mapbox.geojson.Point; import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.services.android.navigation.testapp.R; import com.mapbox.services.android.navigation.ui.v5.NavigationView; import com.mapbox.services.android.navigation.ui.v5.NavigationViewOptions; import com.mapbox.services.android.navigation.ui.v5.OnNavigationReadyCallback; import com.mapbox.services.android.navigation.ui.v5.listeners.NavigationListener; import com.mapbox.services.android.navigation.ui.v5.listeners.RouteListener; import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute; import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener; import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; import java.util.ArrayList; import java.util.List; import retrofit2.Call; import retrofit2.Response; public class WaypointNavigationActivity extends AppCompatActivity implements OnNavigationReadyCallback, NavigationListener, RouteListener, ProgressChangeListener { private NavigationView navigationView; private boolean dropoffDialogShown; private Location lastKnownLocation; private List<Point> points = new ArrayList<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { setTheme(R.style.Theme_AppCompat_NoActionBar); super.onCreate(savedInstanceState); points.add(Point.fromLngLat(-77.04012393951416, 38.9111117447887)); points.add(Point.fromLngLat(-77.03847169876099, 38.91113678979344)); points.add(Point.fromLngLat(-77.03848242759705, 38.91040213277608)); points.add(Point.fromLngLat(-77.03850388526917, 38.909650771013034)); points.add(Point.fromLngLat(-77.03651905059814, 38.90894949285854)); setContentView(R.layout.activity_navigation); navigationView = findViewById(R.id.navigationView); navigationView.onCreate(savedInstanceState); navigationView.initialize(this); } @Override public void onStart() { super.onStart(); navigationView.onStart(); } @Override public void onResume() { super.onResume(); navigationView.onResume(); } @Override public void onLowMemory() { super.onLowMemory(); navigationView.onLowMemory(); } @Override public void onBackPressed() { // If the navigation view didn't need to do anything, call super if (!navigationView.onBackPressed()) { super.onBackPressed(); } } @Override protected void onSaveInstanceState(Bundle outState) { navigationView.onSaveInstanceState(outState); super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); navigationView.onRestoreInstanceState(savedInstanceState); } @Override public void onPause() { super.onPause(); navigationView.onPause(); } @Override public void onStop() { super.onStop(); navigationView.onStop(); } @Override protected void onDestroy() { super.onDestroy(); navigationView.onDestroy(); } @Override public void onNavigationReady(boolean isRunning) { fetchRoute(points.remove(0), points.remove(0)); } @Override public void onCancelNavigation() { // Navigation canceled, finish the activity finish(); } @Override public void onNavigationFinished() { // Intentionally empty } @Override public void onNavigationRunning() { // Intentionally empty } @Override public boolean allowRerouteFrom(Point offRoutePoint) { return true; } @Override public void onOffRoute(Point offRoutePoint) { } @Override public void onRerouteAlong(DirectionsRoute directionsRoute) { } @Override public void onFailedReroute(String errorMessage) { } @Override public void onArrival() { if (!dropoffDialogShown && !points.isEmpty()) { showDropoffDialog(); dropoffDialogShown = true; // Accounts for multiple arrival events } } @Override public void onProgressChange(Location location, RouteProgress routeProgress) { lastKnownLocation = location; } private void startNavigation(DirectionsRoute directionsRoute) { NavigationViewOptions navigationViewOptions = setupOptions(directionsRoute); navigationView.startNavigation(navigationViewOptions); } private void showDropoffDialog() { AlertDialog alertDialog = new AlertDialog.Builder(this).create(); alertDialog.setMessage(getString(R.string.dropoff_dialog_text)); alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.dropoff_dialog_positive_text), (dialogInterface, in) -> fetchRoute(getLastKnownLocation(), points.remove(0))); alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.dropoff_dialog_negative_text), (dialogInterface, in) -> { // Do nothing }); alertDialog.show(); } private void fetchRoute(Point origin, Point destination) { NavigationRoute.builder(this) .accessToken(Mapbox.getAccessToken()) .origin(origin) .destination(destination) .alternatives(true) .build() .getRoute(new SimplifiedCallback() { @Override public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) { startNavigation(response.body().routes().get(0)); } }); } private NavigationViewOptions setupOptions(DirectionsRoute directionsRoute) { dropoffDialogShown = false; NavigationViewOptions.Builder options = NavigationViewOptions.builder(); options.directionsRoute(directionsRoute) .navigationListener(this) .progressChangeListener(this) .routeListener(this) .shouldSimulateRoute(true); return options.build(); } private Point getLastKnownLocation() { return Point.fromLngLat(lastKnownLocation.getLongitude(), lastKnownLocation.getLatitude()); } }