From 2348d3b633e19711d4d5a94666850dd0a0f32150 Mon Sep 17 00:00:00 2001 From: Dimitris Date: Fri, 27 Mar 2026 07:17:53 +0100 Subject: [PATCH] Duration Map --- app/build.gradle.kts | 4 +- .../com/kouros/navigation/ui/MainActivity.kt | 40 ------------- .../navigation/car/DeviceLocationManager.kt | 2 +- .../navigation/car/NavigationSession.kt | 60 +++++++++++-------- .../navigation/car/navigation/Simulation.kt | 3 +- .../navigation/car/screen/NavigationScreen.kt | 25 ++------ .../java/com/kouros/navigation/data/Data.kt | 10 ++-- .../navigation/utils/NavigationUtils.kt | 4 +- 8 files changed, 51 insertions(+), 97 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bfc4272..ab98ae0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,8 +17,8 @@ android { applicationId = "com.kouros.navigation" minSdk = 33 targetSdk = 36 - versionCode = 83 - versionName = "0.2.0.83" + versionCode = 84 + versionName = "0.2.0.84" base.archivesName = "navi-$versionName" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt b/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt index e64a985..a88cbdc 100644 --- a/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt +++ b/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt @@ -43,7 +43,6 @@ import com.google.android.gms.location.LocationServices import com.kouros.data.R import com.kouros.navigation.MainApplication.Companion.navigationViewModel import com.kouros.navigation.car.TextToSpeechManager -import com.kouros.navigation.car.navigation.NavigationService import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE import com.kouros.navigation.data.Constants.INSTRUCTION_DISTANCE import com.kouros.navigation.data.Constants.TAG @@ -80,8 +79,6 @@ import kotlin.time.Duration.Companion.seconds class MainActivity : ComponentActivity() { - var navigationService: NavigationService? = null - var isBound: Boolean = false val routeData = MutableLiveData("") val routeModel = RouteModel() @@ -102,20 +99,6 @@ class MainActivity : ComponentActivity() { } } - // Monitors the state of the connection to the navigation service. - private val serviceConnection: ServiceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, service: IBinder?) { - val binder: NavigationService.LocalBinder = service as NavigationService.LocalBinder - navigationService = binder.service - isBound = true - } - - override fun onServiceDisconnected(name: ComponentName?) { - navigationService = null - isBound = false - } - } - val cameraPosition = MutableLiveData( CameraPosition( zoom = 15.0, target = Position(latitude = 48.1857475, longitude = 11.5793627) @@ -168,27 +151,6 @@ class MainActivity : ComponentActivity() { } } - override fun onStart() { - super.onStart() - Log.i(TAG, "In onStart()") - bindService( - Intent(this, NavigationService::class.java), - serviceConnection, - BIND_AUTO_CREATE - ) - requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1) - } - - override fun onStop() { - Log.i(TAG, "In onStop(). bound $isBound") - if (isBound) { - unbindService(serviceConnection) - isBound = false - navigationService = null - } - super.onStop() - } - @OptIn(ExperimentalMaterial3Api::class) @Composable fun StartScreen( @@ -356,7 +318,6 @@ class MainActivity : ComponentActivity() { routeModel.navState = routeModel.navState.copy(routingEngine = routingEngine) routeModel.startNavigation(newRoute) routeData.value = routeModel.curRoute.routeGeoJson - navigationService?.startNavigation() } fun stopNavigation(closeSheet: () -> Unit) { closeSheet() @@ -364,7 +325,6 @@ class MainActivity : ComponentActivity() { getSettingsViewModel(applicationContext).onLastRouteChanged("") routeData.value = "" stepData.value = StepData("", "", 0.0, 0, 0, 0, 0.0) - navigationService?.stopNavigation() } fun textToSpeech() { diff --git a/common/car/src/main/java/com/kouros/navigation/car/DeviceLocationManager.kt b/common/car/src/main/java/com/kouros/navigation/car/DeviceLocationManager.kt index dc14488..cd19690 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/DeviceLocationManager.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/DeviceLocationManager.kt @@ -67,7 +67,7 @@ class DeviceLocationManager( * @param minDistanceM Minimum distance between updates in meters (default: 5m) */ @SuppressLint("MissingPermission") - fun startLocationUpdates(minTimeMs: Long = 500, minDistanceM: Float = 5f) { + fun startLocationUpdates(minTimeMs: Long = 1000, minDistanceM: Float = 5f) { if (isListening) return // Get and deliver last known location first 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 795b7a7..c8de4ad 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 @@ -1,13 +1,9 @@ package com.kouros.navigation.car import android.Manifest.permission -import android.content.ComponentName -import android.content.Context import android.content.Intent -import android.content.ServiceConnection import android.content.pm.PackageManager import android.location.Location -import android.os.IBinder import android.util.Log import androidx.car.app.CarContext import androidx.car.app.CarToast @@ -15,13 +11,11 @@ import androidx.car.app.Screen import androidx.car.app.ScreenManager import androidx.car.app.Session import androidx.car.app.connection.CarConnection -import androidx.car.app.model.CarIcon import androidx.car.app.model.Distance import androidx.car.app.navigation.NavigationManager import androidx.car.app.navigation.NavigationManagerCallback import androidx.car.app.navigation.model.Destination import androidx.car.app.navigation.model.Step -import androidx.car.app.navigation.model.TravelEstimate import androidx.car.app.navigation.model.Trip import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleObserver @@ -114,11 +108,13 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb private var showTraffic = false; + private var distanceMode = 0 var lastCameraSearch = 0 var speedCameras = listOf() var lastRouteDate: LocalDateTime = LocalDateTime.now() + var navigationManagerStarted = false /** @@ -170,6 +166,10 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb repository.trafficFlow.asLiveData().observe(this, Observer { showTraffic = it }) + repository.distanceModeFlow.asLiveData().observe(this, Observer { + distanceMode = it + }) + } /** @@ -441,24 +441,33 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb * Snaps location to route and checks for deviation requiring reroute. */ private fun handleNavigationLocation(location: Location) { + routeModel.updateLocation(location, navigationViewModel) + if (routeModel.navState.arrived) return if (guidanceAudio == 1) { handleGuidanceAudio() } val streetName = routeModel.currentStep().street val currentDate = LocalDateTime.now(ZoneOffset.UTC) + checkTraffic(currentDate, location) updateSpeedCamera(location) checkRoute(currentDate, location) - routeModel.updateLocation(location, navigationViewModel) checkArrival() + updateNavigationScreen() - updateTripNavigationScreen(location) + snapLocation(location, streetName) + } - if (routeModel.navState.arrived) return + /** + * Updates the surface renderer with snapped location and street name. + * Checks if maximal route deviation is exceeded and reroutes if needed. + */ + private fun snapLocation(location: Location, streetName: String) { val snappedLocation = snapLocation(location, routeModel.route.maneuverLocations()) val distance = location.distanceTo(snappedLocation) when { distance > MAXIMAL_ROUTE_DEVIATION -> { + stopNavigation() navigationScreen.calculateNewRoute(routeModel.navState.destination) } @@ -472,19 +481,20 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb } } - fun updateTripNavigationScreen(location: Location) { - val travelEstimateTrip = routeModel.travelEstimateTrip(carContext, 0) - val travelEstimateStep = routeModel.travelEstimateStep(carContext, 0) - val steps = mutableListOf() - val street = if (routeModel.navState.destination.street != null) { - routeModel.navState.destination.street!! - } else { - // routeModel.navState.destination.name!! - "Street" + /** + * Updates the navigation screen with new trip information. + */ + fun updateNavigationScreen() { + if (routeModel.navState.destination.name.isEmpty() + && routeModel.navState.destination.street.isEmpty()) { + return } + val travelEstimateTrip = routeModel.travelEstimateTrip(carContext, distanceMode) + val travelEstimateStep = routeModel.travelEstimateStep(carContext, distanceMode) + val steps = mutableListOf() val destination = Destination.Builder() - .setName(street) - .setAddress(street) + .setName(routeModel.navState.destination.name) + .setAddress(routeModel.navState.destination.street) .build() val distance = formattedDistance(0, routeModel.routeCalculator.leftStepDistance()) @@ -501,7 +511,7 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb stepTravelEstimate = travelEstimateStep, destinations = mutableListOf(destination), steps = steps, - nextStepRemainingDistance = Distance.create(distance.first, distance.second), + stepRemainingDistance = Distance.create(distance.first, distance.second), shouldShowNextStep = false, shouldShowLanes = true, junctionImage = null, @@ -603,7 +613,7 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb } else { prepareRoute(route) } - updateTripNavigationScreen(surfaceRenderer.lastLocation) + updateNavigationScreen() } } @@ -618,8 +628,7 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb } surfaceRenderer.setRouteData(routeModel.curRoute.routeGeoJson) startNavigation() - updateTripNavigationScreen(surfaceRenderer.lastLocation) - //navigationScreen.updateTrip(surfaceRenderer.lastLocation) + updateNavigationScreen() } /** @@ -630,8 +639,7 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb newRouteModel.navState = routeModel.navState.copy(routingEngine = routingEngine) newRouteModel.startNavigation(route) routeModel.curRoute.summary.trafficDelay = newRouteModel.curRoute.summary.trafficDelay - //navigationScreen.updateTrip(surfaceRenderer.lastLocation) - updateTripNavigationScreen(surfaceRenderer.lastLocation) + updateNavigationScreen() } diff --git a/common/car/src/main/java/com/kouros/navigation/car/navigation/Simulation.kt b/common/car/src/main/java/com/kouros/navigation/car/navigation/Simulation.kt index e0ce33e..7dd056b 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/navigation/Simulation.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/navigation/Simulation.kt @@ -115,8 +115,9 @@ class Simulation { updateLocation(fakeLocation) // Wait before moving to the next point (e.g., every 1 second) if (duration > 100) { - delay(duration / 4) + // delay(duration / 4) } + delay(1000) lastTime = p.time lastLocation = fakeLocation } 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 64ef8c8..6cc8475 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 @@ -65,8 +65,6 @@ open class NavigationScreen( val settingsViewModel = getSettingsViewModel(carContext) - private var distanceMode = 0 - private var tripSuggestion = false private var tripSuggestionCalled = false @@ -76,25 +74,15 @@ open class NavigationScreen( private var isNavigating = false private var isRerouting = false private var hasArrived = false - private lateinit var destinations: MutableList - private lateinit var stepRemainingDistance: Distance - private lateinit var destinationTravelEstimate: TravelEstimate - private lateinit var stepTravelEstimate: TravelEstimate - private var shouldShowNextStep = false - private var shouldShowLanes = false - private lateinit var steps: MutableList - - var junctionImage: CarIcon? = null - - var backGroundColor = CarColor.BLUE - + private var junctionImage: CarIcon? = null + private var backGroundColor = CarColor.BLUE val observerRecentPlaces = Observer> { newPlaces -> recentPlaces.addAll(newPlaces) if (newPlaces.isNotEmpty() && !tripSuggestionCalled) { @@ -108,9 +96,6 @@ open class NavigationScreen( lifecycleScope.launch { settingsViewModel.tripSuggestion.first() } - repository.distanceModeFlow.asLiveData().observe(this, Observer { - distanceMode = it - }) repository.tripSuggestionFlow.asLiveData().observe(this, Observer { navigationViewModel.recentPlaces.observe(this, observerRecentPlaces) @@ -481,7 +466,6 @@ open class NavigationScreen( * Initiates recalculation for a new route to the destination. */ fun calculateNewRoute(destination: Place) { - stopNavigation() navigationType = NavigationType.REROUTE invalidate() val mainThreadHandler = Handler(carContext.mainLooper) @@ -511,7 +495,6 @@ open class NavigationScreen( ) } - /** * Updates navigation state with the current location, checks for arrival, and traffic updates. */ @@ -523,7 +506,7 @@ open class NavigationScreen( steps: MutableList, destinationTravelEstimate: TravelEstimate, stepTravelEstimate: TravelEstimate, - nextStepRemainingDistance: Distance, + stepRemainingDistance: Distance, shouldShowNextStep: Boolean, shouldShowLanes: Boolean, junctionImage: CarIcon?, @@ -534,7 +517,7 @@ open class NavigationScreen( this.hasArrived = hasArrived this.destinations = destinations this.steps = steps - stepRemainingDistance = nextStepRemainingDistance + this.stepRemainingDistance = stepRemainingDistance this.destinationTravelEstimate = destinationTravelEstimate this.stepTravelEstimate = stepTravelEstimate this.shouldShowNextStep = shouldShowNextStep 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 d900f25..0f12b6c 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 @@ -34,13 +34,13 @@ data class Places( @Serializable data class Place( var id: Long = 0, - var name: String? = null, - var category: String? = null, + var name: String = "", + var category: String = "", var latitude: Double = 0.0, var longitude: Double = 0.0, - var postalCode: String? = null, - var city: String? = null, - var street: String? = null, + var postalCode: String = "", + var city: String = "", + var street: String = "", var distance: Float = 0F, //var avatar: Uri? = null, var lastDate: Long = 0, 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 846aed8..e9b943f 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 @@ -3,7 +3,9 @@ package com.kouros.navigation.utils import android.content.Context import android.location.Location import android.location.LocationManager +import android.util.Log import androidx.car.app.model.Distance +import com.kouros.navigation.data.Constants.TAG import com.kouros.navigation.data.Constants.TILT import com.kouros.navigation.data.RouteEngine import com.kouros.navigation.data.osrm.OsrmRepository @@ -141,7 +143,7 @@ fun duration( val cameraDuration = if ((lastBearing - bearing).absoluteValue > 20.0) { 2.seconds } else { - 1.seconds + 1.2.seconds //val updateDuration = java.time.Duration.between(LocalDateTime.now(), lastLocationUpdate) //((updateDuration!!.toMillis().absoluteValue * 1.2).toDuration(DurationUnit.MILLISECONDS)) }