Giter Club home page Giter Club logo

mapbox-navigation-android's Introduction

Mapbox Service

When your users want to get from one location to another, don’t push them out of your application into a generic map application. Instead, keep them engaged with your application 100% of the time with in-app turn-by-turn navigation.

The Mapbox Navigation SDK for Android is built on top of the Mapbox Directions API and the Mapbox Maps SDK to provide tools needed to build a complete navigation experience.

The Mapbox Navigation SDK is a precise and flexible platform which enables your users to explore the world's streets. We are designing new maps specifically for navigation that highlight traffic conditions and helpful landmarks. The calculations are based on the user's current location and compare it to the current route that the user's traversing to provide critical information at any given moment. You control the entire experience, from the time your user chooses a destination to when they arrive.

Getting Started

Refer to the full documentation pages for installation and usage instructions.

For the latest version and changelog visit CHANGELOG or releases pages.

Along with the full documentation, this migration guide can help you transition your project from version v1 of the Navigation SDK to v2 or higher.

Getting Help

  • Need help with your code?: Look for previous questions on the #mapbox tag — or ask a new question.
  • Have a bug to report? Open an issue. If possible, include the version of Mapbox Services, a full log, and a project that shows the issue.
  • Have a feature request? Open an issue. Tell us what the feature should do and why you want the feature.

Using Snapshots

You can use a -SNAPSHOT release if you want to test recent bug fixes or features that have not been packaged in an official release yet.

1.0.0+ versions of the Navigation SDK:

To access SNAPSHOT builds follow the installation instructions and then:

  1. Provide the below additional snapshot repository reference, next to the existing release repository reference:
maven {
    url 'https://api.mapbox.com/downloads/v2/snapshots/maven'
    authentication {
        basic(BasicAuthentication)
    }
    credentials {
        username = "mapbox"
        password = "{secret Mapbox token with DOWNLOADS:READ scope, the same as the token used for the release repository}"
    }
}
  1. Append -SNAPSHOT to the target version:
dependencies {
  implementation "com.mapbox.navigation:android:X.Y.Z-SNAPSHOT"
}

You can find the latest snapshot version reference in gradle.properties.

Examples for Mapbox Navigation Android SDK are now available on their own separate repo, available here.

The QA application is available here.

General documentation for Mapbox Navigation Android SDK is available here.

Contributing

We welcome feedback, translations, and code contributions! Please see CONTRIBUTING.md for details.

mapbox-navigation-android's People

Contributors

abhishek1508 avatar andrlee avatar cafesilencio avatar d-prukop avatar danesfeder avatar dzinad avatar dzmitryfomchyn avatar evabishchevich avatar guardiola31337 avatar jundai avatar kmadsen avatar korshaknn avatar langsmith avatar lebedinsky avatar lukaspaczos avatar mapbox-github-ci-writer-3[bot] avatar mapbox-github-ci-writer-4[bot] avatar mapbox-github-ci-writer-public-1[bot] avatar n-frolov avatar olegzil avatar pengdev avatar ringerjk avatar sevazhukov avatar tobrun avatar tomaszrybakiewicz avatar vitaminpsg avatar vysotskivadim avatar zayankovsky avatar zeac avatar zugaldia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mapbox-navigation-android's Issues

Navigation notification improvement

We don't allow much customization for the notification currently being offered in the SDK, we should add a default notification but also allow devs to pass in their own notifications or even disable the notifications.

The NavigationService onProgressChance can be used for updating the notification.

Navigating through Waypoints stops at first coordinate

Hi, i have implemented a simple navigation UI, from the information that "RouteProgress" object gives. this is how i create "MapboxDirection" object:

 return new MapboxDirections.Builder()
              .setOverview(DirectionsCriteria.OVERVIEW_FULL)
              .setSteps(true)
              .setAccessToken(getString(R.string.mapbox_access_token))
              .setCoordinates(coords)
              .setProfile(DirectionsCriteria.PROFILE_DRIVING)
              .build();

