Кнопка cancelNavigation не возвращает к просмотру карты из навигации. - PullRequest
0 голосов
/ 27 декабря 2018

Мне в настоящее время удалось настроить навигацию с помощью NavigationView, и теперь я могу установить маршрут с помощью mapView, а затем запустить navigationView, нажав кнопку на экране.Проблема в том, что когда я хочу вернуться к mapView, нажав кнопку X в правом нижнем углу navigationView, так как с текущим кодом ниже он просто останавливает навигацию (мне приходится вручную принудительно закрывать приложение иснова откройте его, чтобы иметь возможность использовать его снова).Я пытался добавить finish() функцию чуть ниже navigationView.stopNavigation();, но мне все равно пришлось вручную принудительно закрывать ее.

Теперь я новичок в Java, поэтому могу ошибаться, но я думаю, чтопроблема в том, что код не восстанавливается в любом случае mapView после завершения пользовательского интерфейса навигации.(почему у меня не было таких проблем с navigationLauncher?) Очевидно, в моем коде я не использую фрагменты, поэтому мне было интересно, есть ли способ сделать это без их использования (я боюсь, что мне придетсяпереписать код для реализации фрагментов).

Пожалуйста, не обращайте внимания на весь мусор и плохо написанный код, поскольку он мне нужен просто для создания быстрого функционального прототипа!

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

    }

}

спасибо!

1 Ответ

0 голосов
/ 21 февраля 2019

Вы упомянули, что пытались поместить finish() в navigationView.stopNavigation(), который, как я вижу, вы вызываете внутри вашего onCancelNavigation() метода.Вы пытались вместо этого ввести finish() в свой метод onCancelNavigation()?

@Override
public void onCancelNavigation() {
    finish();
}

Я реализовал пользовательский интерфейс Mapbox Navigation на прошлой неделе, и это метод, который я использовал, чтобы получить крестикКнопка (X) в правой нижней части пользовательского интерфейса возвращает меня к MapView / предыдущему действию.

Надеюсь, это поможет!

...