From bc8a53a5d8f97e5697d94973ab9e7c452dc43d11 Mon Sep 17 00:00:00 2001 From: Dimitris Date: Mon, 23 Mar 2026 07:10:26 +0100 Subject: [PATCH] Preview --- app/build.gradle.kts | 4 +- .../kouros/navigation/car/CarSensorManager.kt | 2 + .../navigation/car/NavigationSession.kt | 5 +- .../kouros/navigation/car/SurfaceRenderer.kt | 10 +-- .../navigation/car/screen/NavigationScreen.kt | 74 +++++++++++++------ .../navigation/car/screen/PlaceListScreen.kt | 6 +- .../car/screen/RoutePreviewScreen.kt | 3 +- .../navigation/car/screen/SearchScreen.kt | 4 +- .../car/screen/settings/NavigationSettings.kt | 1 - .../java/com/kouros/navigation/data/Data.kt | 3 +- .../java/com/kouros/navigation/data/Route.kt | 18 ++--- .../data/tomtom/TomTomRepository.kt | 4 +- .../navigation/utils/NavigationUtils.kt | 3 +- 13 files changed, 78 insertions(+), 59 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 90262c2..09850d8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,8 +13,8 @@ android { applicationId = "com.kouros.navigation" minSdk = 33 targetSdk = 36 - versionCode = 73 - versionName = "0.2.0.73" + versionCode = 76 + versionName = "0.2.0.76" base.archivesName = "navi-$versionName" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/common/car/src/main/java/com/kouros/navigation/car/CarSensorManager.kt b/common/car/src/main/java/com/kouros/navigation/car/CarSensorManager.kt index 207fc8a..3b56910 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/CarSensorManager.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/CarSensorManager.kt @@ -1,6 +1,7 @@ package com.kouros.navigation.car import android.location.Location +import android.util.Log import androidx.car.app.CarContext import androidx.car.app.connection.CarConnection import androidx.car.app.hardware.CarHardwareManager @@ -14,6 +15,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle +import com.kouros.navigation.data.Constants.TAG import com.kouros.navigation.utils.getSettingsRepository import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch diff --git a/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt b/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt index 4ae1b92..14057ca 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt @@ -35,6 +35,7 @@ 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.Place import com.kouros.navigation.data.RouteEngine import com.kouros.navigation.data.osrm.OsrmRepository import com.kouros.navigation.data.tomtom.TomTomRepository @@ -140,7 +141,7 @@ class NavigationSession : Session(), NavigationListener { * Initializes car hardware sensors if available. */ fun onPermissionGranted(permission: Boolean) { - if (::carSensorManager.isInitialized) { + if (::carSensorManager.isInitialized && permission) { carSensorManager.updateConnectionState(routeModel.navState.carConnection) } } @@ -333,7 +334,7 @@ class NavigationSession : Session(), NavigationListener { private fun handleNavigateIntent(screenManager: ScreenManager) { screenManager.popToRoot() screenManager.pushForResult( - SearchScreen(carContext, surfaceRenderer, navigationViewModel, emptyList()) + SearchScreen(carContext, surfaceRenderer, navigationViewModel, mutableListOf()) ) { result -> // Handle search result if needed } diff --git a/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt b/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt index e59ebc9..fb7f6ce 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt @@ -68,7 +68,7 @@ class SurfaceRenderer( var carOrientation = 999F // Current camera position state for the map - private val cameraPosition = MutableLiveData( + val cameraPosition = MutableLiveData( CameraPosition( zoom = 16.0, target = Position(latitude = homeVogelhart.latitude, longitude = homeVogelhart.longitude) @@ -392,7 +392,6 @@ class SurfaceRenderer( * Sets route data for active navigation and switches to VIEW mode. */ fun setRouteData() { - println("SetRouteData") routeData.value = routeModel.curRoute.routeGeoJson viewStyle = ViewStyle.VIEW } @@ -401,7 +400,7 @@ class SurfaceRenderer( * Updates camera position with new bearing, zoom, and target. * Posts update to LiveData for UI observation. */ - private fun updateCameraPosition(bearing: Double, zoom: Double, target: Position, tilt: Double) { + fun updateCameraPosition(bearing: Double, zoom: Double, target: Position, tilt: Double) { synchronized(this) { cameraPosition.postValue( cameraPosition.value!!.copy( @@ -458,11 +457,6 @@ class SurfaceRenderer( } - - fun updateTrafficData(routeModel: RouteCarModel) { - - } - /** * Displays a specific location (e.g., amenity/POI) on the map. */ diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt index 4080690..bcd6e06 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt @@ -4,11 +4,9 @@ import android.location.Location import android.location.LocationManager import android.os.CountDownTimer import android.os.Handler -import android.util.Log import androidx.car.app.CarContext import androidx.car.app.Screen import androidx.car.app.model.Action -import androidx.car.app.model.Action.FLAG_DEFAULT import androidx.car.app.model.Action.FLAG_IS_PERSISTENT import androidx.car.app.model.ActionStrip import androidx.car.app.model.CarColor @@ -40,19 +38,21 @@ import com.kouros.navigation.car.screen.observers.NavigationObserverManager import com.kouros.navigation.car.screen.settings.SettingsScreen import com.kouros.navigation.data.Constants import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE -import com.kouros.navigation.data.Constants.ROUTE_UPDATE +import com.kouros.navigation.data.Constants.TILT import com.kouros.navigation.data.Constants.TRAFFIC_UPDATE import com.kouros.navigation.data.Place import com.kouros.navigation.data.overpass.Elements import com.kouros.navigation.model.NavigationViewModel import com.kouros.navigation.model.RouteModel import com.kouros.navigation.utils.GeoUtils +import com.kouros.navigation.utils.calculateZoom import com.kouros.navigation.utils.formattedDistance import com.kouros.navigation.utils.getSettingsRepository import com.kouros.navigation.utils.getSettingsViewModel import com.kouros.navigation.utils.location import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch +import org.maplibre.spatialk.geojson.Position import java.time.Duration import java.time.LocalDateTime import java.time.ZoneOffset @@ -74,14 +74,14 @@ open class NavigationScreen( var currentNavigationLocation = Location(LocationManager.GPS_PROVIDER) - var recentPlaces = emptyList() + var recentPlaces = mutableListOf() var recentPlace: Place = Place() var navigationType = NavigationType.VIEW var lastTrafficDate: LocalDateTime = LocalDateTime.MIN - var lastRouteDate: LocalDateTime = LocalDateTime.MIN + var lastRouteDate: LocalDateTime = LocalDateTime.now() var lastCameraSearch = 0 var speedCameras = listOf() val observerManager = NavigationObserverManager(navigationViewModel, this) @@ -103,7 +103,7 @@ open class NavigationScreen( private var reRouteTimer: CountDownTimer? = null val observerRecentPlaces = Observer> { newPlaces -> - recentPlaces = newPlaces + recentPlaces.addAll(newPlaces) if (newPlaces.isNotEmpty() && !tripSuggestionCalled) { tripSuggestionCalled = true navigationType = NavigationType.RECENT @@ -147,8 +147,7 @@ open class NavigationScreen( createAction( carContext, R.drawable.search_48px, - FLAG_IS_PERSISTENT, - onClickAction = { startSearchScreen()} + onClickAction = { startSearchScreen() } ) }, { settingsAction() }) return when (navigationType) { @@ -165,7 +164,11 @@ open class NavigationScreen( */ private fun navigationTemplate(actionStripBuilder: ActionStrip.Builder): Template { actionStripBuilder.addAction( - createAction(carContext, R.drawable.ic_close_white_24dp, FLAG_IS_PERSISTENT,{ stopNavigation() }) + createAction( + carContext, + R.drawable.ic_close_white_24dp, + 0, + { stopNavigation() }) ) updateTrip() return NavigationTemplate.Builder() @@ -179,8 +182,8 @@ open class NavigationScreen( surfaceRenderer.viewStyle, { zoomPlus() }, { zoomMinus() }, { createAction( - carContext = carContext, R.drawable.ic_zoom_out_24, - FLAG_IS_PERSISTENT, + carContext = carContext, R.drawable.ic_pan_24, + 0, onClickAction = { surfaceRenderer.viewStyle = ViewStyle.VIEW invalidate() @@ -204,7 +207,8 @@ open class NavigationScreen( surfaceRenderer.viewStyle, { zoomPlus() }, { zoomMinus() }, { createAction( - carContext = carContext, R.drawable.ic_zoom_out_24, + carContext = carContext, R.drawable.ic_pan_24, + 0, onClickAction = { surfaceRenderer.viewStyle = ViewStyle.VIEW invalidate() @@ -264,7 +268,8 @@ open class NavigationScreen( surfaceRenderer.viewStyle, { zoomPlus() }, { zoomMinus() }, { createAction( - carContext = carContext, R.drawable.ic_zoom_out_24, + carContext = carContext, R.drawable.ic_pan_24, + 0, onClickAction = { surfaceRenderer.viewStyle = ViewStyle.VIEW invalidate() @@ -286,7 +291,7 @@ open class NavigationScreen( createAction( carContext, R.drawable.search_48px, - FLAG_IS_PERSISTENT, + 0, { startSearchScreen() }) }, { settingsAction() }) @@ -323,7 +328,13 @@ open class NavigationScreen( mapActionStrip( ViewStyle.VIEW, { settingsAction() }, - { createAction(carContext, R.drawable.search_48px, FLAG_IS_PERSISTENT,{ startSearchScreen() }) }, + { + createAction( + carContext, + R.drawable.search_48px, + FLAG_IS_PERSISTENT, + { startSearchScreen() }) + }, { createAction( carContext = carContext, R.drawable.ic_zoom_out_24, @@ -410,9 +421,15 @@ open class NavigationScreen( * Creates an action to start the settings screen. */ private fun settingsAction(): Action { - return createAction( +// return Action.Builder() +// .setIcon(createCarIcon(carContext, R.drawable.settings_48px)) +// .setOnClickListener { +// screenManager.push(SettingsScreen(carContext, navigationViewModel)) +// } +// .build() + return createAction( carContext, R.drawable.settings_48px, - FLAG_IS_PERSISTENT, + 0, onClickAction = { screenManager.push(SettingsScreen(carContext, navigationViewModel)) } @@ -425,7 +442,7 @@ open class NavigationScreen( private fun zoomPlus(): Action { return createAction( carContext, R.drawable.ic_zoom_in_24, - FLAG_IS_PERSISTENT, + 0, onClickAction = { surfaceRenderer.handleScale(1) invalidate() @@ -437,8 +454,9 @@ open class NavigationScreen( * Creates an action to zoom out on the map. */ private fun zoomMinus(): Action { - return createAction( + return createAction( carContext, R.drawable.ic_zoom_out_24, + 0, onClickAction = { surfaceRenderer.handleScale(-1) invalidate() @@ -497,6 +515,12 @@ open class NavigationScreen( } routeModel.navState = routeModel.navState.copy(destination = place) surfaceRenderer.viewStyle = ViewStyle.VIEW + surfaceRenderer.updateCameraPosition( + 0.0, + 16.0, + Position(surfaceRenderer.lastLocation.longitude, surfaceRenderer.lastLocation.latitude), + TILT + ) invalidate() } @@ -550,7 +574,7 @@ open class NavigationScreen( */ fun updateTrip(location: Location) { val current = LocalDateTime.now(ZoneOffset.UTC) - //checkRoute(current, location) + checkRoute(current, location) checkTraffic(current, location) updateSpeedCamera(location) @@ -566,7 +590,8 @@ open class NavigationScreen( */ private fun checkRoute(current: LocalDateTime, location: Location) { val duration = Duration.between(current, lastRouteDate) - if (duration.abs().seconds > ROUTE_UPDATE) { + val routeUpdate = routeModel.curRoute.summary.duration / 6 + if (duration.abs().seconds > routeUpdate) { lastRouteDate = current val destination = location( routeModel.navState.destination.longitude, @@ -706,10 +731,11 @@ open class NavigationScreen( * Update route and traffic data */ private fun updateRoute(route: String) { - val routeModel = RouteModel() - routeModel.navState = routeModel.navState.copy(routingEngine = routingEngine) + val newRouteModel = RouteModel() + newRouteModel.navState = routeModel.navState.copy(routingEngine = routingEngine) navigationType = NavigationType.NAVIGATION - routeModel.startNavigation(route) + newRouteModel.startNavigation(route) + routeModel.curRoute.summary.trafficDelay = newRouteModel.curRoute.summary.trafficDelay } /** diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt index 5dbf045..51a8aa3 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt @@ -36,15 +36,13 @@ class PlaceListScreen( private val surfaceRenderer: SurfaceRenderer, private val category: String, private val navigationViewModel: NavigationViewModel, - private val recentPlaces: List, + private val recentPlaces: MutableList, ) : Screen(carContext) { val routeModel = RouteCarModel() var place = Place() - var mPlaces = mutableListOf() - val repository = getSettingsRepository(carContext) private var routingEngine = 0 @@ -149,7 +147,7 @@ class PlaceListScreen( carContext, R.string.recent_Item_deleted, CarToast.LENGTH_LONG ).show() - mPlaces.remove(place) + recentPlaces.remove(place) invalidate() } diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt index d3a8b3b..6d87a1f 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt @@ -62,7 +62,6 @@ class RoutePreviewScreen( private var isFavorite = false val maxListItems: Int = 3 - val navigationUtils = NavigationUtils(carContext) val repository = getSettingsRepository(carContext) @@ -245,6 +244,7 @@ class RoutePreviewScreen( private fun zoomMinus(): Action { return createAction( carContext, R.drawable.ic_zoom_out_24, + FLAG_IS_PERSISTENT, onClickAction = { surfaceRenderer.handleScale(-1) invalidate() @@ -355,7 +355,6 @@ class RoutePreviewScreen( private fun onRouteSelected(index: Int) { routeModel.navState = routeModel.navState.copy(currentRouteIndex = index) surfaceRenderer.setPreviewRouteData(routeModel) - surfaceRenderer.updateTrafficData(routeModel) routeSelected = true invalidate() } diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/SearchScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/SearchScreen.kt index 5f498c1..029518d 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/SearchScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/SearchScreen.kt @@ -28,7 +28,7 @@ class SearchScreen( carContext: CarContext, private var surfaceRenderer: SurfaceRenderer, private val navigationViewModel: NavigationViewModel, - private val recentPlaces: List, + private val recentPlaces: MutableList, ) : Screen(carContext) { var isSearchComplete: Boolean = false @@ -52,7 +52,6 @@ class SearchScreen( } } - init { navigationViewModel.searchPlaces.observe(this, observer) } @@ -182,6 +181,7 @@ class SearchScreen( postalCode = result.address.postcode, distance = result.distance ) + recentPlaces.add(place) setResult(place) finish() } diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/settings/NavigationSettings.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/settings/NavigationSettings.kt index 00918e0..5432c99 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/settings/NavigationSettings.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/settings/NavigationSettings.kt @@ -31,7 +31,6 @@ class NavigationSettings( private var ferryToggleState = false - private var carLocationToggleState = false val settingsViewModel = getSettingsViewModel(carContext) diff --git a/common/data/src/main/java/com/kouros/navigation/data/Data.kt b/common/data/src/main/java/com/kouros/navigation/data/Data.kt index eb2f80e..9f21254 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Data.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Data.kt @@ -130,9 +130,8 @@ object Constants { const val TRAFFIC_UPDATE = 300 - const val ROUTE_UPDATE = 60 - const val INSTRUCTION_DISTANCE = 50 + const val GMS_CAR_SPEED_PERMISSION = "com.google.android.gms.permission.CAR_SPEED" const val AUTOMOTIVE_CAR_SPEED_PERMISSION = "android.car.permission.CAR_SPEED" diff --git a/common/data/src/main/java/com/kouros/navigation/data/Route.kt b/common/data/src/main/java/com/kouros/navigation/data/Route.kt index f2d9033..b0ed13d 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Route.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Route.kt @@ -105,15 +105,6 @@ data class Route( } } - fun nextStep(add: Int): Step { - val nextIndex = currentStepIndex + add - return if (isRouteValid() && nextIndex < legs().first().steps.size) { - legs().first().steps[nextIndex] - } else { - currentStep() - } - } - fun maneuverLocations(): List { val waypoints = currentStep().maneuver.waypoints val points = mutableListOf() @@ -123,4 +114,13 @@ data class Route( } return points } + + fun nextStep(add: Int): Step { + val nextIndex = currentStepIndex + add + return if (isRouteValid() && nextIndex < legs().first().steps.size) { + legs().first().steps[nextIndex] + } else { + currentStep() + } + } } \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/TomTomRepository.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/TomTomRepository.kt index 772ca9a..5451efa 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/tomtom/TomTomRepository.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/TomTomRepository.kt @@ -19,9 +19,9 @@ const val tomtomTrafficUrl = "https://api.tomtom.com/traffic/services/5/incident private const val tomtomFields = "{incidents{type,geometry{type,coordinates},properties{iconCategory,events{description}}}}" -const val useLocal = false +const val useLocal = true -const val useLocalTraffic = false +const val useLocalTraffic = true class TomTomRepository : NavigationRepository() { diff --git a/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt b/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt index cc751c2..17f85ea 100644 --- a/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt +++ b/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt @@ -4,6 +4,7 @@ import android.content.Context import android.location.Location import android.location.LocationManager import androidx.car.app.model.Distance +import com.kouros.navigation.data.Constants.TILT import com.kouros.navigation.data.RouteEngine import com.kouros.navigation.data.osrm.OsrmRepository import com.kouros.navigation.data.tomtom.TomTomRepository @@ -93,7 +94,7 @@ fun calculateTilt(newZoom: Double, tilt: Double): Double = 0.0 } else { if (tilt == 0.0) { - 55.0 + TILT } else { tilt }