Mapbox导航useroffroute函数替代无法正常工作 [英] Mapbox navigation useroffroute function override not working

查看:104
本文介绍了Mapbox导航useroffroute函数替代无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

未触发偏离路线

我正在使用导航启动器.我也尝试过使用导航视图.但是没有触发useroffroute功能.

I am using navigation launcher.I have tried using navigation view too.But the useroffroute function is not getting triggered.

package com.example.lenovo.offroutetest;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
// classes needed to initialize map
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
// 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.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 needed to add a marker
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
// 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.route.NavigationMapRoute;
import com.mapbox.services.android.navigation.v5.instruction.Instruction;
import com.mapbox.services.android.navigation.v5.milestone.BannerInstructionMilestone;
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.Trigger;
import com.mapbox.services.android.navigation.v5.milestone.TriggerProperty;
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.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.offroute.OffRouteListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
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.navigation.NavigationEventListener;

import okhttp3.Route;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.util.Log;
// classes needed to launch navigation UI
import android.view.View;
import android.widget.Button;
import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher;

import org.intellij.lang.annotations.Identifier;

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, MapboxMap.OnMapClickListener, OffRouteListener,PermissionsListener,MilestoneEventListener, ProgressChangeListener,NavigationEventListener{
    private MapView mapView;
    // variables for adding location layer
    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 Button button;
    private MapboxNavigation navigation;
    private NavigationView navigationView;
    private CoordinatorLayout coordinatorLayout;
    private boolean running;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Mapbox.getInstance(this,"pk.eyJ1IjoicHJpeWFuZ2EiLCJhIjoiY2pwYzQ1OGxpMGgybTNscGhsbjA0cXlvcSJ9.MJD97KhqBQifpKRrPGtomg");
        //MapboxNavigationOptions options = MapboxNavigationOptions.builder().isDebugLoggingEnabled(true).build();
        //MapboxNavigationOptions opt=MapboxNavigationOptions.builder().build()
        navigation=new MapboxNavigation(MainActivity.this,"pk.eyJ1IjoicHJpeWFuZ2EiLCJhIjoiY2pwYzQ1OGxpMGgybTNscGhsbjA0cXlvcSJ9.MJD97KhqBQifpKRrPGtomg");
        //navigation.addOffRouteListener(offRouteListener);
        //navigation.addMilestoneEventListener(this);
        navigation.addMilestone(new BannerInstructionMilestone.Builder().setIdentifier(1).setTrigger(Trigger.all(Trigger.eq(TriggerProperty.LAST_STEP, TriggerProperty.TRUE))).setInstruction(new Instruction() {
            @Override
            public String buildInstruction(RouteProgress routeProgress) {

                return "I AM HERE";
            }
        }).build());
        setContentView(R.layout.activity_main);
        mapView = findViewById(R.id.mapView);
        //navigationView=findViewById(R.id.navigationView);
        //navigationView.onCreate(savedInstanceState);
        //navigationView.initialize(this);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(this);
    }

    @Override
    public void onMilestoneEvent(RouteProgress routeProgress, String instruction, Milestone milestone) {
        //exampleInstructionPlayer.play(instruction);
        Log.e("milestone","reached");
        Toast.makeText(getApplicationContext(),"Milestone triggered",Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onMapReady(MapboxMap mapboxMap) {
        this.mapboxMap = mapboxMap;
        enableLocationComponent();
        originCoord = new LatLng(originLocation.getLatitude(), originLocation.getLongitude());
        mapboxMap.addOnMapClickListener(this);
        button = findViewById(R.id.startButton);
        /*navigation.addOffRouteListener(new OffRouteListener() {
            @Override
            public void userOffRoute(Location location) {
                Snackbar snackbar = Snackbar
                        .make(coordinatorLayout, "User rerouting", Snackbar.LENGTH_LONG);
                snackbar.show();
                Toast.makeText(getApplicationContext(), "Off route", Toast.LENGTH_SHORT).show();
                //File path = getApplicationContext().getFilesDir();
                //File path=getApplicationContext().getExternalFilesDir(null);
                try {
                    File path=getApplicationContext().getFilesDir();
                    Toast.makeText(getApplicationContext(),String.valueOf(path),Toast.LENGTH_SHORT).show();
                    File file = new File(path, "off_route.txt");
                    FileOutputStream stream = new FileOutputStream(file);
                    stream.write(("Offroute"+location.toString()).getBytes());
                    stream.close();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        });*/
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //NavigationViewOptions navopt=NavigationViewOptions.builder().directionsRoute(currentRoute).shouldSimulateRoute(false).build();
                boolean simulateRoute = false;
                NavigationLauncherOptions options = NavigationLauncherOptions.builder()
                        .directionsRoute(currentRoute)
                        .shouldSimulateRoute(simulateRoute)
                        .build();
                // Call this method with Context from within an Activity
                NavigationLauncher.startNavigation(MainActivity.this, options);
                //navigation.startNavigation(currentRoute);
                //navigation.startNavigation(currentRoute);
                //navigationView.startNavigation(navopt);
            }
        });
    }

    @Override
    public void onProgressChange(Location location, RouteProgress routeProgress)
    {

    }

    @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);
        button.setEnabled(true);
        button.setBackgroundResource(R.color.mapboxBlue);
        /*try {
            //File path=getApplicationContext().getFilesDir();
            File path=getApplicationContext().getExternalFilesDir(null);
            Toast.makeText(getApplicationContext(),String.valueOf(path.getAbsolutePath()),Toast.LENGTH_SHORT).show();
            //File path = getApplicationContext().getExternalFilesDir(null);
            File file = new File(path, "off_route.txt");
            //Log.e("Writing to file","file");
            FileOutputStream stream = new FileOutputStream(file);
            stream.write("Offroute am there".getBytes());
            Toast.makeText(getApplicationContext(),"I ma here",Toast.LENGTH_LONG).show();
            stream.close();
        }
        catch (Exception e)
        {
            Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }*/

    }

    @Override
    public void userOffRoute(Location location) {
        //Snackbar snackbar = Snackbar
          //      .make(coordinatorLayout, "User rerouting", Snackbar.LENGTH_LONG);
        //snackbar.show();
        Toast.makeText(getApplicationContext(), "Off route detected.........", Toast.LENGTH_SHORT).show();
        //File path = getApplicationContext().getFilesDir();
        //File path=getApplicationContext().getExternalFilesDir(null);
        try {
            File path=getApplicationContext().getExternalFilesDir(null);
            Toast.makeText(getApplicationContext(),String.valueOf(path),Toast.LENGTH_SHORT).show();
            File file = new File(path, "useroff.txt");
            FileOutputStream stream = new FileOutputStream(file);
            stream.write(("Offroute"+location.toString()).getBytes());
            stream.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    @Override

    public void onRunning(boolean running)
    {
        this.running=running;
        if(running)
        {
            //navigation.addOffRouteListener(this);
            //navigation.addProgressChangeListener(this);
        }
    }



    private void getRoute(Point origin, Point destination) {
        NavigationRoute.builder(this)
                .accessToken(Mapbox.getAccessToken())
                .origin(origin)
                .destination(destination)
                .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(navigation, mapView, mapboxMap, R.style.NavigationMapRoute);
                        }
                        navigationMapRoute.addRoute(currentRoute);
                    }

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

    @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);
            originLocation = locationComponent.getLastKnownLocation();

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

    @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();
    }

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

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

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

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

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

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




}