coords are a list of coordinates, where the first element in the list is my current location, the last element is the destination, and <21 points in between are waypoints (not stopovers). But the RouteProgress + onAlertLevelChange seems to think that when i come to my second coordinate (from my current location to first waypoint), that the trip is over and i get "You have arrived at your destination" in routeProgress.getCurrentLegProgress().getUpComingStep().getManeuver().getInstruction()
and the routeProgress.getCurrentLegProgress().getDistanceRemaining() is 0. But routeProgress.getDistanceRemaining() and the duration of the whole routeProgress is still there. I also get ARRIVE_ALERT_LEVEL in onAlertLevelChange, at the second coordinate.So how do i make the navigation advance the route leg, without actually stopping navigatint after the fist waypoint.

Test App fails to run any of the activities other than MainActivity.

I'm having issues running the test application. OnCreate in each activity fails to load when setting the view.

setContentView(R.layout.activity_navigation_activity);

android.view.InflateException: Binary XML file line #12: Binary XML file line #12: Error inflating class com.mapbox.mapboxsdk.maps.MapView

I'm at a loss to what the issue is, as I'm running the entire project cloned.

Thanks for any help!

Can I use mapbox navigation to create an indoor navigation?

How could i use sdk navigation to create a navigation inside an indoor map? Let me explain better, I need to create a navigation application for internal locations that shows the route and navigates from one place to another. To make the location of the user without using the gps, I will use qr codes scattered throughout the building to give me the exact location of the user and then show the route and make the navigation to the destination. But I'm not sure if it's possible to do this using the mapbox, since it's geared towards external applications.

I need to create something like this:
image

I would be grateful if anyone could help me.

Add RxJava Support

Similar to how we have created a module for RxJava specific support in Mapbox-Java, we should consider doing the same for the navigation SDK.

NPE on MapboxNavigationOptions.getMinimumHighAlertDistance() in example

Sometimes while running the demo app and the Navigation example it crashes after you have started a route. Does not happen all the time. I tried 5-10 times without a crash yesterday but later I got 5 crashes in a row.

Tested on Google Pixel XL running 7.1.2 and navigation 0.1.

E java.lang.NullPointerException: Attempt to invoke virtual method 'double com.mapbox.services.android.navigation.v5.MapboxNavigationOptions.getMinimumHighAlertDistance()' on a null object reference
E at com.mapbox.services.android.navigation.v5.LocationUpdatedThread.monitorStepProgress(LocationUpdatedThread.java:158)

Should make sure options are not null for that entire method. Seeing that options is used later in that method (monitorStepProgress) as well.

Prevent abrupt re-routing / immediate u-turns

Occasionally during rerouting, the SDK will return a maneuver that's too close to the user's current location and can lead to a missed turn and frequent + repeated re-routing.

If the user was driving 70km/h along a road and missed a left turn, the navigation SDK would trigger a re-route and receive a directions response requiring another left turn or U-turn almost immediately. At the high speed the user was traveling, the immediacy of the maneuver would be too much to act on, and the user would miss the turn and trigger another re-route, and so on.

As a first pass suggestion by @danpat, we can validate that a re-route is reasonable before presenting to the user:

  1. Request the re-route and get back the new response from the Directions API.
  2. Examine the first step. If it's not too quick, display the re-route to the user.
    If it is "too quick" (threshold to be determined), use the intersections object to predict the driver's probable path past the "too quick turn", and request another route from the Directions API that starts somewhere past the "too quick" turn.

cc @cammace

Premature maneuver completion announcements

Sometimes, maneuver completion announcements can happen prematurely.

An example of a driver that's told to make a left turn:

He arrives at the light and stops at the intersection. While he's stationary and waiting for the light to turn, the SDK considers the maneuver complete (presumably because the GPS location moved around slightly) and gives him the next instruction as if he's continued driving. Despite the announcement, the confused user is still waiting for the light to turn green.

@1ec5 proposed a more sophisticated model for determining maneuver state:

Ultimately, we may need to model maneuvers as a state machine rather than reevaluating turn completion factors from scratch on every location update.

