Audio guidance

This commit is contained in:
Dimitris
2026-03-04 15:50:21 +01:00
parent 11e9dbb21e
commit e582c1e0dc
37 changed files with 614 additions and 162 deletions

View File

@@ -13,8 +13,8 @@ android {
applicationId = "com.kouros.navigation"
minSdk = 33
targetSdk = 36
versionCode = 59
versionName = "0.2.0.59"
versionCode = 60
versionName = "0.2.0.60"
base.archivesName = "navi-$versionName"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

View File

@@ -6,6 +6,8 @@ import android.app.AppOpsManager
import android.location.LocationManager
import android.os.Bundle
import android.os.Process
import android.speech.tts.TextToSpeech
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@@ -81,13 +83,14 @@ import org.maplibre.compose.location.Location
import org.maplibre.compose.location.rememberDefaultLocationProvider
import org.maplibre.compose.location.rememberUserLocationState
import org.maplibre.spatialk.geojson.Position
import java.util.Locale
import kotlin.time.Duration.Companion.seconds
class MainActivity : ComponentActivity() {
val routeData = MutableLiveData("")
val routeModel = RouteModel()
var tilt = TILT
var tilt = TILT
val useMock = false
val type = SimulationType.SIMULATE
val stepData: MutableLiveData<StepData> by lazy {
@@ -97,29 +100,38 @@ class MainActivity : ComponentActivity() {
MutableLiveData()
}
var lastStepIndex = -1
var lastLocation = location(0.0, 0.0)
val observer = Observer<String> { newRoute ->
if (newRoute.isNotEmpty()) {
val repository = getSettingsRepository(applicationContext)
val routingEngine = runBlocking { repository.routingEngineFlow.first() }
val routingEngine = runBlocking { repository.routingEngineFlow.first() }
routeModel.navState = routeModel.navState.copy(routingEngine = routingEngine)
routeModel.startNavigation(newRoute)
if (routeModel.hasLegs()) {
getSettingsViewModel(applicationContext).onLastRouteChanged(newRoute)
}
routeData.value = routeModel.curRoute.routeGeoJson
if (useMock) {
when (type) {
SimulationType.SIMULATE -> simulate(routeModel, mock)
SimulationType.TEST -> test(applicationContext, routeModel)
SimulationType.GPX -> gpx(
context = applicationContext, mock
)
SimulationType.TEST_SINGLE -> testSingle(applicationContext, routeModel, mock)
}
checkMock()
}
}
lateinit var textToSpeech: TextToSpeech
private fun checkMock() {
if (useMock) {
when (type) {
SimulationType.SIMULATE -> simulate(routeModel, mock)
SimulationType.TEST -> test(applicationContext, routeModel)
SimulationType.GPX -> gpx(
context = applicationContext, mock
)
SimulationType.TEST_SINGLE -> testSingle(applicationContext, routeModel, mock)
}
}
}
val cameraPosition = MutableLiveData(
CameraPosition(
zoom = 15.0, target = Position(latitude = 48.1857475, longitude = 11.5793627)
@@ -135,6 +147,12 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
textToSpeech = TextToSpeech(applicationContext) { status ->
if (status == TextToSpeech.SUCCESS) {
textToSpeech.language = Locale.getDefault()
}
}
if (useMock) {
checkMockLocationEnabled()
}
@@ -195,8 +213,10 @@ class MainActivity : ComponentActivity() {
updateInterval = 0.5.seconds, desiredAccuracy = DesiredAccuracy.Highest
)
val userLocationState = rememberUserLocationState(locationProvider)
val locationState = locationProvider.location.collectAsState()
updateLocation(locationState.value)
if (!useMock) {
val locationState = locationProvider.location.collectAsState()
updateLocation(locationState.value)
}
val step: StepData? by stepData.observeAsState()
val nextStep: StepData? by nextStepData.observeAsState()
fun closeSheet() {
@@ -210,7 +230,7 @@ class MainActivity : ComponentActivity() {
snackbarHost = {
SnackbarHost(hostState = snackbarHostState)
},
scaffoldState = scaffoldState,
scaffoldState = scaffoldState,
sheetPeekHeight = sheetPeekHeightState.value,
sheetContent = {
SheetContent(step, nextStep) { closeSheet() }
@@ -317,8 +337,9 @@ class MainActivity : ComponentActivity() {
with(routeModel) {
if (isNavigating()) {
updateLocation( currentLocation, navigationViewModel)
updateLocation(currentLocation, navigationViewModel)
stepData.value = currentStep()
//textToSpeech(stepData.value!!.instruction)
if (navState.nextStep) {
nextStepData.value = nextStep()
}
@@ -353,7 +374,24 @@ class MainActivity : ComponentActivity() {
mock.setMockLocation(latitude, longitude, 0F)
}
routeData.value = ""
stepData.value = StepData("", "",0.0, 0, 0, 0, 0.0)
stepData.value = StepData("", "", 0.0, 0, 0, 0, 0.0)
}
fun textToSpeech(text: String) {
val currentStep = routeModel.route.currentStep()
val stepData = routeModel.currentStep()
if (currentStep.index > lastStepIndex && stepData.leftStepDistance < 50) {
lifecycleScope.launch {
try {
val cs: CharSequence = stepData.instruction
textToSpeech.speak(cs, TextToSpeech.QUEUE_FLUSH, null, "1233455")
Log.d("TTS", "speak $cs")
} catch (e: Throwable) {
Log.d("TTS", "speak error", e)
}
}
lastStepIndex = currentStep.index
}
}
fun simulateNavigation() {