我希望被我覆盖的功能useroffroute被触发.但是没有触发发生,因为当用户偏离路线时无法看到Toast消息和文件创建.

I expect the function useroffroute overridden by me gets triggered.But no trigger happens as in am not able to see the toast message and file creation when the user goes offroute.

推荐答案

因此,这里要解决的第一件事是,这绝对不适用于 NavigationLauncher .该对象实际上是一个功能全面的解决方案,可通过最少的自定义快速启动和运行.因此它不够灵活,并且不允许您修改 offRoute 侦听器.这只能通过 NavigationView 来实现.

So the first thing to address here is that this will definitely not work with NavigationLauncher. That object is really meant to be a full-featured solution to get nav up and running quickly with minimal customization. So it is not quite as flexible and doesn't allow you to modify your offRoute listeners. This is only possible with NavigationView.

很容易错过,但是有关如何覆盖默认重路由行为的文档实际上是在地图匹配文档中概述的:

It's easy to miss, but the documentation for how to override the default reroute behavior is actually outlined in the Map Matching docs: https://docs.mapbox.com/android/navigation/overview/map-matching/#map-matching-with-mapboxnavigation

考虑到这一点,您似乎在代码中缺少了关键的一步.将 offRouteListener 添加到 navigation 对象时,您需要执行并覆盖 userOffRoute 函数.最终看起来像这样:

With that in mind, it looks like you're missing one crucial step in your code. When you add an offRouteListener to you navigation object, you need to carry through and override the userOffRoute function. Which would end up looking like this:

navigation.addOffRouteListener(new OffRouteListener() {
    @Override
    public void userOffRoute(Location location) {
        Toast.makeText(getApplicationContext(), "Off route detected.........", Toast.LENGTH_SHORT).show();
        // Make sure you call for a new DirectionsRoute object
        // and end by calling MapboxNavigation#startNavigation on a successful
    }
});

这篇关于Mapbox导航useroffroute函数替代无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