Android version of mapbox/mapbox-navigation-ios#222

cc @cammace

MockLocationEngine and setLocationSource

Hey,
I'm using your pretty cool MockLocationEngine from the demo project. I noticed that the myLocationEnabled state is resettet after the LocationEngine is set (@ mapbox-android-navigation:0.2.0).

If I use only this code, the myLocation-Dot at the map doesn't move (even if I had set myLocationEnabled to true and MyLocationTracking.TRACKING_FOLLOW).
mapboxMap.setLocationSource(mockLocationEngine);

With the additional line
mapboxMap.setMyLocationEnabled(true);
everything work well.

But: In both cases the onMyLocationChange-Listener receives the update from MockLocationEngine

Running Navigation in Fragment

I can't seem to get the navigation to start from a fragment.

All is fine on the routing front, draws the route. But it seems that the line below is where nothing happens:

navigation.startNavigation(route);

No Errors, nothing back from the navigation listeners.

Here is my code

package au.com.gardenbagsbrisbane.gardenbagsdriver.fragment;

import android.content.Context;
import android.graphics.Color;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.support.annotation.NonNull;
import android.support.design.widget.BaseTransientBottomBar;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

import au.com.gardenbagsbrisbane.gardenbagsdriver.R;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import timber.log.Timber;

import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationSource;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.services.Constants;
import com.mapbox.services.android.navigation.v5.MapboxNavigation;
import com.mapbox.services.android.navigation.v5.NavigationConstants;
import com.mapbox.services.android.navigation.v5.RouteProgress;
import com.mapbox.services.android.navigation.v5.listeners.AlertLevelChangeListener;
import com.mapbox.services.android.navigation.v5.listeners.NavigationEventListener;
import com.mapbox.services.android.navigation.v5.listeners.OffRouteListener;
import com.mapbox.services.android.navigation.v5.listeners.ProgressChangeListener;
import com.mapbox.services.android.telemetry.location.LocationEngine;
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
import com.mapbox.services.android.telemetry.permissions.PermissionsListener;
import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
import com.mapbox.services.api.directions.v5.models.DirectionsResponse;
import com.mapbox.services.api.directions.v5.models.DirectionsRoute;
import com.mapbox.services.commons.geojson.LineString;
import com.mapbox.services.commons.models.Position;
import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link HomeFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link HomeFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class HomeFragment extends Fragment implements PermissionsListener, OnMapReadyCallback,MapboxMap.OnMapClickListener,
        ProgressChangeListener, NavigationEventListener, AlertLevelChangeListener, OffRouteListener {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private MapView mapView = null;
    private MapboxMap map;
    private FloatingActionButton floatingActionButton;
    private LocationEngineListener locationEngineListener;
    private PermissionsManager permissionsManager;

    private Marker destinationMarker;

    // Navigation related variables
    private LocationEngine locationEngine;
    private MapboxNavigation navigation;
    private FloatingActionButton startRouteButton;
    private DirectionsRoute route;
    private Position destination;
    private Polyline routeLine;
    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    public HomeFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment HomeFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static HomeFragment newInstance(String param1, String param2) {
        HomeFragment fragment = new HomeFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        Mapbox.getInstance(getActivity(), getString(R.string.access_token));
        View layout = inflater.inflate(R.layout.fragment_home, container, false);

        mapView = (MapView) layout.findViewById(R.id.mapboxMapView);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(this);

        //locationEngine.activate();
        locationEngine = LocationSource.getLocationEngine(getActivity());
        navigation = new MapboxNavigation(getActivity(), Mapbox.getAccessToken());
        locationEngine.setInterval(0);
        locationEngine.setSmallestDisplacement(3.0f);
        locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
        locationEngine.setFastestInterval(1000);

        navigation.setLocationEngine(locationEngine);


        floatingActionButton = (FloatingActionButton) layout.findViewById(R.id.location_toggle_fab);
        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (map != null) {
                    toggleGps(!map.isMyLocationEnabled());
                }
            }
        });
        startRouteButton = (FloatingActionButton) layout.findViewById(R.id.startRouteButton);
        startRouteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (navigation != null && route != null) {

                    // Hide the start button
                    startRouteButton.setVisibility(View.INVISIBLE);

                    // Attach all of our navigation listeners.
                    navigation.addNavigationEventListener(HomeFragment.this);
                    navigation.addProgressChangeListener(HomeFragment.this);
                    navigation.addAlertLevelChangeListener(HomeFragment.this);

                    // Adjust location engine to force a gps reading every second. This isn't required but gives an overall
                    // better navigation experience for users. The updating only occurs if the user moves 3 meters or further
                    // from the last update.
                    navigation.startNavigation(route);
                }
                else
                {
                    Timber.e("No valid navigation object or route");
                }
            }
        });
        return layout;
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }
    @Override
    public void onMapReady(MapboxMap mapboxMap) {
        map = mapboxMap;
        map.setOnMapClickListener(HomeFragment.this);
        Snackbar.make(mapView, "Tap map to place destination", BaseTransientBottomBar.LENGTH_LONG).show();

        map.moveCamera(CameraUpdateFactory.zoomBy(12));

        if (PermissionsManager.areLocationPermissionsGranted(getActivity())) {
            mapboxMap.setMyLocationEnabled(true);
            mapboxMap.getTrackingSettings().setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
        }
    }

    @Override
    public void onMapClick(@NonNull LatLng point) {
        if (destinationMarker != null) {
            map.removeMarker(destinationMarker);
        }
        destinationMarker = map.addMarker(new MarkerOptions().position(point));

        startRouteButton.setVisibility(View.VISIBLE);

        destination = Position.fromCoordinates(point.getLongitude(), point.getLatitude());
        calculateRoute();
    }
    private void drawRouteLine(DirectionsRoute route) {
        List<Position> positions = LineString.fromPolyline(route.getGeometry(), Constants.PRECISION_6).getCoordinates();
        List<LatLng> latLngs = new ArrayList<>();
        for (Position position : positions) {
            latLngs.add(new LatLng(position.getLatitude(), position.getLongitude()));
        }

        // Remove old route if currently being shown on map.
        if (routeLine != null) {
            map.removePolyline(routeLine);
        }

        routeLine = map.addPolyline(new PolylineOptions()
                .addAll(latLngs)
                .color(Color.parseColor("#56b881"))
                .width(5f));
    }

    private void calculateRoute() {
        Location userLocation = map.getMyLocation();
        if (userLocation == null) {
            Timber.d("calculateRoute: User location is null, therefore, origin can't be set.");
            return;
        }

        Position origin = (Position.fromCoordinates(userLocation.getLongitude(), userLocation.getLatitude()));
        navigation.getRoute(origin, destination, new Callback<DirectionsResponse>() {
            @Override
            public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
                DirectionsRoute route = response.body().getRoutes().get(0);
                HomeFragment.this.route = route;
                drawRouteLine(route);
                navigation.addNavigationEventListener(HomeFragment.this);
                navigation.addProgressChangeListener(HomeFragment.this);
                navigation.addAlertLevelChangeListener(HomeFragment.this);

                // Adjust location engine to force a gps reading every second. This isn't required but gives an overall
                // better navigation experience for users. The updating only occurs if the user moves 3 meters or further
                // from the last update.
                navigation.startNavigation(route);
            }

            @Override
            public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
                Timber.e("onFailure: navigation.getRoute()", throwable);
            }
        });
    }
    /*
   * Navigation listeners
   */

    @Override
    public void onRunning(boolean running) {
        if (running) {
            Timber.d("onRunning: Started");
        } else {
            Timber.d("onRunning: Stopped");
        }
    }

    @Override
    public void onProgressChange(Location location, RouteProgress routeProgress) {
        Timber.d("onProgressChange: fraction of route traveled: %f", routeProgress.getFractionTraveled());
    }

    @Override
    public void onAlertLevelChange(int alertLevel, RouteProgress routeProgress) {

        switch (alertLevel) {
            case NavigationConstants.HIGH_ALERT_LEVEL:
                Toast.makeText(getActivity(), "HIGH", Toast.LENGTH_LONG).show();
                break;
            case NavigationConstants.MEDIUM_ALERT_LEVEL:
                Toast.makeText(getActivity(), "MEDIUM", Toast.LENGTH_LONG).show();
                break;
            case NavigationConstants.LOW_ALERT_LEVEL:
                Toast.makeText(getActivity(), "LOW", Toast.LENGTH_LONG).show();
                break;
            case NavigationConstants.ARRIVE_ALERT_LEVEL:
                Toast.makeText(getActivity(), "ARRIVE", Toast.LENGTH_LONG).show();
                break;
            case NavigationConstants.DEPART_ALERT_LEVEL:
                Toast.makeText(getActivity(), "DEPART", Toast.LENGTH_LONG).show();
                break;
            default:
            case NavigationConstants.NONE_ALERT_LEVEL:
                Toast.makeText(getActivity(), "NONE", Toast.LENGTH_LONG).show();
                break;
        }
    }

    @Override
    public void userOffRoute(Location location) {
        Position newOrigin = Position.fromCoordinates(location.getLongitude(), location.getLatitude());
        navigation.updateRoute(newOrigin, destination, new Callback<DirectionsResponse>() {
            @Override
            public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
                DirectionsRoute route = response.body().getRoutes().get(0);
                HomeFragment.this.route = route;

                // Remove old route line from map and draw the new one.
                map.removePolyline(routeLine);
                drawRouteLine(route);
            }

            @Override
            public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
                Timber.e("onFailure: navigation.getRoute()", throwable);
            }
        });
    }
     /*
   * Activity lifecycle methods
   */

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }
    @Override
    public void onStart() {
        super.onStart();
        mapView.onStart();
    }
    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }
    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();

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

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();

    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
        if (locationEngineListener != null) {
            locationEngine.removeLocationEngineListener(locationEngineListener);
        }
        // Remove all navigation listeners
        navigation.removeAlertLevelChangeListener(this);
        navigation.removeNavigationEventListener(this);
        navigation.removeProgressChangeListener(this);
        navigation.removeOffRouteListener(this);

        // End the navigation session
        navigation.endNavigation();
    }
    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }
    private void toggleGps(boolean enableGps) {
        if (enableGps) {
            // Check if user has granted location permission
            permissionsManager = new PermissionsManager(this);
            if (!PermissionsManager.areLocationPermissionsGranted(getActivity())) {
                Log.v("GPS","Requesting permissions");
                permissionsManager.requestLocationPermissions(getActivity());
            } else {
                enableLocation(true);
            }
        } else {
            enableLocation(false);
        }
    }

    private void enableLocation(boolean enabled) {
        if (enabled) {
            // If we have the last location of the user, we can move the camera to that position.
            Location lastLocation = locationEngine.getLastLocation();
            if (lastLocation != null) {
                map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lastLocation), 16));
            }

            locationEngineListener = new LocationEngineListener() {
                @Override
                public void onConnected() {
                    // No action needed here.
                }

                @Override
                public void onLocationChanged(Location location) {
                    if (location != null) {
                        // Move the map camera to where the user location is and then remove the
                        // listener so the camera isn't constantly updating when the user location
                        // changes. When the user disables and then enables the location again, this
                        // listener is registered again and will adjust the camera once again.
                        map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 16));
                        locationEngine.removeLocationEngineListener(this);
                    }
                }
            };
            locationEngine.addLocationEngineListener(locationEngineListener);
            floatingActionButton.setImageResource(R.drawable.ic_location_disabled_24dp);
        } else {
            floatingActionButton.setImageResource(R.drawable.ic_my_location_24dp);
        }
        // Enable or disable the location layer on the map
        map.setMyLocationEnabled(enabled);
    }

    @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(getActivity(), "This app needs location permissions in order to show its functionality.",
                Toast.LENGTH_LONG).show();
    }

    @Override
    public void onPermissionResult(boolean granted) {
        if (granted) {
            enableLocation(true);
        } else {
            Toast.makeText(getActivity(), "You didn't grant location permissions.",
                    Toast.LENGTH_LONG).show();
            getActivity().finish();
        }
    }
    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}

Additional route calculation parameter

Hey,

is there a plan to add different route calculation parameters?
For example:

  • car

  • bicycle

  • pedestrian

  • fastes route

  • shortest route

  • language (for maneuver instructions)

Best regards,
Patrick

Options

Hello,
Is there a drop in controller that can has been implemented for android just like the one in the iOS repository here? https://github.com/mapbox/mapbox-navigation-ios

I would like to use map box and I just want to know if there is already one in the works before I start doing any heavy lifting.

Background Thread

The background handler thread can be removed and logic can be calculated directly in the NavigationService object. The NavigationService however, needs to be running on a separate thread to keep performance intact

cc: @zugaldia @danesfeder

Release v0.1

In order to be able to release the first version of the Mapbox Navigation SDK for Android as a standalone project, the following things need to happen:

cc: @cammace @danesfeder

Once off-route, we measure from the same snapped position causing an endless loop.

05-19 17:51:08.972 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 17.0
05-19 17:51:08.972 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 2.6673089788901962
05-19 17:51:09.912 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:51:09.912 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.120464490039302
05-19 17:51:11.899 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:51:11.899 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.1952861108700281
05-19 17:51:12.935 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:51:12.935 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.5276582018307443
05-19 17:51:14.946 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 16.0
05-19 17:51:14.947 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.2958761817742823
05-19 17:51:15.942 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 17.0
05-19 17:51:15.942 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.4639976027921042
05-19 17:51:17.951 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 17.0
05-19 17:51:17.951 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.234808416569313
05-19 17:51:18.921 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 17.0
05-19 17:51:18.921 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.6589061440476407
05-19 17:51:19.967 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 17.0
05-19 17:51:19.968 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.869655409333431
05-19 17:51:21.933 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 17.0
05-19 17:51:21.933 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 2.536247410736636
05-19 17:51:22.937 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 18.0
05-19 17:51:22.937 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.8308895608109472
05-19 17:51:24.951 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 19.0
05-19 17:51:24.952 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 0.0947097615169983
05-19 17:51:25.928 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 19.0
05-19 17:51:25.929 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.9738245111823365
05-19 17:51:27.919 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 16.0
05-19 17:51:27.920 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 20.92935250395903
05-19 17:51:28.953 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 16.0
05-19 17:51:28.953 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 3.5069682564933435
05-19 17:51:29.947 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 17.0
05-19 17:51:29.947 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 0.6968343303512787
05-19 17:51:31.956 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 16.0
05-19 17:51:31.957 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.2075432097227468
05-19 17:51:32.939 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 17.0
05-19 17:51:32.939 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 2.25326750154043
05-19 17:51:33.954 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 16.0
05-19 17:51:33.954 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 2.312485607613608
05-19 17:51:35.916 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:51:35.917 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.987098264973477
05-19 17:51:36.931 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 16.0
05-19 17:51:36.931 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 2.500876545599369
05-19 17:51:38.958 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:51:38.959 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.5835084095561727
05-19 17:51:39.955 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:51:39.956 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 0.8516772133033655
05-19 17:51:41.913 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:51:41.913 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 0.2026728075728913
05-19 17:51:44.943 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 13.0
05-19 17:51:44.943 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.0697906741340788
05-19 17:51:51.925 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:51:51.926 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 2.1633341236735872
05-19 17:51:53.923 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:51:53.923 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.2343921140133707
05-19 17:51:54.936 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:51:54.936 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 2.027983113197057
05-19 17:51:56.927 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:51:56.927 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 1.131519942450051
05-19 17:51:57.950 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:51:57.951 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 2.4655416279968385
05-19 17:51:59.933 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:51:59.934 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 20.048194106846864
05-19 17:52:00.940 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:52:00.941 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 28.4654527885577
05-19 17:52:01.928 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:52:01.929 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 35.45609534346335
05-19 17:52:02.929 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:52:02.929 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 41.77779286188603
05-19 17:52:04.900 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:52:04.900 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 53.97655449822273
05-19 17:52:05.915 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:52:05.916 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 58.65807539566811
05-19 17:52:06.907 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:52:06.907 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 64.57468121131893
05-19 17:52:07.911 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:52:07.911 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 71.80579155317197
05-19 17:52:08.913 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:52:08.913 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 80.0539120875666
05-19 17:52:09.912 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 14.0
05-19 17:52:09.913 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 88.99351645981768
05-19 17:52:10.923 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:52:10.923 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 97.53616789572308
05-19 17:52:12.933 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:52:12.933 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 115.82413171385913
05-19 17:52:13.929 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 15.0
05-19 17:52:13.929 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 127.29867994638687
05-19 17:52:15.905 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: radius: 16.0
05-19 17:52:15.906 5159-5159/com.mapbox.services.android.navigation.testapp I/System.out: true position: 148.64584220141234

