cancelNavigation button does not go back to mapView from navigationView












0














I currently managed to make the navigation work with NavigationView, and now i can set the route with mapView and then start the navigationView by pressing a button on the screen.
The problem is when I want to get back to mapView by pressing the X button on the bottom right of navigationView, since with the current code below it just stops the navigation from progressing (I have to manually force close the app and re-open it to be able to use it again). I tried to add finish() function just under navigationView.stopNavigation();but i still have to manually force close it.



Now, I'm a beginner with Java so i might be getting it wrong, but i think the problem is that the code is not restoring in anyway the mapView after having terminated the navigation UI. (why didn't I had such problems with navigationLauncher?)
Apparently in my code i'm not using fragments, so i was wondering if there's a way to do it without using those (i'm afraid that i would have to rewrite the code to implements fragments).



Please, don't mind all the junk and the badly written code, since i need it just to build a quick functional prototype!



package com.bpnavi.backpacknavigator;

import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.mapbox.api.directions.v5.DirectionsCriteria;
import com.mapbox.api.directions.v5.MapboxDirections;
import com.mapbox.api.directions.v5.models.BannerInstructions;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.MapView;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;



// classes needed to add the location component
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import android.location.Location;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.Toast;
import com.mapbox.mapboxsdk.geometry.LatLng;
import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;


// classes to calculate a route
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.BannerInstructionsListener;
import com.mapbox.services.android.navigation.ui.v5.listeners.NavigationListener;
import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute;
import com.mapbox.services.android.navigation.v5.instruction.Instruction;
import com.mapbox.services.android.navigation.v5.milestone.Milestone;
import com.mapbox.services.android.navigation.v5.milestone.MilestoneEventListener;
import com.mapbox.services.android.navigation.v5.milestone.RouteMilestone;
import com.mapbox.services.android.navigation.v5.milestone.StepMilestone;
import com.mapbox.services.android.navigation.v5.milestone.Trigger;
import com.mapbox.services.android.navigation.v5.milestone.TriggerProperty;
import com.mapbox.services.android.navigation.v5.navigation.NavigationEventListener;
import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation;
import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigationOptions;
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgressState;
import com.mapbox.services.android.navigation.v5.utils.RouteUtils;

import io.reactivex.Observable;
import io.reactivex.disposables.Disposable;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import timber.log.Timber;


// classes needed to launch navigation UI
import android.view.View;
import android.widget.Button;
import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher;

import com.mapbox.services.android.navigation.v5.offroute.OffRouteListener;
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import com.polidea.rxandroidble2.RxBleClient;
import com.polidea.rxandroidble2.RxBleConnection;
import com.polidea.rxandroidble2.RxBleDevice;
import com.polidea.rxandroidble2.internal.RxBleLog;
import com.polidea.rxandroidble2.scan.ScanSettings;

import android.util.Log;
import android.widget.ToggleButton;


import java.util.List;
import java.util.UUID;


public class MainActivity extends AppCompatActivity implements PermissionsListener, MapboxMap.OnMapClickListener, OnNavigationReadyCallback, BannerInstructionsListener,
MilestoneEventListener, OffRouteListener, ProgressChangeListener, NavigationListener {
private MapView mapView;
private NavigationView navigationView;

private MapboxMap mapboxMap;
private PermissionsManager permissionsManager;
private Location originLocation;

// variables for adding a marker
private Marker destinationMarker;
private LatLng originCoord;
private LatLng destinationCoord;

// variables for calculating and drawing a route
private Point originPosition;
private Point destinationPosition;
private DirectionsRoute currentRoute;
private static final String TAG = "DirectionsActivity";
private NavigationMapRoute navigationMapRoute;
private MapboxDirections client;
private Button startButton;

public static final String BACKPACK_DEVICE_ADDRESS = "321";
public static final String TEST_DEVICE_ADDRESS = "123";
private static final UUID WRITE_CHARACTERISTIC = UUID.fromString("abc123");
private Disposable disposable;
private RxBleDevice device;
private BannerInstructions BannerInstructionMilestone;
private MapboxNavigation navigation;

private static final int INSTR_MILESTONE = 1001;
private boolean noRe = false;
private boolean simActive = true;
private int activationDistance = 15;

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

RxBleClient rxBleClient = RxBleClient.create(this);

device = rxBleClient.getBleDevice(TEST_DEVICE_ADDRESS);

Disposable disposable = device.establishConnection(false) // <-- autoConnect flag
.subscribe(
rxBleConnection -> {
// All GATT operations are done through the rxBleConnection.
},
throwable -> {
// Handle an error here.
}
);
// disposable.dispose();


Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.mapView);
startButton = findViewById(R.id.startButton);

startButton.setOnClickListener(v -> {
setTheme(R.style.Theme_AppCompat_NoActionBar);
setContentView(R.layout.activity_navigation);
navigationView = findViewById(R.id.navigationView);
navigationView.onCreate(savedInstanceState);
navigationView.initialize(this);

// boolean simulateRoute = true;
// NavigationLauncherOptions options = NavigationLauncherOptions.builder()
// .directionsRoute(currentRoute)
// .shouldSimulateRoute(simulateRoute)
// .build();
// // Call this method with Context from within an Activity
// NavigationLauncher.startNavigation(MainActivity.this, options);
});

MapboxNavigationOptions navOptions = MapboxNavigationOptions.builder().isDebugLoggingEnabled(true).build();
navigation = new MapboxNavigation(getApplicationContext(), getString(R.string.access_token), navOptions);
navigation.addMilestoneEventListener(this);


navigation.addMilestone(new StepMilestone.Builder()
.setIdentifier(INSTR_MILESTONE)
.setInstruction(this.myInstruction)
.setTrigger(
Trigger.all(
Trigger.lt(TriggerProperty.STEP_DISTANCE_REMAINING_METERS, 10)))
.build()
);

mapView.onCreate(savedInstanceState);
mapView.getMapAsync(mapboxMap -> {
MainActivity.this.mapboxMap = mapboxMap;
enableLocationComponent();

originCoord = new LatLng(originLocation.getLatitude(), originLocation.getLongitude());

mapboxMap.addOnMapClickListener(this);

//Set stuff here
mapboxMap.addMarker(new MarkerOptions()
.position(new LatLng(45.506833, 9.163333))
.title("Politecnico di Milano")
.snippet("Dipartimento di Design")
);
});

}

@SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent() {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Activate the MapboxMap LocationComponent to show user location
// Adding in LocationComponentOptions is also an optional parameter
LocationComponent locationComponent = mapboxMap.getLocationComponent();
locationComponent.activateLocationComponent(this);
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING_GPS);
locationComponent.setRenderMode(RenderMode.GPS);
originLocation = locationComponent.getLastKnownLocation();

} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}

@Override
public void onMapClick(@NonNull LatLng point){

if (destinationMarker != null) {
mapboxMap.removeMarker(destinationMarker);
}
destinationCoord = point;
destinationMarker = mapboxMap.addMarker(new MarkerOptions()
.position(destinationCoord)
);

destinationPosition = Point.fromLngLat(destinationCoord.getLongitude(), destinationCoord.getLatitude());
originPosition = Point.fromLngLat(originCoord.getLongitude(), originCoord.getLatitude());
getRoute(originPosition, destinationPosition);
}




