Service
This commit is contained in:
@@ -6,7 +6,6 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Color
|
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -29,11 +28,8 @@ import androidx.lifecycle.Observer
|
|||||||
import androidx.lifecycle.ViewModelStore
|
import androidx.lifecycle.ViewModelStore
|
||||||
import androidx.lifecycle.ViewModelStoreOwner
|
import androidx.lifecycle.ViewModelStoreOwner
|
||||||
import androidx.lifecycle.asLiveData
|
import androidx.lifecycle.asLiveData
|
||||||
import androidx.lifecycle.coroutineScope
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.kouros.navigation.car.navigation.NavigationService
|
import com.kouros.navigation.car.navigation.NavigationService
|
||||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
|
||||||
import com.kouros.navigation.car.navigation.Simulation
|
|
||||||
import com.kouros.navigation.car.screen.NavigationListener
|
import com.kouros.navigation.car.screen.NavigationListener
|
||||||
import com.kouros.navigation.car.screen.NavigationScreen
|
import com.kouros.navigation.car.screen.NavigationScreen
|
||||||
import com.kouros.navigation.car.screen.NavigationType
|
import com.kouros.navigation.car.screen.NavigationType
|
||||||
@@ -43,30 +39,22 @@ import com.kouros.navigation.car.screen.checkPermission
|
|||||||
import com.kouros.navigation.car.screen.observers.NavigationObserverCallback
|
import com.kouros.navigation.car.screen.observers.NavigationObserverCallback
|
||||||
import com.kouros.navigation.car.screen.observers.NavigationObserverManager
|
import com.kouros.navigation.car.screen.observers.NavigationObserverManager
|
||||||
import com.kouros.navigation.data.Constants.AUTOMOTIVE_CAR_SPEED_PERMISSION
|
import com.kouros.navigation.data.Constants.AUTOMOTIVE_CAR_SPEED_PERMISSION
|
||||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
|
||||||
import com.kouros.navigation.data.Constants.GMS_CAR_SPEED_PERMISSION
|
import com.kouros.navigation.data.Constants.GMS_CAR_SPEED_PERMISSION
|
||||||
import com.kouros.navigation.data.Constants.INSTRUCTION_DISTANCE
|
|
||||||
import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION
|
|
||||||
import com.kouros.navigation.data.Constants.MAXIMAL_SNAP_CORRECTION
|
|
||||||
import com.kouros.navigation.data.Constants.TAG
|
import com.kouros.navigation.data.Constants.TAG
|
||||||
import com.kouros.navigation.data.Constants.TRAFFIC_UPDATE
|
import com.kouros.navigation.data.Constants.TRAFFIC_UPDATE
|
||||||
import com.kouros.navigation.data.Constants.homeHohenwaldeck
|
import com.kouros.navigation.data.Constants.homeHohenwaldeck
|
||||||
import com.kouros.navigation.data.Place
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.data.RouteEngine
|
import com.kouros.navigation.data.RouteEngine
|
||||||
import com.kouros.navigation.data.SearchFilter
|
|
||||||
import com.kouros.navigation.data.ViewStyle
|
import com.kouros.navigation.data.ViewStyle
|
||||||
import com.kouros.navigation.data.osrm.OsrmRepository
|
import com.kouros.navigation.data.osrm.OsrmRepository
|
||||||
import com.kouros.navigation.data.overpass.Elements
|
import com.kouros.navigation.data.overpass.Elements
|
||||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||||
import com.kouros.navigation.data.valhalla.ValhallaRepository
|
import com.kouros.navigation.data.valhalla.ValhallaRepository
|
||||||
import com.kouros.navigation.model.NavigationViewModel
|
import com.kouros.navigation.model.NavigationViewModel
|
||||||
import com.kouros.navigation.model.RouteModel
|
|
||||||
import com.kouros.navigation.model.SettingsViewModel
|
import com.kouros.navigation.model.SettingsViewModel
|
||||||
import com.kouros.navigation.repository.SettingsRepository
|
import com.kouros.navigation.repository.SettingsRepository
|
||||||
import com.kouros.navigation.utils.GeoUtils
|
import com.kouros.navigation.utils.GeoUtils
|
||||||
import com.kouros.navigation.utils.GeoUtils.snapLocation
|
|
||||||
import com.kouros.navigation.utils.NavigationUtils.getViewModel
|
import com.kouros.navigation.utils.NavigationUtils.getViewModel
|
||||||
import com.kouros.navigation.utils.formattedDistance
|
|
||||||
import com.kouros.navigation.utils.getSettingsRepository
|
import com.kouros.navigation.utils.getSettingsRepository
|
||||||
import com.kouros.navigation.utils.getSettingsViewModel
|
import com.kouros.navigation.utils.getSettingsViewModel
|
||||||
import com.kouros.navigation.utils.location
|
import com.kouros.navigation.utils.location
|
||||||
@@ -115,8 +103,11 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
|
|
||||||
var speedCameras = listOf<Elements>()
|
var speedCameras = listOf<Elements>()
|
||||||
|
|
||||||
|
var recentPlaces = mutableListOf<Place>()
|
||||||
|
|
||||||
var lastRouteDate: LocalDateTime = LocalDateTime.now()
|
var lastRouteDate: LocalDateTime = LocalDateTime.now()
|
||||||
|
|
||||||
|
var destination = Place()
|
||||||
var notificationActive = false
|
var notificationActive = false
|
||||||
|
|
||||||
var navigationService: NavigationService? = null
|
var navigationService: NavigationService? = null
|
||||||
@@ -129,9 +120,9 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
hasArrived: Boolean,
|
hasArrived: Boolean,
|
||||||
destinations: MutableList<Destination>,
|
destinations: MutableList<Destination>,
|
||||||
steps: MutableList<Step>,
|
steps: MutableList<Step>,
|
||||||
destinationTravelEstimate: TravelEstimate?,
|
destinationTravelEstimate: TravelEstimate,
|
||||||
stepTravelEstimate: TravelEstimate?,
|
stepTravelEstimate: TravelEstimate,
|
||||||
stepRemainingDistance: Distance?,
|
stepRemainingDistance: Distance,
|
||||||
shouldShowNextStep: Boolean,
|
shouldShowNextStep: Boolean,
|
||||||
shouldShowLanes: Boolean,
|
shouldShowLanes: Boolean,
|
||||||
junctionImage: CarIcon?,
|
junctionImage: CarIcon?,
|
||||||
@@ -142,11 +133,11 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
isNavigating = isNavigating,
|
isNavigating = isNavigating,
|
||||||
isRerouting = isRerouting,
|
isRerouting = isRerouting,
|
||||||
hasArrived = hasArrived,
|
hasArrived = hasArrived,
|
||||||
destinationTravelEstimate = destinationTravelEstimate!!,
|
destinationTravelEstimate = destinationTravelEstimate,
|
||||||
stepTravelEstimate = stepTravelEstimate!!,
|
stepTravelEstimate = stepTravelEstimate,
|
||||||
destinations = destinations,
|
destinations = destinations,
|
||||||
steps = steps,
|
steps = steps,
|
||||||
stepRemainingDistance = stepRemainingDistance!!,
|
stepRemainingDistance = stepRemainingDistance,
|
||||||
shouldShowNextStep = shouldShowNextStep,
|
shouldShowNextStep = shouldShowNextStep,
|
||||||
shouldShowLanes = shouldShowLanes,
|
shouldShowLanes = shouldShowLanes,
|
||||||
junctionImage = junctionImage,
|
junctionImage = junctionImage,
|
||||||
@@ -162,12 +153,6 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
surfaceRenderer.carOrientation,
|
surfaceRenderer.carOrientation,
|
||||||
)
|
)
|
||||||
initialLocation = false
|
initialLocation = false
|
||||||
navigationViewModel.loadRoute(
|
|
||||||
carContext,
|
|
||||||
location,
|
|
||||||
listOf(homeHohenwaldeck),
|
|
||||||
surfaceRenderer.carOrientation
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
updateLocation(location)
|
updateLocation(location)
|
||||||
}
|
}
|
||||||
@@ -466,7 +451,7 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
private fun handleNavigateIntent(screenManager: ScreenManager) {
|
private fun handleNavigateIntent(screenManager: ScreenManager) {
|
||||||
screenManager.popToRoot()
|
screenManager.popToRoot()
|
||||||
screenManager.pushForResult(
|
screenManager.pushForResult(
|
||||||
SearchScreen(carContext, surfaceRenderer, navigationViewModel, mutableListOf())
|
SearchScreen(carContext, surfaceRenderer, navigationViewModel, recentPlaces)
|
||||||
) { result ->
|
) { result ->
|
||||||
// Handle search result if needed
|
// Handle search result if needed
|
||||||
}
|
}
|
||||||
@@ -500,7 +485,6 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
updateBearing(location)
|
updateBearing(location)
|
||||||
checkTraffic(LocalDateTime.now(ZoneOffset.UTC), location)
|
checkTraffic(LocalDateTime.now(ZoneOffset.UTC), location)
|
||||||
surfaceRenderer.updateLocation(location, "")
|
surfaceRenderer.updateLocation(location, "")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -512,14 +496,13 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start navigation process.
|
* Start navigation process.
|
||||||
* Called when user starts navigation
|
* Called when user starts navigation
|
||||||
*/
|
*/
|
||||||
override fun startNavigation() {
|
override fun startNavigation() {
|
||||||
Log.d(TAG, "startNavigation")
|
Log.d(TAG, "startNavigation")
|
||||||
navigationService!!.startNavigation(route)
|
navigationService!!.startNavigation(route, destination)
|
||||||
if (notificationActive)
|
if (notificationActive)
|
||||||
notificationManager.startNotificationService()
|
notificationManager.startNotificationService()
|
||||||
}
|
}
|
||||||
@@ -621,6 +604,14 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
surfaceRenderer.maxSpeed.value = speed
|
surfaceRenderer.maxSpeed.value = speed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onRecentPlacesReceived(places: List<Place>) {
|
||||||
|
Log.d(TAG, "onRecentPlacesReceived ${places.size}")
|
||||||
|
recentPlaces = places.toMutableList()
|
||||||
|
navigationScreen.recentPlaces = places.toMutableList()
|
||||||
|
navigationScreen.invalidate()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun invalidateScreen() {
|
override fun invalidateScreen() {
|
||||||
navigationScreen.invalidate()
|
navigationScreen.invalidate()
|
||||||
}
|
}
|
||||||
@@ -647,6 +638,7 @@ class NavigationServiceSession : CarSession(), NavigationListener, NavigationObs
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigationViewModel.saveRecent(carContext, place)
|
navigationViewModel.saveRecent(carContext, place)
|
||||||
|
destination = place
|
||||||
// routeModel.navState = routeModel.navState.copy(destination = place)
|
// routeModel.navState = routeModel.navState.copy(destination = place)
|
||||||
if (preview.isEmpty()) {
|
if (preview.isEmpty()) {
|
||||||
navigationViewModel.loadRoute(
|
navigationViewModel.loadRoute(
|
||||||
|
|||||||
@@ -752,6 +752,9 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
|||||||
surfaceRenderer.maxSpeed.value = speed
|
surfaceRenderer.maxSpeed.value = speed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onRecentPlacesReceived(places: List<Place>) {
|
||||||
|
}
|
||||||
|
|
||||||
override fun invalidateScreen() {
|
override fun invalidateScreen() {
|
||||||
navigationScreen.invalidate()
|
navigationScreen.invalidate()
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-49
@@ -6,6 +6,7 @@ import android.app.NotificationManager
|
|||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
|
import android.location.LocationManager
|
||||||
import android.os.Binder
|
import android.os.Binder
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
@@ -16,6 +17,7 @@ import androidx.car.app.CarToast
|
|||||||
import androidx.car.app.model.CarColor
|
import androidx.car.app.model.CarColor
|
||||||
import androidx.car.app.model.CarIcon
|
import androidx.car.app.model.CarIcon
|
||||||
import androidx.car.app.model.Distance
|
import androidx.car.app.model.Distance
|
||||||
|
import androidx.car.app.model.Distance.UNIT_METERS
|
||||||
import androidx.car.app.navigation.NavigationManager
|
import androidx.car.app.navigation.NavigationManager
|
||||||
import androidx.car.app.navigation.NavigationManagerCallback
|
import androidx.car.app.navigation.NavigationManagerCallback
|
||||||
import androidx.car.app.navigation.model.Destination
|
import androidx.car.app.navigation.model.Destination
|
||||||
@@ -29,6 +31,7 @@ import com.kouros.navigation.car.screen.NavigationType
|
|||||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
||||||
import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION
|
import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION
|
||||||
import com.kouros.navigation.data.Constants.MAXIMAL_SNAP_CORRECTION
|
import com.kouros.navigation.data.Constants.MAXIMAL_SNAP_CORRECTION
|
||||||
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.model.NavigationViewModel
|
import com.kouros.navigation.model.NavigationViewModel
|
||||||
import com.kouros.navigation.model.SettingsViewModel
|
import com.kouros.navigation.model.SettingsViewModel
|
||||||
import com.kouros.navigation.repository.SettingsRepository
|
import com.kouros.navigation.repository.SettingsRepository
|
||||||
@@ -37,6 +40,7 @@ import com.kouros.navigation.utils.NavigationUtils.getViewModel
|
|||||||
import com.kouros.navigation.utils.formattedDistance
|
import com.kouros.navigation.utils.formattedDistance
|
||||||
import com.kouros.navigation.utils.getSettingsRepository
|
import com.kouros.navigation.utils.getSettingsRepository
|
||||||
import com.kouros.navigation.utils.getSettingsViewModel
|
import com.kouros.navigation.utils.getSettingsViewModel
|
||||||
|
import com.kouros.navigation.utils.location
|
||||||
import kotlin.collections.copy
|
import kotlin.collections.copy
|
||||||
import kotlin.compareTo
|
import kotlin.compareTo
|
||||||
|
|
||||||
@@ -81,6 +85,8 @@ class NavigationService : Service() {
|
|||||||
// Manages device GPS location updates
|
// Manages device GPS location updates
|
||||||
lateinit var deviceLocationManager: DeviceLocationManagerService
|
lateinit var deviceLocationManager: DeviceLocationManagerService
|
||||||
|
|
||||||
|
var currentLocation = location(0.0, 0.0)
|
||||||
|
|
||||||
lateinit var navigationViewModel: NavigationViewModel
|
lateinit var navigationViewModel: NavigationViewModel
|
||||||
|
|
||||||
private lateinit var navigationManager: NavigationManager
|
private lateinit var navigationManager: NavigationManager
|
||||||
@@ -97,16 +103,15 @@ class NavigationService : Service() {
|
|||||||
hasArrived: Boolean,
|
hasArrived: Boolean,
|
||||||
destinations: MutableList<Destination>,
|
destinations: MutableList<Destination>,
|
||||||
steps: MutableList<Step>,
|
steps: MutableList<Step>,
|
||||||
destinationTravelEstimate: TravelEstimate?,
|
destinationTravelEstimate: TravelEstimate,
|
||||||
stepTravelEstimate: TravelEstimate?,
|
stepTravelEstimate: TravelEstimate,
|
||||||
stepRemainingDistance: Distance?,
|
stepRemainingDistance: Distance,
|
||||||
shouldShowNextStep: Boolean,
|
shouldShowNextStep: Boolean,
|
||||||
shouldShowLanes: Boolean,
|
shouldShowLanes: Boolean,
|
||||||
junctionImage: CarIcon?,
|
junctionImage: CarIcon?,
|
||||||
backGroundColor: CarColor
|
backGroundColor: CarColor
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
fun updateServiceLocation(location: Location)
|
fun updateServiceLocation(location: Location)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -225,29 +230,32 @@ class NavigationService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Starts navigation. */
|
/** Starts navigation. */
|
||||||
fun startNavigation(route: String) {
|
fun startNavigation(route: String, destination: Place) {
|
||||||
Log.i(TAG, "Starting Navigation")
|
Log.i(TAG, "Starting Navigation")
|
||||||
startService(Intent(applicationContext, NavigationService::class.java))
|
startService(Intent(applicationContext, NavigationService::class.java))
|
||||||
|
routeModel.navState = routeModel.navState.copy(destination = destination)
|
||||||
routeModel.navState = routeModel.navState.copy(routingEngine = 2)
|
routeModel.navState = routeModel.navState.copy(routingEngine = 2)
|
||||||
routeModel.startNavigation(route)
|
routeModel.startNavigation(route)
|
||||||
if (routeModel.isNavigating()) {
|
if (routeModel.isNavigating()) {
|
||||||
// listener.navigationStateChanged(
|
routeModel.updateLocation(currentLocation, navigationViewModel)
|
||||||
// isNavigating = true,
|
listener.navigationStateChanged(
|
||||||
// isRerouting = true,
|
isNavigating = true,
|
||||||
// hasArrived = false,
|
isRerouting = false,
|
||||||
// destinations = emptyList<Destination>().toMutableList(),
|
hasArrived = false,
|
||||||
// steps = emptyList<Step>().toMutableList(),
|
destinations = mutableListOf(routeModel.getDestination()),
|
||||||
// destinationTravelEstimate = null,
|
destinationTravelEstimate = routeModel.getTravelEstimateTrip(carContext!!),
|
||||||
// stepTravelEstimate = null,
|
stepTravelEstimate = routeModel.getTravelEstimateStep(carContext!!),
|
||||||
// stepRemainingDistance = null,
|
steps = routeModel.getSteps(carContext!!),
|
||||||
// shouldShowNextStep = false,
|
stepRemainingDistance = routeModel.getDistance(),
|
||||||
// shouldShowLanes = false,
|
shouldShowNextStep = false,
|
||||||
// junctionImage = null,
|
shouldShowLanes = false,
|
||||||
// backGroundColor = CarColor.BLUE
|
junctionImage = null,
|
||||||
// )
|
backGroundColor = routeModel.backGroundColor()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Starts navigation. */
|
/** Starts navigation. */
|
||||||
fun stopNavigation() {
|
fun stopNavigation() {
|
||||||
if (autoDriveEnabled) {
|
if (autoDriveEnabled) {
|
||||||
@@ -261,9 +269,9 @@ class NavigationService : Service() {
|
|||||||
hasArrived = false,
|
hasArrived = false,
|
||||||
destinations = emptyList<Destination>().toMutableList(),
|
destinations = emptyList<Destination>().toMutableList(),
|
||||||
steps = emptyList<Step>().toMutableList(),
|
steps = emptyList<Step>().toMutableList(),
|
||||||
destinationTravelEstimate = null,
|
destinationTravelEstimate = routeModel.travelEstimate(carContext!!, 0.0, 0),
|
||||||
stepTravelEstimate = null,
|
stepTravelEstimate = routeModel.travelEstimate(carContext!!, 0.0, 0),
|
||||||
stepRemainingDistance = null,
|
stepRemainingDistance = Distance.create(0.0, UNIT_METERS),
|
||||||
shouldShowNextStep = false,
|
shouldShowNextStep = false,
|
||||||
shouldShowLanes = false,
|
shouldShowLanes = false,
|
||||||
junctionImage = null,
|
junctionImage = null,
|
||||||
@@ -275,6 +283,7 @@ class NavigationService : Service() {
|
|||||||
|
|
||||||
fun updateLocation(location: Location) {
|
fun updateLocation(location: Location) {
|
||||||
Log.d(TAG, "updateLocation")
|
Log.d(TAG, "updateLocation")
|
||||||
|
currentLocation = location
|
||||||
if (routeModel.isNavigating()) {
|
if (routeModel.isNavigating()) {
|
||||||
routeModel.updateLocation(location, navigationViewModel)
|
routeModel.updateLocation(location, navigationViewModel)
|
||||||
val snappedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
val snappedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
||||||
@@ -296,49 +305,33 @@ class NavigationService : Service() {
|
|||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val travelEstimateTrip = routeModel.travelEstimateTrip(carContext!!, distanceMode)
|
|
||||||
val travelEstimateStep = routeModel.travelEstimateStep(carContext!!, distanceMode)
|
|
||||||
val steps = mutableListOf<Step>()
|
|
||||||
val destination = Destination.Builder()
|
|
||||||
.setName(routeModel.navState.destination.name)
|
|
||||||
.setAddress(routeModel.navState.destination.street)
|
|
||||||
.build()
|
|
||||||
val distance =
|
|
||||||
formattedDistance(0, routeModel.routeCalculator.leftStepDistance())
|
|
||||||
steps.add(routeModel.currentStep(carContext!!))
|
|
||||||
if (routeModel.navState.nextStep) {
|
|
||||||
steps.add(routeModel.nextStep(carContext = carContext!!))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
listener.navigationStateChanged(
|
listener.navigationStateChanged(
|
||||||
isNavigating = routeModel.isNavigating(),
|
isNavigating = routeModel.isNavigating(),
|
||||||
isRerouting = false,
|
isRerouting = false,
|
||||||
hasArrived = routeModel.isArrival(),
|
hasArrived = routeModel.isArrival(),
|
||||||
destinationTravelEstimate = travelEstimateTrip,
|
destinations = mutableListOf(routeModel.getDestination()),
|
||||||
stepTravelEstimate = travelEstimateStep,
|
destinationTravelEstimate = routeModel.getTravelEstimateTrip(carContext!!),
|
||||||
destinations = mutableListOf(destination),
|
stepTravelEstimate = routeModel.getTravelEstimateStep(carContext!!),
|
||||||
steps = steps,
|
steps = routeModel.getSteps(carContext!!),
|
||||||
stepRemainingDistance = Distance.create(distance.first, distance.second),
|
stepRemainingDistance = routeModel.getDistance(),
|
||||||
shouldShowNextStep = false,
|
shouldShowNextStep = false,
|
||||||
shouldShowLanes = true,
|
shouldShowLanes = false,
|
||||||
junctionImage = null,
|
junctionImage = null,
|
||||||
backGroundColor = routeModel.backGroundColor()
|
backGroundColor = routeModel.backGroundColor()
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the trip information and notifies the listener with a new Trip object.
|
* Updates the trip information and notifies the listener with a new Trip object.
|
||||||
* This includes destination name, address, travel estimate, and loading status.
|
* This includes destination name, address, travel estimate, and loading status.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val tripBuilder = Trip.Builder()
|
val tripBuilder = Trip.Builder()
|
||||||
tripBuilder.addDestination(
|
tripBuilder.addDestination(
|
||||||
destination,
|
routeModel.getDestination(),
|
||||||
travelEstimateTrip
|
routeModel.getTravelEstimateTrip(carContext!!)
|
||||||
)
|
)
|
||||||
tripBuilder.setLoading(false)
|
tripBuilder.setLoading(false)
|
||||||
tripBuilder.setCurrentRoad(destination.name.toString())
|
tripBuilder.setCurrentRoad(routeModel.getDestination().name.toString())
|
||||||
tripBuilder.addStep(steps.first(), travelEstimateStep)
|
tripBuilder.addStep(routeModel.getSteps(carContext!!).first(), routeModel.getTravelEstimateStep(carContext!!))
|
||||||
navigationManager.updateTrip(tripBuilder.build())
|
navigationManager.updateTrip(tripBuilder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import androidx.car.app.model.DateTimeWithZone
|
|||||||
import androidx.car.app.model.Distance
|
import androidx.car.app.model.Distance
|
||||||
import androidx.car.app.model.DurationSpan
|
import androidx.car.app.model.DurationSpan
|
||||||
import androidx.car.app.model.ForegroundCarColorSpan
|
import androidx.car.app.model.ForegroundCarColorSpan
|
||||||
|
import androidx.car.app.navigation.model.Destination
|
||||||
import androidx.car.app.navigation.model.Lane
|
import androidx.car.app.navigation.model.Lane
|
||||||
import androidx.car.app.navigation.model.LaneDirection
|
import androidx.car.app.navigation.model.LaneDirection
|
||||||
import androidx.car.app.navigation.model.Maneuver
|
import androidx.car.app.navigation.model.Maneuver
|
||||||
@@ -99,7 +100,6 @@ class RouteCarModel : RouteModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun travelEstimate(carContext: CarContext, timeLeft: Double, distanceMode: Int): TravelEstimate {
|
fun travelEstimate(carContext: CarContext, timeLeft: Double, distanceMode: Int): TravelEstimate {
|
||||||
|
|
||||||
val timeToDestinationMillis =
|
val timeToDestinationMillis =
|
||||||
TimeUnit.SECONDS.toMillis(timeLeft.toLong())
|
TimeUnit.SECONDS.toMillis(timeLeft.toLong())
|
||||||
val distance = formattedDistance(distanceMode, routeCalculator.travelLeftDistance())
|
val distance = formattedDistance(distanceMode, routeCalculator.travelLeftDistance())
|
||||||
@@ -134,6 +134,37 @@ class RouteCarModel : RouteModel() {
|
|||||||
}
|
}
|
||||||
return travelBuilder.build()
|
return travelBuilder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSteps(carContext: CarContext): MutableList<Step> {
|
||||||
|
val steps = mutableListOf<Step>()
|
||||||
|
steps.add(currentStep(carContext))
|
||||||
|
if (navState.nextStep) {
|
||||||
|
steps.add(nextStep(carContext = carContext))
|
||||||
|
}
|
||||||
|
return steps
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDistance(): Distance {
|
||||||
|
val distance =
|
||||||
|
formattedDistance(0, routeCalculator.leftStepDistance())
|
||||||
|
return Distance.create(distance.first, distance.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTravelEstimateTrip(carContext: CarContext): TravelEstimate {
|
||||||
|
return travelEstimateTrip(carContext, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTravelEstimateStep(carContext: CarContext): TravelEstimate {
|
||||||
|
return travelEstimateStep(carContext, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDestination(): Destination {
|
||||||
|
return Destination.Builder()
|
||||||
|
.setName(navState.destination.name)
|
||||||
|
.setAddress(navState.destination.street)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
private fun createDelay(delay: Int): CarText {
|
private fun createDelay(delay: Int): CarText {
|
||||||
val delayBuilder = SpannableStringBuilder()
|
val delayBuilder = SpannableStringBuilder()
|
||||||
delayBuilder.append(
|
delayBuilder.append(
|
||||||
|
|||||||
@@ -154,10 +154,11 @@ open class NavigationScreen(
|
|||||||
.setDestinationTravelEstimate(destinationTravelEstimate)
|
.setDestinationTravelEstimate(destinationTravelEstimate)
|
||||||
.setActionStrip(actionStripBuilder.build())
|
.setActionStrip(actionStripBuilder.build())
|
||||||
.setMapActionStrip(
|
.setMapActionStrip(
|
||||||
mapActionStrip(carContext,
|
mapActionStrip(
|
||||||
|
carContext,
|
||||||
surfaceRenderer.viewStyle,
|
surfaceRenderer.viewStyle,
|
||||||
{ zoomPlus() }, { zoomMinus() }, {
|
{ zoomPlus() }, { zoomMinus() }, {
|
||||||
Action.Builder()
|
Action.Builder()
|
||||||
.setIcon(createCarIcon(carContext, R.drawable.ic_recenter_24))
|
.setIcon(createCarIcon(carContext, R.drawable.ic_recenter_24))
|
||||||
.setFlags(0)
|
.setFlags(0)
|
||||||
.setOnClickListener {
|
.setOnClickListener {
|
||||||
@@ -175,17 +176,18 @@ open class NavigationScreen(
|
|||||||
* Creates and returns a template for the default view state.
|
* Creates and returns a template for the default view state.
|
||||||
*/
|
*/
|
||||||
private fun navigationView(actionStripBuilder: ActionStrip.Builder): Template {
|
private fun navigationView(actionStripBuilder: ActionStrip.Builder): Template {
|
||||||
val mapActionStrip = mapActionStrip(carContext,
|
val mapActionStrip = mapActionStrip(
|
||||||
surfaceRenderer.viewStyle,
|
carContext,
|
||||||
{ zoomPlus() }, { zoomMinus() }, {
|
surfaceRenderer.viewStyle,
|
||||||
createAction(
|
{ zoomPlus() }, { zoomMinus() }, {
|
||||||
carContext = carContext, R.drawable.ic_recenter_24,
|
createAction(
|
||||||
0,
|
carContext = carContext, R.drawable.ic_recenter_24,
|
||||||
onClickAction = {
|
0,
|
||||||
surfaceRenderer.viewStyle = ViewStyle.VIEW
|
onClickAction = {
|
||||||
invalidate()
|
surfaceRenderer.viewStyle = ViewStyle.VIEW
|
||||||
})
|
invalidate()
|
||||||
})
|
})
|
||||||
|
})
|
||||||
return NavigationTemplate.Builder()
|
return NavigationTemplate.Builder()
|
||||||
.setBackgroundColor(backGroundColor)
|
.setBackgroundColor(backGroundColor)
|
||||||
.setActionStrip(actionStripBuilder.build())
|
.setActionStrip(actionStripBuilder.build())
|
||||||
@@ -241,7 +243,8 @@ open class NavigationScreen(
|
|||||||
.setBackgroundColor(backGroundColor)
|
.setBackgroundColor(backGroundColor)
|
||||||
.setActionStrip(actionStripBuilder.build())
|
.setActionStrip(actionStripBuilder.build())
|
||||||
.setMapActionStrip(
|
.setMapActionStrip(
|
||||||
mapActionStrip(carContext,
|
mapActionStrip(
|
||||||
|
carContext,
|
||||||
surfaceRenderer.viewStyle,
|
surfaceRenderer.viewStyle,
|
||||||
{ zoomPlus() }, { zoomMinus() }, {
|
{ zoomPlus() }, { zoomMinus() }, {
|
||||||
createAction(
|
createAction(
|
||||||
@@ -302,7 +305,8 @@ open class NavigationScreen(
|
|||||||
val builder = MapWithContentTemplate.Builder()
|
val builder = MapWithContentTemplate.Builder()
|
||||||
.setContentTemplate(contentTemplate)
|
.setContentTemplate(contentTemplate)
|
||||||
.setActionStrip(
|
.setActionStrip(
|
||||||
mapActionStrip(carContext,
|
mapActionStrip(
|
||||||
|
carContext,
|
||||||
ViewStyle.VIEW,
|
ViewStyle.VIEW,
|
||||||
{ settingsAction() },
|
{ settingsAction() },
|
||||||
{
|
{
|
||||||
@@ -341,10 +345,12 @@ open class NavigationScreen(
|
|||||||
*/
|
*/
|
||||||
fun getRoutingInfo(): RoutingInfo {
|
fun getRoutingInfo(): RoutingInfo {
|
||||||
val routingInfo = RoutingInfo.Builder()
|
val routingInfo = RoutingInfo.Builder()
|
||||||
.setCurrentStep(
|
if (steps.isNotEmpty()) {
|
||||||
|
routingInfo.setCurrentStep(
|
||||||
steps.first(),
|
steps.first(),
|
||||||
stepRemainingDistance
|
stepRemainingDistance
|
||||||
)
|
)
|
||||||
|
}
|
||||||
if (shouldShowNextStep && steps.size > 1) {
|
if (shouldShowNextStep && steps.size > 1) {
|
||||||
routingInfo.setNextStep(steps[1])
|
routingInfo.setNextStep(steps[1])
|
||||||
}
|
}
|
||||||
@@ -492,7 +498,6 @@ open class NavigationScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates navigation state with the current location, checks for arrival, and traffic updates.
|
* Updates navigation state with the current location, checks for arrival, and traffic updates.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,6 @@
|
|||||||
package com.kouros.navigation.car.screen.observers
|
package com.kouros.navigation.car.screen.observers
|
||||||
|
|
||||||
import com.kouros.navigation.data.Place
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.data.nominatim.SearchResult
|
|
||||||
import com.kouros.navigation.data.overpass.Elements
|
import com.kouros.navigation.data.overpass.Elements
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,6 +25,8 @@ interface NavigationObserverCallback {
|
|||||||
/** Called when max speed is updated */
|
/** Called when max speed is updated */
|
||||||
fun onMaxSpeedReceived(speed: Int)
|
fun onMaxSpeedReceived(speed: Int)
|
||||||
|
|
||||||
|
fun onRecentPlacesReceived(places: List<Place>)
|
||||||
|
|
||||||
/** Called to request UI invalidation/refresh */
|
/** Called to request UI invalidation/refresh */
|
||||||
fun invalidateScreen()
|
fun invalidateScreen()
|
||||||
|
|
||||||
|
|||||||
+6
@@ -19,12 +19,18 @@ class NavigationObserverManager(
|
|||||||
val speedCameraObserver = SpeedCameraObserver(callback)
|
val speedCameraObserver = SpeedCameraObserver(callback)
|
||||||
val maxSpeedObserver = MaxSpeedObserver(callback)
|
val maxSpeedObserver = MaxSpeedObserver(callback)
|
||||||
|
|
||||||
|
val recentPlacesObserver = RecentPlacesObserver(callback)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun attachAllObservers(session: CarSession) {
|
fun attachAllObservers(session: CarSession) {
|
||||||
viewModel.route.observe(session, routeObserver)
|
viewModel.route.observe(session, routeObserver)
|
||||||
viewModel.traffic.observe(session, trafficObserver)
|
viewModel.traffic.observe(session, trafficObserver)
|
||||||
viewModel.placeLocation.observe(session, placeSearchObserver)
|
viewModel.placeLocation.observe(session, placeSearchObserver)
|
||||||
viewModel.speedCameras.observe(session, speedCameraObserver)
|
viewModel.speedCameras.observe(session, speedCameraObserver)
|
||||||
viewModel.maxSpeed.observe(session, maxSpeedObserver)
|
viewModel.maxSpeed.observe(session, maxSpeedObserver)
|
||||||
|
viewModel.recentPlaces.observe(session, recentPlacesObserver)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package com.kouros.navigation.car.screen.observers
|
||||||
|
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import com.kouros.navigation.data.Place
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observer for route updates. Triggers navigation start when a non-empty route is received.
|
||||||
|
*/
|
||||||
|
class RecentPlacesObserver(
|
||||||
|
private val callback: NavigationObserverCallback
|
||||||
|
) : Observer<List<Place>> {
|
||||||
|
|
||||||
|
override fun onChanged(value: List<Place>) {
|
||||||
|
if (value.isNotEmpty()) {
|
||||||
|
callback.onRecentPlacesReceived(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user