Crash if smartphone localization is disabled

Hey,

I don't know if this is a navigation issue or a general mapbox-java issue.

My setup on a Google Nexus 6 with Android 6.0 is:

compile ('com.mapbox.mapboxsdk:mapbox-android-sdk:5.1.0-beta.2@aar') {
transitive = true
exclude module: 'lost'
exclude module: 'mapbox-java-geojson'
exclude module: 'mapbox-android-telemetry'
}
compile('com.mapbox.mapboxsdk:mapbox-android-services:2.1.0@aar') {
transitive = true
}
compile 'com.mapbox.mapboxsdk:mapbox-android-navigation:0.2.0'

If the user has allowed the smartphone to locate himself, everything work fine (app permissions for localisation are granted).

But if he disables the localisation, and I run the following code, the app crashes after I activate the location engine:

LocationEngine locationEngine = LocationSource.getLocationEngine(context);
locationEngine.activate();

05-24 15:35:21.661 15330-15330/? W/System.err: java.lang.AbstractMethodError: abstract method "void com.mapzen.android.lost.api.LocationListener.onProviderDisabled(java.lang.String)"
05-24 15:35:21.662 15330-15330/? W/System.err:     at com.mapzen.android.lost.internal.LostClientManager.reportProviderDisabled(LostClientManager.java:205)
05-24 15:35:21.662 15330-15330/? W/System.err:     at com.mapzen.android.lost.internal.FusedLocationProviderServiceImpl.reportProviderDisabled(FusedLocationProviderServiceImpl.java:145)
05-24 15:35:21.662 15330-15330/? W/System.err:     at com.mapzen.android.lost.internal.FusionEngine.onProviderDisabled(FusionEngine.java:214)
05-24 15:35:21.662 15330-15330/? W/System.err:     at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:310)
05-24 15:35:21.662 15330-15330/? W/System.err:     at android.location.LocationManager$ListenerTransport.-wrap0(LocationManager.java)
05-24 15:35:21.662 15330-15330/? W/System.err:     at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:242)
05-24 15:35:21.662 15330-15330/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
05-24 15:35:21.662 15330-15330/? W/System.err:     at android.os.Looper.loop(Looper.java:154)
05-24 15:35:21.662 15330-15330/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6077)
05-24 15:35:21.662 15330-15330/? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
05-24 15:35:21.662 15330-15330/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
05-24 15:35:21.662 15330-15330/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Best regards,
Patrick

