fix: Custom navigation events
This commit is contained in:
parent
65cdeb17d0
commit
ffbd7c46b8
5 changed files with 97 additions and 27 deletions
|
@ -4,6 +4,7 @@ import android.content.res.Configuration
|
|||
import android.content.res.Resources
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.geojson.Point
|
||||
import com.mapbox.maps.ImageHolder
|
||||
import com.mapbox.maps.plugin.LocationPuck2D
|
||||
import com.mapbox.maps.plugin.animation.camera
|
||||
|
@ -48,6 +49,8 @@ class MapControl(
|
|||
*/
|
||||
val navigationLocationProvider = NavigationLocationProvider()
|
||||
|
||||
val navigationStatusControl = NavigationStatusControl()
|
||||
|
||||
val replay = ReplayResources(this)
|
||||
|
||||
// Observers
|
||||
|
@ -59,7 +62,6 @@ class MapControl(
|
|||
private lateinit var routeProgressObserver: RouteProgressObserver
|
||||
private lateinit var voiceInstructionsObserver: VoiceInstructionsObserver
|
||||
private val searchControl = SearchControl(this, ui)
|
||||
private val navigationStateListener = NavigationStateListener()
|
||||
|
||||
fun init() {
|
||||
viewportDataSource = MapboxNavigationViewportDataSource(ui.mapView.mapboxMap)
|
||||
|
@ -105,6 +107,10 @@ class MapControl(
|
|||
voiceInstructionsObserver = voiceControl.voiceInstructionsObserver
|
||||
}
|
||||
|
||||
fun routeToPoint(point: Point) {
|
||||
routeControl.findRoute(point)
|
||||
}
|
||||
|
||||
fun initNavigation() {
|
||||
MapboxNavigationApp.setup(
|
||||
NavigationOptions.Builder(context)
|
||||
|
@ -135,7 +141,8 @@ class MapControl(
|
|||
mapboxNavigation.registerLocationObserver(locationObserver)
|
||||
mapboxNavigation.registerRouteProgressObserver(routeProgressObserver)
|
||||
mapboxNavigation.registerVoiceInstructionsObserver(voiceInstructionsObserver)
|
||||
mapboxNavigation.registerNavigationSessionStateObserver(navigationStateListener)
|
||||
|
||||
navigationStatusControl.registerObserver(searchControl)
|
||||
|
||||
replay.onAttached(mapboxNavigation)
|
||||
}
|
||||
|
@ -145,7 +152,8 @@ class MapControl(
|
|||
mapboxNavigation.unregisterLocationObserver(locationObserver)
|
||||
mapboxNavigation.unregisterRouteProgressObserver(routeProgressObserver)
|
||||
mapboxNavigation.unregisterVoiceInstructionsObserver(voiceInstructionsObserver)
|
||||
mapboxNavigation.unregisterNavigationSessionStateObserver(navigationStateListener)
|
||||
|
||||
navigationStatusControl.unregisterObserver(searchControl)
|
||||
|
||||
replay.onDetached(mapboxNavigation)
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package eu.ztsh.garmin.mapbox
|
||||
|
||||
import com.mapbox.navigation.core.trip.session.NavigationSessionState
|
||||
import com.mapbox.navigation.core.trip.session.NavigationSessionStateObserver
|
||||
|
||||
class NavigationStateListener: NavigationSessionStateObserver {
|
||||
|
||||
override fun onNavigationSessionStateChanged(navigationSession: NavigationSessionState) {
|
||||
// TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}
|
49
app/src/main/java/eu/ztsh/garmin/mapbox/NavigationStatus.kt
Normal file
49
app/src/main/java/eu/ztsh/garmin/mapbox/NavigationStatus.kt
Normal file
|
@ -0,0 +1,49 @@
|
|||
package eu.ztsh.garmin.mapbox
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.util.concurrent.CopyOnWriteArraySet
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
class NavigationStatusControl {
|
||||
|
||||
private val stateObservers = CopyOnWriteArraySet<NavigationStatusObserver>()
|
||||
private val current = AtomicReference(NavigationStatus.IDLE)
|
||||
|
||||
fun registerObserver(observer: NavigationStatusObserver) {
|
||||
stateObservers.add(observer)
|
||||
observer.onNavigationStatusChanged(current.get())
|
||||
}
|
||||
|
||||
fun unregisterObserver(observer: NavigationStatusObserver) {
|
||||
stateObservers.remove(observer)
|
||||
}
|
||||
|
||||
fun sendEvent(status: NavigationStatus) {
|
||||
current.set(status)
|
||||
stateObservers.forEach {
|
||||
it.onNavigationStatusChanged(status)
|
||||
}
|
||||
if (status == NavigationStatus.FINISHED || status == NavigationStatus.CANCELED) {
|
||||
// TODO: lifecyclescope?
|
||||
runBlocking {
|
||||
delay(1000)
|
||||
sendEvent(NavigationStatus.IDLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum class NavigationStatus {
|
||||
IDLE,
|
||||
STARTED,
|
||||
FINISHED,
|
||||
CANCELED
|
||||
}
|
||||
|
||||
fun interface NavigationStatusObserver {
|
||||
|
||||
fun onNavigationStatusChanged(navigationStatus: NavigationStatus)
|
||||
|
||||
}
|
|
@ -3,10 +3,10 @@ package eu.ztsh.garmin.mapbox
|
|||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.mapbox.api.directions.v5.models.Bearing
|
||||
import com.mapbox.api.directions.v5.models.RouteOptions
|
||||
import com.mapbox.geojson.Point
|
||||
import com.mapbox.maps.plugin.gestures.gestures
|
||||
import com.mapbox.navigation.base.TimeFormat
|
||||
import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
|
||||
import com.mapbox.navigation.base.extensions.applyLanguageAndVoiceUnitOptions
|
||||
|
@ -37,6 +37,10 @@ import com.mapbox.navigation.ui.maps.route.line.model.MapboxRouteLineApiOptions
|
|||
import com.mapbox.navigation.ui.maps.route.line.model.MapboxRouteLineViewOptions
|
||||
import eu.ztsh.garmin.Garmin
|
||||
import eu.ztsh.garmin.UI
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class RouteControl(private val mapControl: MapControl, ui: UI, private val context: Context) {
|
||||
|
||||
|
@ -115,11 +119,6 @@ class RouteControl(private val mapControl: MapControl, ui: UI, private val conte
|
|||
// Ensure that the route line related layers are present before the route arrow
|
||||
routeLineView.initializeLayers(it)
|
||||
|
||||
// add long click listener that search for a route to the clicked destination
|
||||
// ui.mapView.gestures.addOnMapLongClickListener { point ->
|
||||
// findRoute(point)
|
||||
// true
|
||||
// }
|
||||
}
|
||||
|
||||
// initialize view interactions
|
||||
|
@ -219,7 +218,7 @@ class RouteControl(private val mapControl: MapControl, ui: UI, private val conte
|
|||
}
|
||||
}
|
||||
|
||||
private fun findRoute(destination: Point) {
|
||||
fun findRoute(destination: Point) {
|
||||
val originLocation = mapControl.navigationLocationProvider.lastLocation ?: return
|
||||
val originPoint = Point.fromLngLat(originLocation.longitude, originLocation.latitude)
|
||||
|
||||
|
@ -284,6 +283,15 @@ class RouteControl(private val mapControl: MapControl, ui: UI, private val conte
|
|||
|
||||
// start simulation
|
||||
mapControl.replay.startSimulation(routes.first().directionsRoute)
|
||||
|
||||
mapControl.context.apply {
|
||||
lifecycleScope.launch {
|
||||
async {
|
||||
delay(5000)
|
||||
mapControl.navigationCamera.requestNavigationCameraToFollowing()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearRouteAndStopNavigation() {
|
||||
|
@ -298,6 +306,9 @@ class RouteControl(private val mapControl: MapControl, ui: UI, private val conte
|
|||
mapControl.ui.maneuverView.visibility = View.INVISIBLE
|
||||
mapControl.ui.routeOverview.visibility = View.INVISIBLE
|
||||
mapControl.ui.tripProgressCard.visibility = View.INVISIBLE
|
||||
|
||||
// post custom event
|
||||
mapControl.navigationStatusControl.sendEvent(NavigationStatus.CANCELED)
|
||||
}
|
||||
|
||||
fun cancel() {
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.mapbox.maps.plugin.annotation.annotations
|
|||
import com.mapbox.maps.plugin.annotation.generated.CircleAnnotationOptions
|
||||
import com.mapbox.maps.plugin.annotation.generated.createCircleAnnotationManager
|
||||
import com.mapbox.maps.plugin.gestures.gestures
|
||||
import com.mapbox.navigation.core.trip.session.NavigationSessionState
|
||||
import com.mapbox.search.autocomplete.PlaceAutocomplete
|
||||
import com.mapbox.search.autocomplete.PlaceAutocompleteOptions
|
||||
import com.mapbox.search.autocomplete.PlaceAutocompleteSuggestion
|
||||
|
@ -33,7 +34,7 @@ import eu.ztsh.garmin.R
|
|||
import eu.ztsh.garmin.UI
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class SearchControl(val mapControl: MapControl, val ui: UI) {
|
||||
class SearchControl(val mapControl: MapControl, val ui: UI): NavigationStatusObserver {
|
||||
|
||||
// Set your Access Token here if it's not already set in some other way
|
||||
// MapboxOptions.accessToken = "<my-access-token>"
|
||||
|
@ -86,13 +87,12 @@ class SearchControl(val mapControl: MapControl, val ui: UI) {
|
|||
}
|
||||
|
||||
addOnNavigateClickListener { searchPlace ->
|
||||
showToast(R.string.not_implemented_yet)
|
||||
// startActivity(geoIntent(searchPlace.coordinate))
|
||||
mapControl.routeToPoint(searchPlace.coordinate)
|
||||
mapControl.navigationStatusControl.sendEvent(NavigationStatus.STARTED)
|
||||
}
|
||||
|
||||
addOnShareClickListener { searchPlace ->
|
||||
addOnShareClickListener { _ ->
|
||||
showToast(R.string.not_implemented_yet)
|
||||
// startActivity(shareIntent(searchPlace))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,6 +182,20 @@ class SearchControl(val mapControl: MapControl, val ui: UI) {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onNavigationStatusChanged(navigationStatus: NavigationStatus) {
|
||||
when (navigationStatus) {
|
||||
NavigationStatus.IDLE -> {
|
||||
ui.queryEditText.visibility = View.VISIBLE
|
||||
}
|
||||
NavigationStatus.STARTED -> {
|
||||
mapControl.navigationCamera.requestNavigationCameraToOverview()
|
||||
closePlaceCard()
|
||||
ui.queryEditText.visibility = View.GONE
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showToast(@StringRes resId: Int): Unit =
|
||||
Toast.makeText(mapControl.context, resId, Toast.LENGTH_LONG).show()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue