This commit is contained in:
Dimitris
2026-02-20 15:00:47 +01:00
parent ebd97cf1c9
commit 723707dac6
29 changed files with 487 additions and 648 deletions

View File

@@ -2,7 +2,6 @@ package com.kouros.navigation.car
import android.Manifest
import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
@@ -34,12 +33,10 @@ import com.kouros.navigation.car.navigation.RouteCarModel
import com.kouros.navigation.car.screen.NavigationScreen
import com.kouros.navigation.car.screen.RequestPermissionScreen
import com.kouros.navigation.car.screen.SearchScreen
import com.kouros.navigation.data.Constants.CAR_LOCATION
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.RouteEngine
import com.kouros.navigation.data.datastore.DataStoreManager
import com.kouros.navigation.data.osrm.OsrmRepository
import com.kouros.navigation.data.tomtom.TomTomRepository
import com.kouros.navigation.data.valhalla.ValhallaRepository
@@ -47,7 +44,6 @@ import com.kouros.navigation.model.NavigationViewModel
import com.kouros.navigation.utils.GeoUtils.snapLocation
import com.kouros.navigation.utils.NavigationUtils.getViewModel
import com.kouros.navigation.utils.getSettingsRepository
import com.kouros.navigation.utils.getSettingsViewModel
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch

View File

@@ -31,7 +31,6 @@ import com.kouros.navigation.car.map.cameraState
import com.kouros.navigation.car.map.getPaddingValues
import com.kouros.navigation.car.map.rememberBaseStyle
import com.kouros.navigation.car.navigation.RouteCarModel
import com.kouros.navigation.data.Constants.ROUTING_ENGINE
import com.kouros.navigation.data.Constants.homeVogelhart
import com.kouros.navigation.data.ObjectBox
import com.kouros.navigation.data.RouteEngine
@@ -42,7 +41,6 @@ import com.kouros.navigation.utils.calculateTilt
import com.kouros.navigation.utils.calculateZoom
import com.kouros.navigation.utils.duration
import com.kouros.navigation.utils.getSettingsRepository
import com.kouros.navigation.utils.getSettingsViewModel
import com.kouros.navigation.utils.location
import com.kouros.navigation.utils.previewZoom
import com.kouros.navigation.utils.settingsViewModel

View File