Release Mapbox Navigation 0.3.1

This ticket tracks the release of Mapbox Android Navigation SDK v0.3.1. This release brings many improvements to the RouteProgress objects and significantly increases performance.

Highlights

  • Use AutoValue inside RouteProgress objects.
  • Directly use direction distance measurements instead of calculating them.

Release checklist @cammace @zugaldia

  • Finish merging PRs that exist on the 0.3.1 milestone
  • Run through testapp/demo app and test all activities
  • Change version name to 0.3.1 in gradle.properties
  • Publish 0.3.1 artifact to Maven Central
  • Change version name back to 0.4.0-SNAPSHOT
  • Update CHANGELOG.md
  • Tag v0.3.1 in GitHub

Post-release @langsmith

  • Update README.md
  • Generate Javadoc
  • Update /android-docs
  • Update Android demo app
    /cc: @mapbox/navigation

Add localizations

The following files contain translatable messages that should be localized at Transifex:

https://github.com/mapbox/mapbox-navigation-android/blob/master/navigation/app/src/main/res/values/strings.xml
https://github.com/mapbox/mapbox-navigation-android/blob/master/navigation/libandroid-navigation/src/main/res/values/strings.xml

We’ll want to set up a separate project under the Mapbox organization. Though Transifex mostly supports drawing in resources from multiple repositories, the tx client works best when a Transifex project is hooked up to a single repository. For convenience, we can share the same translation teams as the iOS navigation SDK and the map SDKs.