private void getRoute(Point origin, Point destination) {

Toast.makeText(this, "Calculating route...", Toast.LENGTH_SHORT).show();

MapboxDirections.builder()
.origin(origin)
.destination(destination)
.accessToken(getString(R.string.access_token))
.profile(DirectionsCriteria.PROFILE_CYCLING)
.bannerInstructions(true)
.steps(true)
.roundaboutExits(true)
.build();

NavigationRoute.builder(this)
.accessToken(getString(R.string.access_token))
.origin(origin)
.destination(destination)
.profile(DirectionsCriteria.PROFILE_CYCLING)
.voiceUnits("metric")
.build()
.getRoute(new Callback<DirectionsResponse>() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
} else if (response.body().routes().size() < 1) {
Log.e(TAG, "No routes found");
return;
}

currentRoute = response.body().routes().get(0);

// Draw the route on the map
if (navigationMapRoute != null) {
navigationMapRoute.removeRoute();
} else {
navigationMapRoute = new NavigationMapRoute(null, mapView, mapboxMap, R.style.NavigationMapRoute);

startButton.setVisibility(View.VISIBLE);
startButton.setBackgroundResource(R.color.colorPrimary);

ToggleButton toggleSim = findViewById(R.id.toggleSimButton);
toggleSim.setVisibility(View.VISIBLE);

}
navigationMapRoute.addRoute(currentRoute);
}

@Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
Log.e(TAG, "Error: " + throwable.getMessage());
}
});
}



@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
}

@Override
public void onPermissionResult(boolean granted) {
if (granted) {
enableLocationComponent();
} else {
Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
finish();
}
}

@Override
protected void onStart() {
super.onStart();
mapView.onStart();
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
int REQUEST_ENABLE_BT = 1;
this.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

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

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

@Override
protected void onStop() {
super.onStop();
mapView.onStop();
if (disposable != null) {
disposable.dispose();
disposable = null;
}
}

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
}

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


@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
if (disposable != null) {
disposable.dispose();
disposable = null;
}
}

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

@Override
public void onBackPressed() {
// If the navigation view didn't need to do anything, call super
if (!navigationView.onBackPressed()) {
super.onBackPressed();
}
}


@Override
public void onNavigationReady(boolean isRunning) {

NavigationViewOptions options = NavigationViewOptions.builder()
.directionsRoute(currentRoute)
.shouldSimulateRoute(simActive)
.bannerInstructionsListener(this)
.milestoneEventListener(MainActivity.this)
.navigationListener(MainActivity.this)
.progressChangeListener(MainActivity.this)
.build();

navigationView.startNavigation(options);

}

@Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
if (routeProgress.currentLegProgress().currentStepProgress().distanceRemaining()>20) {
noRe = false;
}

Context context = getApplicationContext();
String instr = myInstruction.buildInstruction(routeProgress).replaceAll(" ", "");
int duration = Toast.LENGTH_SHORT;

if (instr.length() < 20 &&
!noRe &&
routeProgress.currentLegProgress().currentStepProgress().distanceRemaining() < activationDistance
) {
noRe = true;
Toast.makeText(context, instr, duration).show();

RxBleClient rxBleClient = RxBleClient.create(this);
device = rxBleClient.getBleDevice(TEST_DEVICE_ADDRESS);


Disposable disposable = device.establishConnection(false) // <-- autoConnect flag
.flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(WRITE_CHARACTERISTIC, instr.getBytes()))
.subscribe(
characteristicValue -> {
// Characteristic value confirmed.
},
throwable -> {
// Handle an error here.
}
);
}
}

@Override
public void userOffRoute(Location location) {
Toast.makeText(this, "offRoute", Toast.LENGTH_LONG).show();
}

@Override
public void onMilestoneEvent(RouteProgress routeProgress, String instruction, Milestone milestone) {

}

Instruction myInstruction = new Instruction() {

@Override
public String buildInstruction(RouteProgress routeProgress) {
return routeProgress.currentLegProgress().upComingStep().maneuver().type() + routeProgress.currentLegProgress().upComingStep().maneuver().modifier();
}
};

@Override
public BannerInstructions willDisplay(BannerInstructions instructions) {

return instructions;
}

@Override
public void onCancelNavigation() {
navigationView.stopNavigation();
}

@Override
public void onNavigationFinished() {

}

@Override
public void onNavigationRunning() {

}

}


thanks!










