Mapbox-navigation-android: Lag on Android 9 Before Instructions Are Heard

Created on 22 Feb 2019  路  18Comments  路  Source: mapbox/mapbox-navigation-android

There is a lag between when I start the NavigationView and when I hear the first instruction (Hopefully, this isn't a duplicate of #1762...I wasn't sure). I often have to drive a half mile before any instructions are spoken. This only seems to happen on Android 9 and only some of the time.

I was told to fix this in an earlier version of the SDK by adding a FusedLocationEngine to the NavigationViewOptions, but was recently told that after 0.27.0 or 0.28.0, the LocationEngine was baked in to the Android Navigation and I didn't need to attach it to the NavigationViewOptions anymore.

Here is my code:

NavigationViewOptions.Builder navigationViewOptions = NavigationViewOptions.builder();
navigationViewOptions.directionsRoute(currentRoute);
navigationViewOptions.navigationListener(NavigationActivity.this);
navigationViewOptions.milestoneEventListener(NavigationActivity.this);
navigationViewOptions.speechAnnouncementListener(NavigationActivity.this);
navigationViewOptions.bannerInstructionsListener(NavigationActivity.this);
navigationViewOptions.routeListener(NavigationActivity.this);
navigationViewOptions.shouldSimulateRoute(false);

                        navigationView.startNavigation(navigationViewOptions.build());

Android API:
Android 9
Test Device: Google Pixel

Mapbox Navigation SDK version:
0.30.0

Steps to trigger behavior

  1. Start navigation in a parking lot.
  2. Start driving.
  3. Instructions will start at some point, but usually around the half mile mark.

Expected behavior

The instructions should start as soon as I'm on the main route or approaching the main route.

Actual behavior

The instructions often start after I've driven a 1/2 mile or so. This only happens on Android 9 and doesn't happen all of the time.

Most helpful comment

So, I'm still testing, but it seems to reduce the lag quite a bit.

The other bonus is that it seems to allow me to navigate with the device's Location Method set to High Accuracy OR Phone Only, which is a bonus. The other way with the FusedLocationEngine only seemed to work wit the device set to High Accuracy.

Again, I'll update this once I know more. I want to make sure I test enough to verify what I've initially seen.

All 18 comments

Hey @billyking991 馃憢 thanks for the feedback here. To clarify, you're saying the instructions are delayed but are you seeing a delay in movement of the user location icon on the map itself as well? I ask because the voice instructions are triggered by the current position of the device, so the two behaviors should coincide.

This is correct. The delay in movement of the user location doesn't happen all of the time, but it seems to be somewhere between 15% - 25% on Android 9. I will continue testing too see if I can come up with a pattern. I had previous added the locationEngine, as you had directed me to do in the past, but it didn't seem to help. Here is how I created the LocationEngine in the previous attempt:

@SuppressWarnings( {"MissingPermission"})
private void initializeLocationEngine() {
locationEngine = LocationEngineProvider.getBestLocationEngine(getApplicationContext());
LocationEngineRequest request = buildEngineRequest();
locationEngine.requestLocationUpdates(request, callback, null);
locationEngine.getLastLocation(callback);
}

@NonNull
private LocationEngineRequest buildEngineRequest() {
    return new LocationEngineRequest.Builder(UPDATE_INTERVAL_IN_MILLISECONDS)
            .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
            .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS)
            .build();
}

private static class NavigationLauncherLocationCallback implements LocationEngineCallback<LocationEngineResult> {

    private final WeakReference<NavigationActivity> activityWeakReference;

    NavigationLauncherLocationCallback(NavigationActivity activity) {
        this.activityWeakReference = new WeakReference<>(activity);
    }

    @Override
    public void onSuccess(LocationEngineResult result) {
        NavigationActivity activity = activityWeakReference.get();
        if (activity != null) {
            Location location = result.getLastLocation();
            if (location == null) {
                return;
            }
            activity.updateCurrentLocation(Point.fromLngLat(location.getLongitude(), location.getLatitude()));
            //activity.onLocationFound(location);
        }
    }

    @Override
    public void onFailure(@NonNull Exception exception) {
        Timber.e(exception);
    }
}

@billyking991 I apologize for the back-and-forth regarding the LocationEngine setup. But can you possibly re-test with FusedLocationEngine? We've seen some behavior with LocationEngineProvider.getBestLocationEngine(getApplicationContext()); that sound similar to what you're describing. In which case, this is an upstream issue with our location library. Thank you for your patience and great feedback.

I would use the FusedLocationEngine, but it looks like the LocationEngineListener was removed from the latest few versions of the Mapbox Navigation SDK. That was why I removed it during the upgrade to the latest SDK version. Do you know of a new implementation of FusedLocationEngine that works with the last few Mapbox Nav SDKs?

Previously, I was using your FusedLocationEngine and ForwardingLocationCallback files that you had previously asked me to try.

@billyking991 here are some updated snippets adhering to the new LocationEngine APIs:

ForwardingLocationCallback.txt
FusedLocationEngine.txt

Thank you so much for the quick response.

OK, I've updated the files. I'm assuming that the new FusedLocationEngine handles everything automatically, correct? Before I was handling the requestLocationUpdates in OnResume, removeLocationUpdates in OnPause, and initializing the locationEngine by calling:

private void initializeLocationEngine() {
locationEngine = new FusedLocationEngine(getApplicationContext());
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.addLocationEngineListener(this);
locationEngine.setInterval(ONE_SECOND_INTERVAL);
locationEngine.setFastestInterval(500);
locationEngine.activate();
}