make prepare-osrm already pulls in translations from the OSRM Text Instructions project on Transifex, so guidance instructions should already be localized as long as we’re using TextInstructions wherever we need to display an instruction.

/cc @cammace @langsmith @tobrun

Add annotations to RouteProgress object

Now that RouteProgress has moved to an Android project, we can take advantage of the annotations to further ensure parameters, methods, classes, etc. are correct.

Troubles with Routes on Cycling profile

Hello MapBox !

Platform: Android
Mapbox SDK version: 4.2.2

I need to find a route for cycling users so my app is on Cycling profile, but this profile allow parking and private roads.

For now I use Driving profile to avoid these problems, but one way roads and cycling ways are not allowed in this mode.

Do someone have to solve this problem or someones know how to deal with it ?

image

Arrival Point before parking's exit :

image

Arrival Point after parking's exit :
image

App crashes on end of navigation if speed is higher than step length

Platform: Android 7.1.2
SDK version: Latest SNAPSHOT

Steps to trigger behavior

  1. Open the RerouteActivity.java
  2. Set speed of the MockEngine to 60 on this line
    (2.1. Set destination coordinate to be sure you'll experience the bug: -87.6910, 41.8542)
  3. Reach the end of the path and observe crash

I thought this was specific to the mock engine but actually if I'm right this could happen in real life if car is going fast and GPS signal is slow I guess.

Expected behavior

Navigation should end nicely

Actual behavior

App crash with an NPE

Navigation UI like in iOS

Is there, and/or will there be a separate Activity with a mapview with some style, that would take 'Route' object and show built in navigation with distance,estimated time, next maneuver etc. UI. iOS has NavigationViewController (MBNavigationViewController) that can be easily presented.

Release Mapbox Navigation 0.3.0

This ticket tracks the release of Mapbox Android Navigation SDK v0.3.0. The leading feature in this release are listed below:

Highlights

Release checklist @cammace @zugaldia

  • Finish merging PRs that exist on the 0.3.0 milestone
  • Run through testapp/demo app and test all activities
  • Change version name to 0.3.0 in gradle.properties
  • Publish 0.3.0 artifact to Maven Central
  • Change version name back to 0.4.0-SNAPSHOT
  • Update CHANGELOG.md
  • Tag v0.3.0 in GitHub

Post-release @langsmith

/cc: @mapbox/navigation

Restore locationEngine state to what user had before nav session

When a navigation session begins, we take the instance of the locationEngine passed in and force the updating to happen more frequently. After a nav session, the locationEngine is automatically set to a lower battery consumption settings but this isn't necessarily what the developer had before they started navigating. Perhaps this is an API we should include in locationEngine, thoughts @zugaldia?

Kalman Location Engine

In order to better control when location updates occur, a Kalman filter can be used to force location updates between real GPS updates.

cc: @zugaldia

Remove RouteUtils

RouteUtils is no longer needed and can be removed in favor of placing the logic directly where it is needed.

Reroute refactor

The current implementation can be significantly improved; we offer the option to consider the user's bearing when first creating a route but not when rerouting. Additionally, the rerouting should find the user's future position x time in the future (using dead reckoning). Potentially lower the off-route threshold when already detected off-route at first.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.