share|improve this question



























    0














    I currently managed to make the navigation work with NavigationView, and now i can set the route with mapView and then start the navigationView by pressing a button on the screen.
    The problem is when I want to get back to mapView by pressing the X button on the bottom right of navigationView, since with the current code below it just stops the navigation from progressing (I have to manually force close the app and re-open it to be able to use it again). I tried to add finish() function just under navigationView.stopNavigation();but i still have to manually force close it.



    Now, I'm a beginner with Java so i might be getting it wrong, but i think the problem is that the code is not restoring in anyway the mapView after having terminated the navigation UI. (why didn't I had such problems with navigationLauncher?)
    Apparently in my code i'm not using fragments, so i was wondering if there's a way to do it without using those (i'm afraid that i would have to rewrite the code to implements fragments).



    Please, don't mind all the junk and the badly written code, since i need it just to build a quick functional prototype!



    package com.bpnavi.backpacknavigator;

    import android.bluetooth.BluetoothAdapter;
    import android.content.Context;
    import android.content.Intent;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;

    import com.mapbox.api.directions.v5.DirectionsCriteria;
    import com.mapbox.api.directions.v5.MapboxDirections;
    import com.mapbox.api.directions.v5.models.BannerInstructions;
    import com.mapbox.mapboxsdk.annotations.Marker;
    import com.mapbox.mapboxsdk.annotations.MarkerOptions;
    import com.mapbox.mapboxsdk.camera.CameraPosition;
    import com.mapbox.mapboxsdk.geometry.LatLng;
    import com.mapbox.mapboxsdk.Mapbox;
    import com.mapbox.mapboxsdk.location.modes.RenderMode;
    import com.mapbox.mapboxsdk.maps.MapboxMap;
    import com.mapbox.mapboxsdk.maps.MapView;

    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;



    // classes needed to add the location component
    import com.mapbox.geojson.Point;
    import com.mapbox.mapboxsdk.maps.MapboxMap;
    import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
    import android.location.Location;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.widget.Button;
    import android.widget.CompoundButton;
    import android.widget.Toast;
    import com.mapbox.mapboxsdk.geometry.LatLng;
    import android.support.annotation.NonNull;
    import com.mapbox.mapboxsdk.location.LocationComponent;
    import com.mapbox.mapboxsdk.location.modes.CameraMode;
    import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions;
    import com.mapbox.android.core.permissions.PermissionsListener;
    import com.mapbox.android.core.permissions.PermissionsManager;


    // classes to calculate a route
    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.BannerInstructionsListener;
    import com.mapbox.services.android.navigation.ui.v5.listeners.NavigationListener;
    import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute;
    import com.mapbox.services.android.navigation.v5.instruction.Instruction;
    import com.mapbox.services.android.navigation.v5.milestone.Milestone;
    import com.mapbox.services.android.navigation.v5.milestone.MilestoneEventListener;
    import com.mapbox.services.android.navigation.v5.milestone.RouteMilestone;
    import com.mapbox.services.android.navigation.v5.milestone.StepMilestone;
    import com.mapbox.services.android.navigation.v5.milestone.Trigger;
    import com.mapbox.services.android.navigation.v5.milestone.TriggerProperty;
    import com.mapbox.services.android.navigation.v5.navigation.NavigationEventListener;
    import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
    import com.mapbox.api.directions.v5.models.DirectionsResponse;
    import com.mapbox.api.directions.v5.models.DirectionsRoute;
    import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation;
    import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigationOptions;
    import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
    import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
    import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgressState;
    import com.mapbox.services.android.navigation.v5.utils.RouteUtils;

    import io.reactivex.Observable;
    import io.reactivex.disposables.Disposable;
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    import timber.log.Timber;


    // classes needed to launch navigation UI
    import android.view.View;
    import android.widget.Button;
    import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher;

    import com.mapbox.services.android.navigation.v5.offroute.OffRouteListener;
    import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
    import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
    import com.polidea.rxandroidble2.RxBleClient;
    import com.polidea.rxandroidble2.RxBleConnection;
    import com.polidea.rxandroidble2.RxBleDevice;
    import com.polidea.rxandroidble2.internal.RxBleLog;
    import com.polidea.rxandroidble2.scan.ScanSettings;

    import android.util.Log;
    import android.widget.ToggleButton;


    import java.util.List;
    import java.util.UUID;


    public class MainActivity extends AppCompatActivity implements PermissionsListener, MapboxMap.OnMapClickListener, OnNavigationReadyCallback, BannerInstructionsListener,
    MilestoneEventListener, OffRouteListener, ProgressChangeListener, NavigationListener {
    private MapView mapView;
    private NavigationView navigationView;

    private MapboxMap mapboxMap;
    private PermissionsManager permissionsManager;
    private Location originLocation;

    // variables for adding a marker
    private Marker destinationMarker;
    private LatLng originCoord;
    private LatLng destinationCoord;

    // variables for calculating and drawing a route
    private Point originPosition;
    private Point destinationPosition;
    private DirectionsRoute currentRoute;
    private static final String TAG = "DirectionsActivity";
    private NavigationMapRoute navigationMapRoute;
    private MapboxDirections client;
    private Button startButton;

    public static final String BACKPACK_DEVICE_ADDRESS = "321";
    public static final String TEST_DEVICE_ADDRESS = "123";
    private static final UUID WRITE_CHARACTERISTIC = UUID.fromString("abc123");
    private Disposable disposable;
    private RxBleDevice device;
    private BannerInstructions BannerInstructionMilestone;
    private MapboxNavigation navigation;

    private static final int INSTR_MILESTONE = 1001;
    private boolean noRe = false;
    private boolean simActive = true;
    private int activationDistance = 15;

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

    RxBleClient rxBleClient = RxBleClient.create(this);

    device = rxBleClient.getBleDevice(TEST_DEVICE_ADDRESS);

    Disposable disposable = device.establishConnection(false) // <-- autoConnect flag
    .subscribe(
    rxBleConnection -> {
    // All GATT operations are done through the rxBleConnection.
    },
    throwable -> {
    // Handle an error here.
    }
    );
    // disposable.dispose();


    Mapbox.getInstance(this, getString(R.string.access_token));
    setContentView(R.layout.activity_main);
    mapView = (MapView) findViewById(R.id.mapView);
    startButton = findViewById(R.id.startButton);

    startButton.setOnClickListener(v -> {
    setTheme(R.style.Theme_AppCompat_NoActionBar);
    setContentView(R.layout.activity_navigation);
    navigationView = findViewById(R.id.navigationView);
    navigationView.onCreate(savedInstanceState);
    navigationView.initialize(this);

    // boolean simulateRoute = true;
    // NavigationLauncherOptions options = NavigationLauncherOptions.builder()
    // .directionsRoute(currentRoute)
    // .shouldSimulateRoute(simulateRoute)
    // .build();
    // // Call this method with Context from within an Activity
    // NavigationLauncher.startNavigation(MainActivity.this, options);
    });

    MapboxNavigationOptions navOptions = MapboxNavigationOptions.builder().isDebugLoggingEnabled(true).build();
    navigation = new MapboxNavigation(getApplicationContext(), getString(R.string.access_token), navOptions);
    navigation.addMilestoneEventListener(this);


    navigation.addMilestone(new StepMilestone.Builder()
    .setIdentifier(INSTR_MILESTONE)
    .setInstruction(this.myInstruction)
    .setTrigger(
    Trigger.all(
    Trigger.lt(TriggerProperty.STEP_DISTANCE_REMAINING_METERS, 10)))
    .build()
    );

    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(mapboxMap -> {
    MainActivity.this.mapboxMap = mapboxMap;
    enableLocationComponent();

    originCoord = new LatLng(originLocation.getLatitude(), originLocation.getLongitude());

    mapboxMap.addOnMapClickListener(this);

    //Set stuff here
    mapboxMap.addMarker(new MarkerOptions()
    .position(new LatLng(45.506833, 9.163333))
    .title("Politecnico di Milano")
    .snippet("Dipartimento di Design")
    );
    });

    }

    @SuppressWarnings( {"MissingPermission"})
    private void enableLocationComponent() {
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {
    // Activate the MapboxMap LocationComponent to show user location
    // Adding in LocationComponentOptions is also an optional parameter
    LocationComponent locationComponent = mapboxMap.getLocationComponent();
    locationComponent.activateLocationComponent(this);
    locationComponent.setLocationComponentEnabled(true);
    // Set the component's camera mode
    locationComponent.setCameraMode(CameraMode.TRACKING_GPS);
    locationComponent.setRenderMode(RenderMode.GPS);
    originLocation = locationComponent.getLastKnownLocation();

    } else {
    permissionsManager = new PermissionsManager(this);
    permissionsManager.requestLocationPermissions(this);
    }
    }

    @Override
    public void onMapClick(@NonNull LatLng point){

    if (destinationMarker != null) {
    mapboxMap.removeMarker(destinationMarker);
    }
    destinationCoord = point;
    destinationMarker = mapboxMap.addMarker(new MarkerOptions()
    .position(destinationCoord)
    );

    destinationPosition = Point.fromLngLat(destinationCoord.getLongitude(), destinationCoord.getLatitude());
    originPosition = Point.fromLngLat(originCoord.getLongitude(), originCoord.getLatitude());
    getRoute(originPosition, destinationPosition);
    }




    private void getRoute(Point origin, Point destination) {

    Toast.makeText(this, "Calculating route...", Toast.LENGTH_SHORT).show();

    MapboxDirections.builder()
    .origin(origin)
    .destination(destination)
    .accessToken(getString(R.string.access_token))
    .profile(DirectionsCriteria.PROFILE_CYCLING)
    .bannerInstructions(true)
    .steps(true)
    .roundaboutExits(true)
    .build();

    NavigationRoute.builder(this)
    .accessToken(getString(R.string.access_token))
    .origin(origin)
    .destination(destination)
    .profile(DirectionsCriteria.PROFILE_CYCLING)
    .voiceUnits("metric")
    .build()
    .getRoute(new Callback<DirectionsResponse>() {
    @Override
    public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
    // You can get the generic HTTP info about the response
    Log.d(TAG, "Response code: " + response.code());
    if (response.body() == null) {
    Log.e(TAG, "No routes found, make sure you set the right user and access token.");
    return;
    } else if (response.body().routes().size() < 1) {
    Log.e(TAG, "No routes found");
    return;
    }

    currentRoute = response.body().routes().get(0);

    // Draw the route on the map
    if (navigationMapRoute != null) {
    navigationMapRoute.removeRoute();
    } else {
    navigationMapRoute = new NavigationMapRoute(null, mapView, mapboxMap, R.style.NavigationMapRoute);

    startButton.setVisibility(View.VISIBLE);
    startButton.setBackgroundResource(R.color.colorPrimary);

    ToggleButton toggleSim = findViewById(R.id.toggleSimButton);
    toggleSim.setVisibility(View.VISIBLE);

    }
    navigationMapRoute.addRoute(currentRoute);
    }

    @Override
    public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
    Log.e(TAG, "Error: " + throwable.getMessage());
    }
    });
    }



    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public void onExplanationNeeded(List<String> permissionsToExplain) {
    Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onPermissionResult(boolean granted) {
    if (granted) {
    enableLocationComponent();
    } else {
    Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
    finish();
    }
    }

    @Override
    protected void onStart() {
    super.onStart();
    mapView.onStart();
    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    int REQUEST_ENABLE_BT = 1;
    this.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }

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

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

    @Override
    protected void onStop() {
    super.onStop();
    mapView.onStop();
    if (disposable != null) {
    disposable.dispose();
    disposable = null;
    }
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    }

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


    @Override
    protected void onDestroy() {
    super.onDestroy();
    mapView.onDestroy();
    if (disposable != null) {
    disposable.dispose();
    disposable = null;
    }
    }

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

    @Override
    public void onBackPressed() {
    // If the navigation view didn't need to do anything, call super
    if (!navigationView.onBackPressed()) {
    super.onBackPressed();
    }
    }


    @Override
    public void onNavigationReady(boolean isRunning) {

    NavigationViewOptions options = NavigationViewOptions.builder()
    .directionsRoute(currentRoute)
    .shouldSimulateRoute(simActive)
    .bannerInstructionsListener(this)
    .milestoneEventListener(MainActivity.this)
    .navigationListener(MainActivity.this)
    .progressChangeListener(MainActivity.this)
    .build();

    navigationView.startNavigation(options);

    }

    @Override
    public void onProgressChange(Location location, RouteProgress routeProgress) {
    if (routeProgress.currentLegProgress().currentStepProgress().distanceRemaining()>20) {
    noRe = false;
    }

    Context context = getApplicationContext();
    String instr = myInstruction.buildInstruction(routeProgress).replaceAll(" ", "");
    int duration = Toast.LENGTH_SHORT;

    if (instr.length() < 20 &&
    !noRe &&
    routeProgress.currentLegProgress().currentStepProgress().distanceRemaining() < activationDistance
    ) {
    noRe = true;
    Toast.makeText(context, instr, duration).show();

    RxBleClient rxBleClient = RxBleClient.create(this);
    device = rxBleClient.getBleDevice(TEST_DEVICE_ADDRESS);


    Disposable disposable = device.establishConnection(false) // <-- autoConnect flag
    .flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(WRITE_CHARACTERISTIC, instr.getBytes()))
    .subscribe(
    characteristicValue -> {
    // Characteristic value confirmed.
    },
    throwable -> {
    // Handle an error here.
    }
    );
    }
    }

    @Override
    public void userOffRoute(Location location) {
    Toast.makeText(this, "offRoute", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onMilestoneEvent(RouteProgress routeProgress, String instruction, Milestone milestone) {

    }

    Instruction myInstruction = new Instruction() {

    @Override
    public String buildInstruction(RouteProgress routeProgress) {
    return routeProgress.currentLegProgress().upComingStep().maneuver().type() + routeProgress.currentLegProgress().upComingStep().maneuver().modifier();
    }
    };

    @Override
    public BannerInstructions willDisplay(BannerInstructions instructions) {

    return instructions;
    }

    @Override
    public void onCancelNavigation() {
    navigationView.stopNavigation();
    }

    @Override
    public void onNavigationFinished() {

    }

    @Override
    public void onNavigationRunning() {

    }

    }


    thanks!










    share|improve this question

























      0












      0








      0







      I currently managed to make the navigation work with NavigationView, and now i can set the route with mapView and then start the navigationView by pressing a button on the screen.
      The problem is when I want to get back to mapView by pressing the X button on the bottom right of navigationView, since with the current code below it just stops the navigation from progressing (I have to manually force close the app and re-open it to be able to use it again). I tried to add finish() function just under navigationView.stopNavigation();but i still have to manually force close it.



      Now, I'm a beginner with Java so i might be getting it wrong, but i think the problem is that the code is not restoring in anyway the mapView after having terminated the navigation UI. (why didn't I had such problems with navigationLauncher?)
      Apparently in my code i'm not using fragments, so i was wondering if there's a way to do it without using those (i'm afraid that i would have to rewrite the code to implements fragments).



      Please, don't mind all the junk and the badly written code, since i need it just to build a quick functional prototype!



      package com.bpnavi.backpacknavigator;

      import android.bluetooth.BluetoothAdapter;
      import android.content.Context;
      import android.content.Intent;
      import android.support.annotation.Nullable;
      import android.support.v7.app.AppCompatActivity;
      import android.os.Bundle;

      import com.mapbox.api.directions.v5.DirectionsCriteria;
      import com.mapbox.api.directions.v5.MapboxDirections;
      import com.mapbox.api.directions.v5.models.BannerInstructions;
      import com.mapbox.mapboxsdk.annotations.Marker;
      import com.mapbox.mapboxsdk.annotations.MarkerOptions;
      import com.mapbox.mapboxsdk.camera.CameraPosition;
      import com.mapbox.mapboxsdk.geometry.LatLng;
      import com.mapbox.mapboxsdk.Mapbox;
      import com.mapbox.mapboxsdk.location.modes.RenderMode;
      import com.mapbox.mapboxsdk.maps.MapboxMap;
      import com.mapbox.mapboxsdk.maps.MapView;

      import android.support.annotation.NonNull;
      import android.support.annotation.Nullable;
      import android.support.v4.app.Fragment;
      import android.support.v4.app.FragmentActivity;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;



      // classes needed to add the location component
      import com.mapbox.geojson.Point;
      import com.mapbox.mapboxsdk.maps.MapboxMap;
      import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
      import android.location.Location;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.view.Window;
      import android.widget.Button;
      import android.widget.CompoundButton;
      import android.widget.Toast;
      import com.mapbox.mapboxsdk.geometry.LatLng;
      import android.support.annotation.NonNull;
      import com.mapbox.mapboxsdk.location.LocationComponent;
      import com.mapbox.mapboxsdk.location.modes.CameraMode;
      import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions;
      import com.mapbox.android.core.permissions.PermissionsListener;
      import com.mapbox.android.core.permissions.PermissionsManager;


      // classes to calculate a route
      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.BannerInstructionsListener;
      import com.mapbox.services.android.navigation.ui.v5.listeners.NavigationListener;
      import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute;
      import com.mapbox.services.android.navigation.v5.instruction.Instruction;
      import com.mapbox.services.android.navigation.v5.milestone.Milestone;
      import com.mapbox.services.android.navigation.v5.milestone.MilestoneEventListener;
      import com.mapbox.services.android.navigation.v5.milestone.RouteMilestone;
      import com.mapbox.services.android.navigation.v5.milestone.StepMilestone;
      import com.mapbox.services.android.navigation.v5.milestone.Trigger;
      import com.mapbox.services.android.navigation.v5.milestone.TriggerProperty;
      import com.mapbox.services.android.navigation.v5.navigation.NavigationEventListener;
      import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
      import com.mapbox.api.directions.v5.models.DirectionsResponse;
      import com.mapbox.api.directions.v5.models.DirectionsRoute;
      import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation;
      import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigationOptions;
      import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
      import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
      import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgressState;
      import com.mapbox.services.android.navigation.v5.utils.RouteUtils;

      import io.reactivex.Observable;
      import io.reactivex.disposables.Disposable;
      import retrofit2.Call;
      import retrofit2.Callback;
      import retrofit2.Response;
      import timber.log.Timber;


      // classes needed to launch navigation UI
      import android.view.View;
      import android.widget.Button;
      import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher;

      import com.mapbox.services.android.navigation.v5.offroute.OffRouteListener;
      import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
      import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
      import com.polidea.rxandroidble2.RxBleClient;
      import com.polidea.rxandroidble2.RxBleConnection;
      import com.polidea.rxandroidble2.RxBleDevice;
      import com.polidea.rxandroidble2.internal.RxBleLog;
      import com.polidea.rxandroidble2.scan.ScanSettings;

      import android.util.Log;
      import android.widget.ToggleButton;


      import java.util.List;
      import java.util.UUID;


      public class MainActivity extends AppCompatActivity implements PermissionsListener, MapboxMap.OnMapClickListener, OnNavigationReadyCallback, BannerInstructionsListener,
      MilestoneEventListener, OffRouteListener, ProgressChangeListener, NavigationListener {
      private MapView mapView;
      private NavigationView navigationView;

      private MapboxMap mapboxMap;
      private PermissionsManager permissionsManager;
      private Location originLocation;

      // variables for adding a marker
      private Marker destinationMarker;
      private LatLng originCoord;
      private LatLng destinationCoord;

      // variables for calculating and drawing a route
      private Point originPosition;
      private Point destinationPosition;
      private DirectionsRoute currentRoute;
      private static final String TAG = "DirectionsActivity";
      private NavigationMapRoute navigationMapRoute;
      private MapboxDirections client;
      private Button startButton;

      public static final String BACKPACK_DEVICE_ADDRESS = "321";
      public static final String TEST_DEVICE_ADDRESS = "123";
      private static final UUID WRITE_CHARACTERISTIC = UUID.fromString("abc123");
      private Disposable disposable;
      private RxBleDevice device;
      private BannerInstructions BannerInstructionMilestone;
      private MapboxNavigation navigation;

      private static final int INSTR_MILESTONE = 1001;
      private boolean noRe = false;
      private boolean simActive = true;
      private int activationDistance = 15;

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

      RxBleClient rxBleClient = RxBleClient.create(this);

      device = rxBleClient.getBleDevice(TEST_DEVICE_ADDRESS);

      Disposable disposable = device.establishConnection(false) // <-- autoConnect flag
      .subscribe(
      rxBleConnection -> {
      // All GATT operations are done through the rxBleConnection.
      },
      throwable -> {
      // Handle an error here.
      }
      );
      // disposable.dispose();


      Mapbox.getInstance(this, getString(R.string.access_token));
      setContentView(R.layout.activity_main);
      mapView = (MapView) findViewById(R.id.mapView);
      startButton = findViewById(R.id.startButton);

      startButton.setOnClickListener(v -> {
      setTheme(R.style.Theme_AppCompat_NoActionBar);
      setContentView(R.layout.activity_navigation);
      navigationView = findViewById(R.id.navigationView);
      navigationView.onCreate(savedInstanceState);
      navigationView.initialize(this);

      // boolean simulateRoute = true;
      // NavigationLauncherOptions options = NavigationLauncherOptions.builder()
      // .directionsRoute(currentRoute)
      // .shouldSimulateRoute(simulateRoute)
      // .build();
      // // Call this method with Context from within an Activity
      // NavigationLauncher.startNavigation(MainActivity.this, options);
      });

      MapboxNavigationOptions navOptions = MapboxNavigationOptions.builder().isDebugLoggingEnabled(true).build();
      navigation = new MapboxNavigation(getApplicationContext(), getString(R.string.access_token), navOptions);
      navigation.addMilestoneEventListener(this);


      navigation.addMilestone(new StepMilestone.Builder()
      .setIdentifier(INSTR_MILESTONE)
      .setInstruction(this.myInstruction)
      .setTrigger(
      Trigger.all(
      Trigger.lt(TriggerProperty.STEP_DISTANCE_REMAINING_METERS, 10)))
      .build()
      );

      mapView.onCreate(savedInstanceState);
      mapView.getMapAsync(mapboxMap -> {
      MainActivity.this.mapboxMap = mapboxMap;
      enableLocationComponent();

      originCoord = new LatLng(originLocation.getLatitude(), originLocation.getLongitude());

      mapboxMap.addOnMapClickListener(this);

      //Set stuff here
      mapboxMap.addMarker(new MarkerOptions()
      .position(new LatLng(45.506833, 9.163333))
      .title("Politecnico di Milano")
      .snippet("Dipartimento di Design")
      );
      });

      }

      @SuppressWarnings( {"MissingPermission"})
      private void enableLocationComponent() {
      // Check if permissions are enabled and if not request
      if (PermissionsManager.areLocationPermissionsGranted(this)) {
      // Activate the MapboxMap LocationComponent to show user location
      // Adding in LocationComponentOptions is also an optional parameter
      LocationComponent locationComponent = mapboxMap.getLocationComponent();
      locationComponent.activateLocationComponent(this);
      locationComponent.setLocationComponentEnabled(true);
      // Set the component's camera mode
      locationComponent.setCameraMode(CameraMode.TRACKING_GPS);
      locationComponent.setRenderMode(RenderMode.GPS);
      originLocation = locationComponent.getLastKnownLocation();

      } else {
      permissionsManager = new PermissionsManager(this);
      permissionsManager.requestLocationPermissions(this);
      }
      }

      @Override
      public void onMapClick(@NonNull LatLng point){

      if (destinationMarker != null) {
      mapboxMap.removeMarker(destinationMarker);
      }
      destinationCoord = point;
      destinationMarker = mapboxMap.addMarker(new MarkerOptions()
      .position(destinationCoord)
      );

      destinationPosition = Point.fromLngLat(destinationCoord.getLongitude(), destinationCoord.getLatitude());
      originPosition = Point.fromLngLat(originCoord.getLongitude(), originCoord.getLatitude());
      getRoute(originPosition, destinationPosition);
      }




      private void getRoute(Point origin, Point destination) {

      Toast.makeText(this, "Calculating route...", Toast.LENGTH_SHORT).show();

      MapboxDirections.builder()
      .origin(origin)
      .destination(destination)
      .accessToken(getString(R.string.access_token))
      .profile(DirectionsCriteria.PROFILE_CYCLING)
      .bannerInstructions(true)
      .steps(true)
      .roundaboutExits(true)
      .build();

      NavigationRoute.builder(this)
      .accessToken(getString(R.string.access_token))
      .origin(origin)
      .destination(destination)
      .profile(DirectionsCriteria.PROFILE_CYCLING)
      .voiceUnits("metric")
      .build()
      .getRoute(new Callback<DirectionsResponse>() {
      @Override
      public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
      // You can get the generic HTTP info about the response
      Log.d(TAG, "Response code: " + response.code());
      if (response.body() == null) {
      Log.e(TAG, "No routes found, make sure you set the right user and access token.");
      return;
      } else if (response.body().routes().size() < 1) {
      Log.e(TAG, "No routes found");
      return;
      }

      currentRoute = response.body().routes().get(0);

      // Draw the route on the map
      if (navigationMapRoute != null) {
      navigationMapRoute.removeRoute();
      } else {
      navigationMapRoute = new NavigationMapRoute(null, mapView, mapboxMap, R.style.NavigationMapRoute);

      startButton.setVisibility(View.VISIBLE);
      startButton.setBackgroundResource(R.color.colorPrimary);

      ToggleButton toggleSim = findViewById(R.id.toggleSimButton);
      toggleSim.setVisibility(View.VISIBLE);

      }
      navigationMapRoute.addRoute(currentRoute);
      }

      @Override
      public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
      Log.e(TAG, "Error: " + throwable.getMessage());
      }
      });
      }



      @Override
      public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
      permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
      }

      @Override
      public void onExplanationNeeded(List<String> permissionsToExplain) {
      Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
      }

      @Override
      public void onPermissionResult(boolean granted) {
      if (granted) {
      enableLocationComponent();
      } else {
      Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
      finish();
      }
      }

      @Override
      protected void onStart() {
      super.onStart();
      mapView.onStart();
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
      int REQUEST_ENABLE_BT = 1;
      this.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
      }

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

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

      @Override
      protected void onStop() {
      super.onStop();
      mapView.onStop();
      if (disposable != null) {
      disposable.dispose();
      disposable = null;
      }
      }

      @Override
      public void onSaveInstanceState(@NonNull Bundle outState) {
      super.onSaveInstanceState(outState);
      }

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


      @Override
      protected void onDestroy() {
      super.onDestroy();
      mapView.onDestroy();
      if (disposable != null) {
      disposable.dispose();
      disposable = null;
      }
      }

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

      @Override
      public void onBackPressed() {
      // If the navigation view didn't need to do anything, call super
      if (!navigationView.onBackPressed()) {
      super.onBackPressed();
      }
      }


      @Override
      public void onNavigationReady(boolean isRunning) {

      NavigationViewOptions options = NavigationViewOptions.builder()
      .directionsRoute(currentRoute)
      .shouldSimulateRoute(simActive)
      .bannerInstructionsListener(this)
      .milestoneEventListener(MainActivity.this)
      .navigationListener(MainActivity.this)
      .progressChangeListener(MainActivity.this)
      .build();

      navigationView.startNavigation(options);

      }

      @Override
      public void onProgressChange(Location location, RouteProgress routeProgress) {
      if (routeProgress.currentLegProgress().currentStepProgress().distanceRemaining()>20) {
      noRe = false;
      }

      Context context = getApplicationContext();
      String instr = myInstruction.buildInstruction(routeProgress).replaceAll(" ", "");
      int duration = Toast.LENGTH_SHORT;

      if (instr.length() < 20 &&
      !noRe &&
      routeProgress.currentLegProgress().currentStepProgress().distanceRemaining() < activationDistance
      ) {
      noRe = true;
      Toast.makeText(context, instr, duration).show();

      RxBleClient rxBleClient = RxBleClient.create(this);
      device = rxBleClient.getBleDevice(TEST_DEVICE_ADDRESS);


      Disposable disposable = device.establishConnection(false) // <-- autoConnect flag
      .flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(WRITE_CHARACTERISTIC, instr.getBytes()))
      .subscribe(
      characteristicValue -> {
      // Characteristic value confirmed.
      },
      throwable -> {
      // Handle an error here.
      }
      );
      }
      }

      @Override
      public void userOffRoute(Location location) {
      Toast.makeText(this, "offRoute", Toast.LENGTH_LONG).show();
      }

      @Override
      public void onMilestoneEvent(RouteProgress routeProgress, String instruction, Milestone milestone) {

      }

      Instruction myInstruction = new Instruction() {

      @Override
      public String buildInstruction(RouteProgress routeProgress) {
      return routeProgress.currentLegProgress().upComingStep().maneuver().type() + routeProgress.currentLegProgress().upComingStep().maneuver().modifier();
      }
      };

      @Override
      public BannerInstructions willDisplay(BannerInstructions instructions) {

      return instructions;
      }

      @Override
      public void onCancelNavigation() {
      navigationView.stopNavigation();
      }

      @Override
      public void onNavigationFinished() {

      }

      @Override
      public void onNavigationRunning() {

      }

      }


      thanks!










      share|improve this question













      I currently managed to make the navigation work with NavigationView, and now i can set the route with mapView and then start the navigationView by pressing a button on the screen.
      The problem is when I want to get back to mapView by pressing the X button on the bottom right of navigationView, since with the current code below it just stops the navigation from progressing (I have to manually force close the app and re-open it to be able to use it again). I tried to add finish() function just under navigationView.stopNavigation();but i still have to manually force close it.



      Now, I'm a beginner with Java so i might be getting it wrong, but i think the problem is that the code is not restoring in anyway the mapView after having terminated the navigation UI. (why didn't I had such problems with navigationLauncher?)
      Apparently in my code i'm not using fragments, so i was wondering if there's a way to do it without using those (i'm afraid that i would have to rewrite the code to implements fragments).



      Please, don't mind all the junk and the badly written code, since i need it just to build a quick functional prototype!



      package com.bpnavi.backpacknavigator;

      import android.bluetooth.BluetoothAdapter;
      import android.content.Context;
      import android.content.Intent;
      import android.support.annotation.Nullable;
      import android.support.v7.app.AppCompatActivity;
      import android.os.Bundle;

      import com.mapbox.api.directions.v5.DirectionsCriteria;
      import com.mapbox.api.directions.v5.MapboxDirections;
      import com.mapbox.api.directions.v5.models.BannerInstructions;
      import com.mapbox.mapboxsdk.annotations.Marker;
      import com.mapbox.mapboxsdk.annotations.MarkerOptions;
      import com.mapbox.mapboxsdk.camera.CameraPosition;
      import com.mapbox.mapboxsdk.geometry.LatLng;
      import com.mapbox.mapboxsdk.Mapbox;
      import com.mapbox.mapboxsdk.location.modes.RenderMode;
      import com.mapbox.mapboxsdk.maps.MapboxMap;
      import com.mapbox.mapboxsdk.maps.MapView;

      import android.support.annotation.NonNull;
      import android.support.annotation.Nullable;
      import android.support.v4.app.Fragment;
      import android.support.v4.app.FragmentActivity;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;



      // classes needed to add the location component
      import com.mapbox.geojson.Point;
      import com.mapbox.mapboxsdk.maps.MapboxMap;
      import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
      import android.location.Location;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.view.Window;
      import android.widget.Button;
      import android.widget.CompoundButton;
      import android.widget.Toast;
      import com.mapbox.mapboxsdk.geometry.LatLng;
      import android.support.annotation.NonNull;
      import com.mapbox.mapboxsdk.location.LocationComponent;
      import com.mapbox.mapboxsdk.location.modes.CameraMode;
      import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions;
      import com.mapbox.android.core.permissions.PermissionsListener;
      import com.mapbox.android.core.permissions.PermissionsManager;


      // classes to calculate a route
      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.BannerInstructionsListener;
      import com.mapbox.services.android.navigation.ui.v5.listeners.NavigationListener;
      import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute;
      import com.mapbox.services.android.navigation.v5.instruction.Instruction;
      import com.mapbox.services.android.navigation.v5.milestone.Milestone;
      import com.mapbox.services.android.navigation.v5.milestone.MilestoneEventListener;
      import com.mapbox.services.android.navigation.v5.milestone.RouteMilestone;
      import com.mapbox.services.android.navigation.v5.milestone.StepMilestone;
      import com.mapbox.services.android.navigation.v5.milestone.Trigger;
      import com.mapbox.services.android.navigation.v5.milestone.TriggerProperty;
      import com.mapbox.services.android.navigation.v5.navigation.NavigationEventListener;
      import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
      import com.mapbox.api.directions.v5.models.DirectionsResponse;
      import com.mapbox.api.directions.v5.models.DirectionsRoute;
      import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation;
      import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigationOptions;
      import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
      import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
      import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgressState;
      import com.mapbox.services.android.navigation.v5.utils.RouteUtils;

      import io.reactivex.Observable;
      import io.reactivex.disposables.Disposable;
      import retrofit2.Call;
      import retrofit2.Callback;
      import retrofit2.Response;
      import timber.log.Timber;


      // classes needed to launch navigation UI
      import android.view.View;
      import android.widget.Button;
      import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher;

      import com.mapbox.services.android.navigation.v5.offroute.OffRouteListener;
      import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
      import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
      import com.polidea.rxandroidble2.RxBleClient;
      import com.polidea.rxandroidble2.RxBleConnection;
      import com.polidea.rxandroidble2.RxBleDevice;
      import com.polidea.rxandroidble2.internal.RxBleLog;
      import com.polidea.rxandroidble2.scan.ScanSettings;

      import android.util.Log;
      import android.widget.ToggleButton;


      import java.util.List;
      import java.util.UUID;


      public class MainActivity extends AppCompatActivity implements PermissionsListener, MapboxMap.OnMapClickListener, OnNavigationReadyCallback, BannerInstructionsListener,
      MilestoneEventListener, OffRouteListener, ProgressChangeListener, NavigationListener {
      private MapView mapView;
      private NavigationView navigationView;

      private MapboxMap mapboxMap;
      private PermissionsManager permissionsManager;
      private Location originLocation;

      // variables for adding a marker
      private Marker destinationMarker;
      private LatLng originCoord;
      private LatLng destinationCoord;

      // variables for calculating and drawing a route
      private Point originPosition;
      private Point destinationPosition;
      private DirectionsRoute currentRoute;
      private static final String TAG = "DirectionsActivity";
      private NavigationMapRoute navigationMapRoute;
      private MapboxDirections client;
      private Button startButton;

      public static final String BACKPACK_DEVICE_ADDRESS = "321";
      public static final String TEST_DEVICE_ADDRESS = "123";
      private static final UUID WRITE_CHARACTERISTIC = UUID.fromString("abc123");
      private Disposable disposable;
      private RxBleDevice device;
      private BannerInstructions BannerInstructionMilestone;
      private MapboxNavigation navigation;

      private static final int INSTR_MILESTONE = 1001;
      private boolean noRe = false;
      private boolean simActive = true;
      private int activationDistance = 15;

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

      RxBleClient rxBleClient = RxBleClient.create(this);

      device = rxBleClient.getBleDevice(TEST_DEVICE_ADDRESS);

      Disposable disposable = device.establishConnection(false) // <-- autoConnect flag
      .subscribe(
      rxBleConnection -> {
      // All GATT operations are done through the rxBleConnection.
      },
      throwable -> {
      // Handle an error here.
      }
      );
      // disposable.dispose();


      Mapbox.getInstance(this, getString(R.string.access_token));
      setContentView(R.layout.activity_main);
      mapView = (MapView) findViewById(R.id.mapView);
      startButton = findViewById(R.id.startButton);

      startButton.setOnClickListener(v -> {
      setTheme(R.style.Theme_AppCompat_NoActionBar);
      setContentView(R.layout.activity_navigation);
      navigationView = findViewById(R.id.navigationView);
      navigationView.onCreate(savedInstanceState);
      navigationView.initialize(this);

      // boolean simulateRoute = true;
      // NavigationLauncherOptions options = NavigationLauncherOptions.builder()
      // .directionsRoute(currentRoute)
      // .shouldSimulateRoute(simulateRoute)
      // .build();
      // // Call this method with Context from within an Activity
      // NavigationLauncher.startNavigation(MainActivity.this, options);
      });

      MapboxNavigationOptions navOptions = MapboxNavigationOptions.builder().isDebugLoggingEnabled(true).build();
      navigation = new MapboxNavigation(getApplicationContext(), getString(R.string.access_token), navOptions);
      navigation.addMilestoneEventListener(this);


      navigation.addMilestone(new StepMilestone.Builder()
      .setIdentifier(INSTR_MILESTONE)
      .setInstruction(this.myInstruction)
      .setTrigger(
      Trigger.all(
      Trigger.lt(TriggerProperty.STEP_DISTANCE_REMAINING_METERS, 10)))
      .build()
      );

      mapView.onCreate(savedInstanceState);
      mapView.getMapAsync(mapboxMap -> {
      MainActivity.this.mapboxMap = mapboxMap;
      enableLocationComponent();

      originCoord = new LatLng(originLocation.getLatitude(), originLocation.getLongitude());

      mapboxMap.addOnMapClickListener(this);

      //Set stuff here
      mapboxMap.addMarker(new MarkerOptions()
      .position(new LatLng(45.506833, 9.163333))
      .title("Politecnico di Milano")
      .snippet("Dipartimento di Design")
      );
      });

      }

      @SuppressWarnings( {"MissingPermission"})
      private void enableLocationComponent() {
      // Check if permissions are enabled and if not request
      if (PermissionsManager.areLocationPermissionsGranted(this)) {
      // Activate the MapboxMap LocationComponent to show user location
      // Adding in LocationComponentOptions is also an optional parameter
      LocationComponent locationComponent = mapboxMap.getLocationComponent();
      locationComponent.activateLocationComponent(this);
      locationComponent.setLocationComponentEnabled(true);
      // Set the component's camera mode
      locationComponent.setCameraMode(CameraMode.TRACKING_GPS);
      locationComponent.setRenderMode(RenderMode.GPS);
      originLocation = locationComponent.getLastKnownLocation();

      } else {
      permissionsManager = new PermissionsManager(this);
      permissionsManager.requestLocationPermissions(this);
      }
      }

      @Override
      public void onMapClick(@NonNull LatLng point){

      if (destinationMarker != null) {
      mapboxMap.removeMarker(destinationMarker);
      }
      destinationCoord = point;
      destinationMarker = mapboxMap.addMarker(new MarkerOptions()
      .position(destinationCoord)
      );

      destinationPosition = Point.fromLngLat(destinationCoord.getLongitude(), destinationCoord.getLatitude());
      originPosition = Point.fromLngLat(originCoord.getLongitude(), originCoord.getLatitude());
      getRoute(originPosition, destinationPosition);
      }




      private void getRoute(Point origin, Point destination) {

      Toast.makeText(this, "Calculating route...", Toast.LENGTH_SHORT).show();

      MapboxDirections.builder()
      .origin(origin)
      .destination(destination)
      .accessToken(getString(R.string.access_token))
      .profile(DirectionsCriteria.PROFILE_CYCLING)
      .bannerInstructions(true)
      .steps(true)
      .roundaboutExits(true)
      .build();

      NavigationRoute.builder(this)
      .accessToken(getString(R.string.access_token))
      .origin(origin)
      .destination(destination)
      .profile(DirectionsCriteria.PROFILE_CYCLING)
      .voiceUnits("metric")
      .build()
      .getRoute(new Callback<DirectionsResponse>() {
      @Override
      public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
      // You can get the generic HTTP info about the response
      Log.d(TAG, "Response code: " + response.code());
      if (response.body() == null) {
      Log.e(TAG, "No routes found, make sure you set the right user and access token.");
      return;
      } else if (response.body().routes().size() < 1) {
      Log.e(TAG, "No routes found");
      return;
      }

      currentRoute = response.body().routes().get(0);

      // Draw the route on the map
      if (navigationMapRoute != null) {
      navigationMapRoute.removeRoute();
      } else {
      navigationMapRoute = new NavigationMapRoute(null, mapView, mapboxMap, R.style.NavigationMapRoute);

      startButton.setVisibility(View.VISIBLE);
      startButton.setBackgroundResource(R.color.colorPrimary);

      ToggleButton toggleSim = findViewById(R.id.toggleSimButton);
      toggleSim.setVisibility(View.VISIBLE);

      }
      navigationMapRoute.addRoute(currentRoute);
      }

      @Override
      public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
      Log.e(TAG, "Error: " + throwable.getMessage());
      }
      });
      }



      @Override
      public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
      permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
      }

      @Override
      public void onExplanationNeeded(List<String> permissionsToExplain) {
      Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
      }

      @Override
      public void onPermissionResult(boolean granted) {
      if (granted) {
      enableLocationComponent();
      } else {
      Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
      finish();
      }
      }

      @Override
      protected void onStart() {
      super.onStart();
      mapView.onStart();
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
      int REQUEST_ENABLE_BT = 1;
      this.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
      }

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

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

      @Override
      protected void onStop() {
      super.onStop();
      mapView.onStop();
      if (disposable != null) {
      disposable.dispose();
      disposable = null;
      }
      }

      @Override
      public void onSaveInstanceState(@NonNull Bundle outState) {
      super.onSaveInstanceState(outState);
      }

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


      @Override
      protected void onDestroy() {
      super.onDestroy();
      mapView.onDestroy();
      if (disposable != null) {
      disposable.dispose();
      disposable = null;
      }
      }

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

      @Override
      public void onBackPressed() {
      // If the navigation view didn't need to do anything, call super
      if (!navigationView.onBackPressed()) {
      super.onBackPressed();
      }
      }


      @Override
      public void onNavigationReady(boolean isRunning) {

      NavigationViewOptions options = NavigationViewOptions.builder()
      .directionsRoute(currentRoute)
      .shouldSimulateRoute(simActive)
      .bannerInstructionsListener(this)
      .milestoneEventListener(MainActivity.this)
      .navigationListener(MainActivity.this)
      .progressChangeListener(MainActivity.this)
      .build();

      navigationView.startNavigation(options);

      }

      @Override
      public void onProgressChange(Location location, RouteProgress routeProgress) {
      if (routeProgress.currentLegProgress().currentStepProgress().distanceRemaining()>20) {
      noRe = false;
      }

      Context context = getApplicationContext();
      String instr = myInstruction.buildInstruction(routeProgress).replaceAll(" ", "");
      int duration = Toast.LENGTH_SHORT;

      if (instr.length() < 20 &&
      !noRe &&
      routeProgress.currentLegProgress().currentStepProgress().distanceRemaining() < activationDistance
      ) {
      noRe = true;
      Toast.makeText(context, instr, duration).show();

      RxBleClient rxBleClient = RxBleClient.create(this);
      device = rxBleClient.getBleDevice(TEST_DEVICE_ADDRESS);


      Disposable disposable = device.establishConnection(false) // <-- autoConnect flag
      .flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(WRITE_CHARACTERISTIC, instr.getBytes()))
      .subscribe(
      characteristicValue -> {
      // Characteristic value confirmed.
      },
      throwable -> {
      // Handle an error here.
      }
      );
      }
      }

      @Override
      public void userOffRoute(Location location) {
      Toast.makeText(this, "offRoute", Toast.LENGTH_LONG).show();
      }

      @Override
      public void onMilestoneEvent(RouteProgress routeProgress, String instruction, Milestone milestone) {

      }

      Instruction myInstruction = new Instruction() {

      @Override
      public String buildInstruction(RouteProgress routeProgress) {
      return routeProgress.currentLegProgress().upComingStep().maneuver().type() + routeProgress.currentLegProgress().upComingStep().maneuver().modifier();
      }
      };

      @Override
      public BannerInstructions willDisplay(BannerInstructions instructions) {

      return instructions;
      }

      @Override
      public void onCancelNavigation() {
      navigationView.stopNavigation();
      }

      @Override
      public void onNavigationFinished() {

      }

      @Override
      public void onNavigationRunning() {

      }

      }


      thanks!







      android mapbox mapbox-android






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 27 at 13:15









      NoveB

      11




      11





























          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53945729%2fcancelnavigation-button-does-not-go-back-to-mapview-from-navigationview%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53945729%2fcancelnavigation-button-does-not-go-back-to-mapview-from-navigationview%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Monofisismo

          Angular Downloading a file using contenturl with Basic Authentication

          Olmecas