Now it seems like I can attach the locationEngine to the NavigationView after calling:

private void initializeLocationEngine() {
locationEngine = new FusedLocationEngine(getApplicationContext());
}

Correct? I'm going out to test. Thank you for all of your help!

@billyking991 using the NavigationView, you'd only need to:

Location locationEngine = new FusedLocationEngine(getApplicationContext());
// TODO pass to NavigationViewOptions

The NavigationView will handle activation with a LocationEngineRequest and all Android lifecycle "under-the-hood".

Oh yeah, that's much better. No lag anymore, just like it was before. Thank you so much for the quick help!! I'll continue testing for the next day or so, but I think my lag issue is solved. Closing...

@billyking991 great to hear, thank you!

hey @billyking991 can you try to setDisplacement(0.0f); in the LocationEngineRequest explicitly and retest? i'd hugely appreciate if you could update this thread with your findings. thanks!

This is correct. The delay in movement of the user location doesn't happen all of the time, but it seems to be somewhere between 15% - 25% on Android 9. I will continue testing too see if I can come up with a pattern. I had previous added the locationEngine, as you had directed me to do in the past, but it didn't seem to help. Here is how I created the LocationEngine in the previous attempt:

@SuppressWarnings( {"MissingPermission"})
private void initializeLocationEngine() {
locationEngine = LocationEngineProvider.getBestLocationEngine(getApplicationContext());
LocationEngineRequest request = buildEngineRequest();
locationEngine.requestLocationUpdates(request, callback, null);
locationEngine.getLastLocation(callback);
}

@NonNull
private LocationEngineRequest buildEngineRequest() {
    return new LocationEngineRequest.Builder(UPDATE_INTERVAL_IN_MILLISECONDS)
            .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
            .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS)
            .build();
}

private static class NavigationLauncherLocationCallback implements LocationEngineCallback<LocationEngineResult> {

    private final WeakReference<NavigationActivity> activityWeakReference;

    NavigationLauncherLocationCallback(NavigationActivity activity) {
        this.activityWeakReference = new WeakReference<>(activity);
    }

    @Override
    public void onSuccess(LocationEngineResult result) {
        NavigationActivity activity = activityWeakReference.get();
        if (activity != null) {
            Location location = result.getLastLocation();
            if (location == null) {
                return;
            }
            activity.updateCurrentLocation(Point.fromLngLat(location.getLongitude(), location.getLatitude()));
            //activity.onLocationFound(location);
        }
    }

    @Override
    public void onFailure(@NonNull Exception exception) {
        Timber.e(exception);
    }
}

@andrlee I will do this tomorrow and let you know what I find out. I apologize for the delay in getting back to you. I should have more info for you soon.

thanks for putting your time into it @billyking991

So, I'm still testing, but it seems to reduce the lag quite a bit.

The other bonus is that it seems to allow me to navigate with the device's Location Method set to High Accuracy OR Phone Only, which is a bonus. The other way with the FusedLocationEngine only seemed to work wit the device set to High Accuracy.

Again, I'll update this once I know more. I want to make sure I test enough to verify what I've initially seen.

I'm no longer seeing any lag and have been testing on two Android 9 devices. This is my full locationEngine initialization:

@SuppressWarnings( {"MissingPermission"})
private void initializeLocationEngine() {
locationEngine = LocationEngineProvider.getBestLocationEngine(getApplicationContext());
LocationEngineRequest request = buildEngineRequest();
locationEngine.requestLocationUpdates(request, callback, null);
locationEngine.getLastLocation(callback);
}

@NonNull
private LocationEngineRequest buildEngineRequest() {
    return new LocationEngineRequest.Builder(UPDATE_INTERVAL_IN_MILLISECONDS)
            .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
            .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS)
            .setDisplacement(0.0f)
            .build();
}

private static class NavigationLauncherLocationCallback implements LocationEngineCallback<LocationEngineResult> {

    private final WeakReference<NavigationActivity> activityWeakReference;

    NavigationLauncherLocationCallback(NavigationActivity activity) {
        this.activityWeakReference = new WeakReference<>(activity);
    }

    @Override
    public void onSuccess(LocationEngineResult result) {
        NavigationActivity activity = activityWeakReference.get();
        if (activity != null) {
            Location location = result.getLastLocation();
            if (location == null) {
                return;
            }
            activity.updateCurrentLocation(Point.fromLngLat(location.getLongitude(), location.getLatitude()));
            //activity.onLocationFound(location);
        }
    }

    @Override
    public void onFailure(@NonNull Exception exception) {
        Timber.e(exception);
    }
}

@billyking991 thanks for your feedback! we will push the patch release with the fix out early next week. stay tuned!

Sounds good. Thank you.

@billyking991 thanks for you help with testing these changes for us.

We made a new release of Mapbox-Android-Core 1.2.0 that integrates these changes. Tracking integration into Navigation SDK through this ticket: https://github.com/mapbox/mapbox-navigation-android/issues/1794

Hey Mapbox Team,

I have the same problem for a while now see here but cannot solve it with any of your proposed solutions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hmkum picture hmkum  路  4Comments

Guardiola31337 picture Guardiola31337  路  5Comments

thanhnguyenduc157 picture thanhnguyenduc157  路  5Comments

carstenhag picture carstenhag  路  8Comments

headbanggg picture headbanggg  路  5Comments