@@ -22,18 +22,18 @@ class DisplaySettings(private val carContext: CarContext) : Screen(carContext) {
init {
lifecycleScope.launch {
settingsViewModel.threedBuilding.collect {
settingsViewModel.show3D.collect {
invalidate()
}
}
}
override fun onGetTemplate(): Template {
buildingToggleState = settingsViewModel.threedBuilding.value
buildingToggleState = settingsViewModel.show3D.value
val listBuilder = ItemList.Builder()
val buildingToggle: Toggle =
Toggle.Builder { checked: Boolean ->
settingsViewModel.onThreedBuildingChanged(checked)
settingsViewModel.onShow3DChanged(checked)
buildingToggleState = !buildingToggleState
}.setChecked(buildingToggleState).build()
listBuilder.addItem(buildRowForTemplate(R.string.threed_building, buildingToggle))

View File

@@ -38,9 +38,7 @@ import com.kouros.navigation.repository.SettingsRepository
import com.kouros.navigation.utils.GeoUtils
import com.kouros.navigation.utils.getSettingsViewModel
import com.kouros.navigation.utils.location
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.time.Duration
import java.time.LocalDateTime
import java.time.ZoneOffset

View File

@@ -30,7 +30,11 @@ class NavigationSettings(private val carContext: CarContext, private var navigat
init {
lifecycleScope.launch {
settingsViewModel.avoidTollway.collect {
invalidate()
settingsViewModel.avoidMotorway.collect {
settingsViewModel.carLocation.collect {
invalidate()
}
}
}
}
}

View File

@@ -102,8 +102,6 @@ object Constants {
//const val STYLE_DARK: String = "https://kouros-online.de/liberty_night.json"
const val STYLE: String = "https://tiles.openfreemap.org/styles/liberty"
const val STYLE_DARK: String = "https://tiles.openfreemap.org/styles/liberty"
const val TAG: String = "Navigation"
const val CATEGORIES: String = "Categories"
@@ -126,21 +124,6 @@ object Constants {
val homeVogelhart = location(11.5793748, 48.185749)
val homeHohenwaldeck = location( 11.594322, 48.1164817)
const val SHARED_PREF_KEY = "NavigationPrefs"
const val SHOW_THREED_BUILDING = "Show3D"
const val DARK_MODE_SETTINGS = "DarkMode"
const val AVOID_MOTORWAY = "AvoidMotorway"
const val AVOID_TOLLWAY = "AvoidTollway"
const val CAR_LOCATION = "CarLocation"
const val ROUTING_ENGINE = "RoutingEngine"
const val LAST_ROUTE = "LastRoute"
const val NEXT_STEP_THRESHOLD = 500.0
const val MAXIMAL_SNAP_CORRECTION = 50.0

View File

@@ -51,11 +51,10 @@ abstract class NavigationRepository {
currentLocation: Location,
location: Location,
carOrientation: Float,
searchFilter: SearchFilter,
context: Context
): Double {
val osrm = OsrmRepository()
val route = osrm.getRoute(context, currentLocation, location, carOrientation, searchFilter)
val route = osrm.getRoute(context, currentLocation, location, carOrientation, SearchFilter())
val gson = GsonBuilder().serializeNulls().create()
val osrmJson = gson.fromJson(route, OsrmResponse::class.java)
if (osrmJson.routes.isEmpty()) {

View File

@@ -6,6 +6,7 @@ import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
@@ -26,7 +27,7 @@ class DataStoreManager(private val context: Context) {
// Keys
private object PreferencesKeys {
val THREED_BUILDING = booleanPreferencesKey("Show3D")
val SHOW_3D = booleanPreferencesKey("Show3D")
val DARK_MODE = intPreferencesKey("DarkMode")
@@ -37,13 +38,17 @@ class DataStoreManager(private val context: Context) {
val CAR_LOCATION = booleanPreferencesKey("CarLocation")
val ROUTING_ENGINE = intPreferencesKey("RoutingEngine")
val LAST_ROUTE = stringPreferencesKey("LastRoute")
val TOMTOM_APIKEY = stringPreferencesKey("TomTomApiKey")
}
// Read values
val threeDBuildingFlow: Flow<Boolean> =
val show3DFlow: Flow<Boolean> =
context.dataStore.data.map { preferences ->
preferences[PreferencesKeys.THREED_BUILDING] == true
preferences[PreferencesKeys.SHOW_3D] == true
}
val darkModeFlow: Flow<Int> =
context.dataStore.data.map { preferences ->
@@ -72,10 +77,22 @@ class DataStoreManager(private val context: Context) {
?: 0
}
val lastRouteFlow: Flow<String> =
context.dataStore.data.map { preferences ->
preferences[PreferencesKeys.LAST_ROUTE]
?: ""
}
val tomTomApiKeyFlow: Flow<String> =
context.dataStore.data.map { preferences ->
preferences[PreferencesKeys.TOMTOM_APIKEY]
?: ""
}
// Save values
suspend fun setThreedBuilding(enabled: Boolean) {
suspend fun setShow3D(enabled: Boolean) {
context.dataStore.edit { preferences ->
preferences[PreferencesKeys.THREED_BUILDING] = enabled
preferences[PreferencesKeys.SHOW_3D] = enabled
}
}
@@ -108,4 +125,16 @@ class DataStoreManager(private val context: Context) {
prefs[PreferencesKeys.ROUTING_ENGINE] = mode
}
}
suspend fun setLastRoute(route: String) {
context.dataStore.edit { prefs ->
prefs[PreferencesKeys.LAST_ROUTE] = route
}
}
suspend fun setTomtomApiKey(apiKey: String) {
context.dataStore.edit { prefs ->
prefs[PreferencesKeys.TOMTOM_APIKEY] = apiKey
}
}
}

View File

@@ -6,18 +6,21 @@ import com.kouros.data.R
import com.kouros.navigation.data.NavigationRepository
import com.kouros.navigation.data.SearchFilter
import com.kouros.navigation.utils.GeoUtils.calculateSquareRadius
import com.kouros.navigation.utils.getSettingsRepository
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
private const val routeUrl = "https://api.tomtom.com/routing/1/calculateRoute/"
const val tomtomApiKey = "678k5v6940cSXXIS5oD92qIrDgW3RBZ3"
//const val tomtomApiKey = "678k5v6940cSXXIS5oD92qIrDgW3RBZ3"
const val tomtomTrafficUrl = "https://api.tomtom.com/traffic/services/5/incidentDetails"
private const val tomtomFields =
"{incidents{type,geometry{type,coordinates},properties{iconCategory,events{description}}}}"
const val useAsset = true
const val useAsset = false
class TomTomRepository : NavigationRepository() {
override fun getRoute(
@@ -32,6 +35,8 @@ class TomTomRepository : NavigationRepository() {
val routeJsonString = routeJson.bufferedReader().use { it.readText() }
return routeJsonString
}
val repository = getSettingsRepository(context)
val tomtomApiKey = runBlocking { repository.tomTomApiKeyFlow.first() }
val url =
routeUrl + "${currentLocation.latitude},${currentLocation.longitude}:${location.latitude},${location.longitude}" +
"/json?vehicleHeading=90&sectionType=traffic&report=effectiveSettings&routeType=eco" +
@@ -47,6 +52,8 @@ class TomTomRepository : NavigationRepository() {
}
override fun getTraffic(context: Context, location: Location, carOrientation: Float): String {
val repository = getSettingsRepository(context)
val tomtomApiKey = runBlocking { repository.tomTomApiKeyFlow.first() }
val bbox = calculateSquareRadius(location.latitude, location.longitude, 15.0)
return if (useAsset) {
val trafficJson = context.resources.openRawResource(R.raw.tomtom_traffic)

View File

@@ -102,7 +102,6 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
location,
plLocation,
carOrientation,
SearchFilter(),
context
)
place.distance = distance.toFloat()
@@ -135,7 +134,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
location,
plLocation,
carOrientation,
getSearchFilter(context), context
context
)
place.distance = distance.toFloat()
}
@@ -164,7 +163,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
location,
plLocation,
carOrientation,
getSearchFilter(context),
context
)
place.distance = distance.toFloat()
@@ -486,7 +485,6 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
location,
plLocation,
carOrientation,
getSearchFilter(context),
context
)
place.distance = distance.toFloat()

View File

@@ -60,7 +60,7 @@ open class RouteModel {
)
if (hasLegs()) {
navState = navState.copy(navigating = true)
//NavigationUtils.setStringKeyValue(context, routeString, LAST_ROUTE)
getSettingsViewModel(context).onLastRouteChanged(routeString)
}
}
@@ -75,7 +75,7 @@ open class RouteModel {
arrived = false,
maneuverType = Maneuver.TYPE_UNKNOWN
)
//NavigationUtils.setStringKeyValue(context, "", LAST_ROUTE)
getSettingsViewModel(context).onLastRouteChanged("")
}
fun updateLocation(context: Context, curLocation: Location, viewModel: NavigationViewModel) {

View File

@@ -9,7 +9,7 @@ import kotlinx.coroutines.launch
class SettingsViewModel(private val repository: SettingsRepository) : ViewModel() {
val threedBuilding = repository.threedBuildingFlow.stateIn(
val show3D = repository.show3DFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
false
@@ -45,10 +45,21 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
0
)
fun onThreedBuildingChanged(enabled: Boolean) {
viewModelScope.launch { repository.setThreedBuilding(enabled) }
}
val lastRoute = repository.lastRouteFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
""
)
val tomTomApiKey = repository.tomTomApiKeyFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
""
)
fun onShow3DChanged(enabled: Boolean) {
viewModelScope.launch { repository.setShow3D(enabled) }
}
fun onDarkModeChanged(mode: Int) {
viewModelScope.launch { repository.setDarkMode(mode) }
@@ -69,4 +80,12 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
fun onRoutingEngineChanged(mode: Int) {
viewModelScope.launch { repository.setRoutingEngine(mode) }
}
fun onLastRouteChanged(route: String) {
viewModelScope.launch { repository.setLastRoute(route) }
}
fun onTomTomApiKeyChanged(route: String) {
viewModelScope.launch { repository.setTomTomApiKey(route) }
}
}

View File

@@ -6,9 +6,8 @@ import kotlinx.coroutines.flow.Flow
class SettingsRepository(
private val dataStoreManager: DataStoreManager
) {
val threedBuildingFlow: Flow<Boolean> =
dataStoreManager.threeDBuildingFlow
val show3DFlow: Flow<Boolean> =
dataStoreManager.show3DFlow
val darkModeFlow: Flow<Int> =
dataStoreManager.darkModeFlow
@@ -24,9 +23,14 @@ class SettingsRepository(
val routingEngineFlow: Flow<Int> =
dataStoreManager.routingEngineFlow
val lastRouteFlow: Flow<String> =
dataStoreManager.lastRouteFlow
suspend fun setThreedBuilding(enabled: Boolean) {
dataStoreManager.setThreedBuilding(enabled)
val tomTomApiKeyFlow: Flow<String> =
dataStoreManager.tomTomApiKeyFlow
suspend fun setShow3D(enabled: Boolean) {
dataStoreManager.setShow3D(enabled)
}
suspend fun setDarkMode(mode: Int) {
@@ -49,4 +53,12 @@ class SettingsRepository(
dataStoreManager.setRoutingEngine(mode)
}
suspend fun setLastRoute(route: String) {
dataStoreManager.setLastRoute(route)
}
suspend fun setTomTomApiKey(apiKey: String) {
dataStoreManager.setTomtomApiKey(apiKey)
}
}

View File

@@ -3,18 +3,11 @@ package com.kouros.navigation.utils
import android.content.Context
import android.location.Location
import android.location.LocationManager
import androidx.car.app.CarContext
import androidx.core.content.edit
import com.kouros.navigation.data.Constants.ROUTING_ENGINE
import com.kouros.navigation.data.Constants.SHARED_PREF_KEY
import com.kouros.navigation.data.RouteEngine
import com.kouros.navigation.data.datastore.DataStoreManager
import com.kouros.navigation.data.osrm.OsrmRepository
import com.kouros.navigation.data.tomtom.TomTomRepository
import com.kouros.navigation.data.valhalla.ValhallaRepository
import com.kouros.navigation.model.NavigationViewModel
import com.kouros.navigation.model.SettingsViewModel
import com.kouros.navigation.repository.SettingsRepository
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import java.time.LocalDateTime

View File

@@ -36,4 +36,5 @@
<string name="use_car_location">Use car location</string>
<string name="tomtom">TomTom\t</string>
<string name="options">Options</string>
<string name="tomtom_api_key">TomTom ApiKey</string>
</resources>