-
Notifications
You must be signed in to change notification settings - Fork 319
Add some flexibility to NavigationLocationProvider #6420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| package com.mapbox.navigation.core.trip.session; | ||
|
|
||
| import android.location.Location; | ||
|
|
||
| import androidx.annotation.NonNull; | ||
| import androidx.annotation.UiThread; | ||
|
|
||
| /** | ||
| * An interface which enables listening to location updates | ||
| * | ||
| * @see LocationMatcherResult | ||
| */ | ||
| @UiThread | ||
| public interface LocationObserver { | ||
|
|
||
| /** | ||
| * Invoked as soon as a new [Location] has been received. | ||
| * | ||
| * @param rawLocation un-snapped update | ||
| */ | ||
| default void onNewRawLocation(@NonNull Location rawLocation) { | ||
| // Override to capture | ||
| } | ||
|
|
||
| /** | ||
| * Provides the best possible location update, snapped to the route or map-matched to the road if possible. | ||
| * | ||
| * @param locationMatcherResult details about the status of the enhanced location. | ||
| */ | ||
| default void onNewLocationMatcherResult(@NonNull LocationMatcherResult locationMatcherResult) { | ||
| // Override to capture | ||
| } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,13 +3,17 @@ package com.mapbox.navigation.ui.maps.location | |
| import android.animation.ValueAnimator | ||
| import android.annotation.SuppressLint | ||
| import android.location.Location | ||
| import androidx.annotation.CallSuper | ||
| import com.mapbox.geojson.Point | ||
| import com.mapbox.maps.plugin.locationcomponent.LocationComponentConstants | ||
| import com.mapbox.maps.plugin.locationcomponent.LocationComponentPlugin | ||
| import com.mapbox.maps.plugin.locationcomponent.LocationConsumer | ||
| import com.mapbox.maps.plugin.locationcomponent.LocationProvider | ||
| import com.mapbox.maps.plugin.locationcomponent.OnIndicatorPositionChangedListener | ||
| import com.mapbox.navigation.core.MapboxNavigation | ||
| import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp | ||
| import com.mapbox.navigation.core.lifecycle.MapboxNavigationObserver | ||
| import com.mapbox.navigation.core.trip.session.LocationMatcherResult | ||
| import com.mapbox.navigation.core.trip.session.LocationObserver | ||
| import com.mapbox.navigation.ui.maps.internal.location.PuckAnimationEvaluator | ||
| import com.mapbox.navigation.utils.internal.ifNonNull | ||
|
|
@@ -53,7 +57,10 @@ import java.util.concurrent.CopyOnWriteArraySet | |
| * } | ||
| * ``` | ||
| */ | ||
| class NavigationLocationProvider : LocationProvider { | ||
| open class NavigationLocationProvider : | ||
| LocationProvider, | ||
| LocationObserver, | ||
| MapboxNavigationObserver { | ||
|
|
||
| private val locationConsumers = CopyOnWriteArraySet<LocationConsumer>() | ||
|
|
||
|
|
@@ -73,6 +80,17 @@ class NavigationLocationProvider : LocationProvider { | |
| var lastKeyPoints: List<Location> = emptyList() | ||
| private set | ||
|
|
||
| /** | ||
| * Automatically updated when this class is registered to [MapboxNavigationApp] | ||
| */ | ||
| @CallSuper | ||
| override fun onNewLocationMatcherResult(locationMatcherResult: LocationMatcherResult) { | ||
| changePosition( | ||
| locationMatcherResult.enhancedLocation, | ||
| locationMatcherResult.keyPoints, | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Register the location consumer to the Location Provider. | ||
| * | ||
|
|
@@ -81,7 +99,7 @@ class NavigationLocationProvider : LocationProvider { | |
| * @param locationConsumer | ||
| */ | ||
| @SuppressLint("MissingPermission") | ||
| override fun registerLocationConsumer(locationConsumer: LocationConsumer) { | ||
| final override fun registerLocationConsumer(locationConsumer: LocationConsumer) { | ||
| if (locationConsumers.add(locationConsumer)) { | ||
| ifNonNull(lastLocation, lastKeyPoints) { location, keyPoints -> | ||
| locationConsumer.notifyLocationUpdates( | ||
|
|
@@ -103,7 +121,7 @@ class NavigationLocationProvider : LocationProvider { | |
| * | ||
| * @param locationConsumer | ||
| */ | ||
| override fun unRegisterLocationConsumer(locationConsumer: LocationConsumer) { | ||
| final override fun unRegisterLocationConsumer(locationConsumer: LocationConsumer) { | ||
| locationConsumers.remove(locationConsumer) | ||
| } | ||
|
|
||
|
|
@@ -122,6 +140,7 @@ class NavigationLocationProvider : LocationProvider { | |
| * @see LocationObserver | ||
| * @see MapboxNavigation.registerLocationObserver | ||
| */ | ||
| @CallSuper | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about making this final.. Leaving it open provides more flexibility but it's not covering a real use case. Once it is open it cannot be closed, so am debating making it |
||
| fun changePosition( | ||
| location: Location, | ||
| keyPoints: List<Location> = emptyList(), | ||
|
|
@@ -140,6 +159,27 @@ class NavigationLocationProvider : LocationProvider { | |
| lastKeyPoints = keyPoints | ||
| } | ||
|
|
||
| /** | ||
| * Use [getRegisteredInstance] to share a single instance of the [NavigationLocationProvider]. | ||
| * | ||
| * @see [MapboxNavigationApp] | ||
| */ | ||
| @CallSuper | ||
| override fun onAttached(mapboxNavigation: MapboxNavigation) { | ||
| mapboxNavigation.registerLocationObserver(this) | ||
| } | ||
|
|
||
| /** | ||
| * Disabled automatically with the [MapboxNavigationApp]. You can manually disable with | ||
| * [MapboxNavigationApp.unregisterObserver]. | ||
| * | ||
| * @see [MapboxNavigationApp] | ||
| */ | ||
| @CallSuper | ||
| override fun onDetached(mapboxNavigation: MapboxNavigation) { | ||
| mapboxNavigation.unregisterLocationObserver(this) | ||
| } | ||
|
|
||
| private fun LocationConsumer.notifyLocationUpdates( | ||
| location: Location, | ||
| keyPoints: List<Location>, | ||
|
|
@@ -176,4 +216,14 @@ class NavigationLocationProvider : LocationProvider { | |
| clientOptions?.also { apply(it) } | ||
| } | ||
| } | ||
|
|
||
| companion object { | ||
| /** | ||
| * Get the registered instance or create one and register it to [MapboxNavigationApp]. | ||
| */ | ||
| @JvmStatic | ||
| fun getRegisteredInstance(): NavigationLocationProvider = MapboxNavigationApp | ||
| .getObservers(NavigationLocationProvider::class).firstOrNull() | ||
| ?: NavigationLocationProvider().also { MapboxNavigationApp.registerObserver(it) } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By implementing the interface directly, we're exposing it as part of the
NavigationLocationProvidersurface, while it's not needed. TheLocationObserverinstance could be a member of theNavigationLocationProviderinstead.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes it so you can capture
onNewLocationMatcherResultevents downstream.LocationConsumerdoes not give access toLocationMatcherResult. If it is internal, we need a another way to surface the map matched locations. Do you think there should be another registry ofLocationObserverobservers?