Audio guidance
This commit is contained in:
@@ -179,9 +179,12 @@ class RouteModelTest {
|
||||
val curLocation = location(waypoint[0], waypoint[1])
|
||||
if (routeModel.isNavigating()) {
|
||||
if (index in 0..routeModel.curRoute.waypoints.size) {
|
||||
routeModel.updateLocation(curLocation, NavigationViewModel(TomTomRepository()))
|
||||
//runBlocking { delay(1000) }
|
||||
val start = System.currentTimeMillis()
|
||||
routeModel.updateLocation(curLocation, NavigationViewModel(TomTomRepository()))
|
||||
val stepData = routeModel.currentStep()
|
||||
val nextData = routeModel.nextStep()
|
||||
println("${stepData.instruction} ${System.currentTimeMillis() - start}")
|
||||
// val nextData = routeModel.nextStep()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.Manifest.permission
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.location.Location
|
||||
import android.speech.tts.TextToSpeech
|
||||
import android.util.Log
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.Screen
|
||||
@@ -16,9 +17,12 @@ import androidx.car.app.navigation.model.Trip
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelStore
|
||||
import androidx.lifecycle.ViewModelStoreOwner
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.kouros.navigation.car.navigation.NavigationUtils
|
||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||
import com.kouros.navigation.car.screen.NavigationScreen
|
||||
import com.kouros.navigation.car.screen.RequestPermissionScreen
|
||||
@@ -35,8 +39,11 @@ import com.kouros.navigation.data.valhalla.ValhallaRepository
|
||||
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 kotlinx.coroutines.awaitCancellation
|
||||
import kotlinx.coroutines.launch
|
||||
import org.maplibre.compose.expressions.dsl.step
|
||||
import java.util.Locale
|
||||
|
||||
|
||||
/**
|
||||
@@ -67,6 +74,8 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
|
||||
lateinit var navigationManager: NavigationManager
|
||||
|
||||
lateinit var textToSpeechManager: TextToSpeechManager
|
||||
|
||||
/**
|
||||
* Lifecycle observer for managing session lifecycle events.
|
||||
* Cleans up resources when the session is destroyed.
|
||||
@@ -82,6 +91,9 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
if (::deviceLocationManager.isInitialized) {
|
||||
deviceLocationManager.stopLocationUpdates()
|
||||
}
|
||||
if (::textToSpeechManager.isInitialized) {
|
||||
textToSpeechManager.cleanup()
|
||||
}
|
||||
Log.i(TAG, "NavigationSession destroyed")
|
||||
}
|
||||
}
|
||||
@@ -92,6 +104,10 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
// Store for ViewModels to survive configuration changes
|
||||
lateinit var viewModelStoreOwner: ViewModelStoreOwner
|
||||
|
||||
var lastStepIndex = -1
|
||||
|
||||
var guidanceAudio = 0
|
||||
|
||||
init {
|
||||
lifecycle.addObserver(lifecycleObserver)
|
||||
}
|
||||
@@ -130,6 +146,7 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
CarConnection.CONNECTION_TYPE_NATIVE -> {
|
||||
navigationScreen.checkPermission(AUTOMOTIVE_CAR_SPEED_PERMISSION)
|
||||
}
|
||||
|
||||
CarConnection.CONNECTION_TYPE_PROJECTION -> {
|
||||
navigationScreen.checkPermission(GMS_CAR_SPEED_PERMISSION)
|
||||
}
|
||||
@@ -221,6 +238,12 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
textToSpeechManager = TextToSpeechManager(carContext)
|
||||
val repository = getSettingsRepository(carContext)
|
||||
repository.guidanceAudioFlow.asLiveData().observe(this, Observer {
|
||||
guidanceAudio = it
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,7 +342,6 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
*/
|
||||
fun updateLocation(location: Location) {
|
||||
updateBearing(location)
|
||||
|
||||
if (routeModel.isNavigating()) {
|
||||
handleNavigationLocation(location)
|
||||
} else {
|
||||
@@ -341,6 +363,9 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
* Snaps location to route and checks for deviation requiring reroute.
|
||||
*/
|
||||
private fun handleNavigationLocation(location: Location) {
|
||||
if (guidanceAudio == 1) {
|
||||
handleGuidanceAudio()
|
||||
}
|
||||
navigationScreen.updateTrip(location)
|
||||
if (routeModel.navState.arrived) return
|
||||
val snappedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
||||
@@ -349,11 +374,9 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
distance > MAXIMAL_ROUTE_DEVIATION -> {
|
||||
navigationScreen.calculateNewRoute(routeModel.navState.destination)
|
||||
}
|
||||
|
||||
distance < MAXIMAL_SNAP_CORRECTION -> {
|
||||
surfaceRenderer.updateLocation(snappedLocation)
|
||||
}
|
||||
|
||||
else -> {
|
||||
surfaceRenderer.updateLocation(location)
|
||||
}
|
||||
@@ -382,6 +405,21 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
navigationManager.updateTrip(trip)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle guidance audio
|
||||
* Called when user wants to hear the step by step instructions
|
||||
*/
|
||||
private fun handleGuidanceAudio() {
|
||||
val currentStep = routeModel.route.currentStep()
|
||||
val stepData = routeModel.currentStep()
|
||||
if (currentStep.index > lastStepIndex && stepData.leftStepDistance < 50) {
|
||||
if (textToSpeechManager.initialized) {
|
||||
textToSpeechManager.speak(stepData.message)
|
||||
}
|
||||
lastStepIndex = currentStep.index
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// URI host for deep linking
|
||||
var uriHost: String = "navigation"
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.kouros.navigation.car
|
||||
|
||||
import android.media.AudioAttributes
|
||||
import android.media.AudioFocusRequest
|
||||
import android.media.AudioManager
|
||||
import android.speech.tts.TextToSpeech
|
||||
import android.util.Log
|
||||
import androidx.car.app.CarContext
|
||||
import java.util.Locale
|
||||
|
||||
class TextToSpeechManager(private val carContext: CarContext) {
|
||||
|
||||
var textToSpeech: TextToSpeech
|
||||
|
||||
var initialized = false
|
||||
|
||||
init {
|
||||
textToSpeech = TextToSpeech(carContext) { status ->
|
||||
if (status == TextToSpeech.SUCCESS) {
|
||||
Log.d("TTS", "Initialization Success")
|
||||
val audioAttributes =
|
||||
AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
|
||||
.build()
|
||||
val request =
|
||||
AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)
|
||||
.setAudioAttributes(audioAttributes)
|
||||
.build()
|
||||
val audioManager: AudioManager =
|
||||
carContext.getSystemService<AudioManager?>(AudioManager::class.java)!!
|
||||
// Requesting the audio focus.
|
||||
if (audioManager.requestAudioFocus(request) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
textToSpeech.setAudioAttributes(audioAttributes)
|
||||
}
|
||||
initialized = true
|
||||
} else {
|
||||
Log.d("TTS", "Initialization Failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun speak(text: String) {
|
||||
try {
|
||||
val cs: CharSequence = text
|
||||
textToSpeech.speak(cs, TextToSpeech.QUEUE_FLUSH, null, "1233455")
|
||||
} catch (e: Throwable) {
|
||||
Log.d("TTS", "speak error", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up manager.
|
||||
* Should be called when the session is destroyed.
|
||||
*/
|
||||
fun cleanup() {
|
||||
if (initialized) {
|
||||
textToSpeech.shutdown()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,27 @@
|
||||
package com.kouros.navigation.car.navigation
|
||||
|
||||
import android.media.AudioAttributes
|
||||
import android.media.AudioFocusRequest
|
||||
import android.media.AudioManager
|
||||
import android.media.MediaPlayer
|
||||
import android.media.MediaPlayer.OnCompletionListener
|
||||
import android.speech.tts.TextToSpeech
|
||||
import android.util.Log
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.RawRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.Alert
|
||||
import androidx.car.app.model.AlertCallback
|
||||
import androidx.car.app.model.CarIcon
|
||||
import androidx.car.app.model.CarText
|
||||
import androidx.car.app.model.OnClickListener
|
||||
import androidx.car.app.model.Row
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.kouros.android.cars.carappservice.R
|
||||
import com.kouros.navigation.data.Constants.TAG
|
||||
import java.io.IOException
|
||||
import java.util.Locale
|
||||
|
||||
class NavigationMessage (private var carContext: CarContext) {
|
||||
class NavigationUtils(private var carContext: CarContext) {
|
||||
|
||||
private fun createToastAction(
|
||||
@StringRes titleRes: Int, @StringRes toastStringRes: Int,
|
||||
@@ -35,6 +43,7 @@ class NavigationMessage (private var carContext: CarContext) {
|
||||
)
|
||||
.show()
|
||||
}
|
||||
|
||||
fun createCarText(@StringRes stringRes: Int): CarText {
|
||||
return CarText.create(carContext.getString(stringRes))
|
||||
}
|
||||
@@ -42,4 +51,19 @@ class NavigationMessage (private var carContext: CarContext) {
|
||||
fun createCarIcon(@DrawableRes iconRes: Int): CarIcon {
|
||||
return CarIcon.Builder(IconCompat.createWithResource(carContext, iconRes)).build()
|
||||
}
|
||||
|
||||
fun buildRowForTemplate(title: Int, resource: Int): Row {
|
||||
return Row.Builder()
|
||||
.setTitle(carContext.getString(title))
|
||||
.setImage(
|
||||
CarIcon.Builder(
|
||||
IconCompat.createWithResource(
|
||||
carContext,
|
||||
resource
|
||||
)
|
||||
)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.kouros.navigation.car.navigation
|
||||
|
||||
import android.speech.tts.TextToSpeech
|
||||
import android.text.SpannableString
|
||||
import android.util.Log
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.car.app.AppManager
|
||||
@@ -26,15 +28,18 @@ import com.kouros.data.R
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.utils.formattedDistance
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/** A class that provides models for the routing demos. */
|
||||
class RouteCarModel() : RouteModel() {
|
||||
class RouteCarModel : RouteModel() {
|
||||
|
||||
/** Returns the current [Step] with information such as the cue text and images. */
|
||||
fun currentStep(carContext: CarContext): Step {
|
||||
|
||||
val stepData = currentStep()
|
||||
|
||||
val currentStepCueWithImage: SpannableString =
|
||||
createString(stepData.instruction)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import androidx.car.app.navigation.model.MapWithContentTemplate
|
||||
import androidx.lifecycle.Observer
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.SurfaceRenderer
|
||||
import com.kouros.navigation.car.navigation.NavigationMessage
|
||||
import com.kouros.navigation.car.navigation.NavigationUtils
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.data.overpass.Elements
|
||||
@@ -124,7 +124,7 @@ class CategoryScreen(
|
||||
} else {
|
||||
row.addText(carText("${it.tags.openingHours}"))
|
||||
}
|
||||
val navigationMessage = NavigationMessage(carContext)
|
||||
val navigationUtils = NavigationUtils(carContext)
|
||||
row.addAction(
|
||||
Action.Builder()
|
||||
.setOnClickListener {
|
||||
@@ -144,7 +144,7 @@ class CategoryScreen(
|
||||
)
|
||||
finish()
|
||||
}
|
||||
.setIcon(navigationMessage.createCarIcon(R.drawable.navigation_48px))
|
||||
.setIcon(navigationUtils.createCarIcon(R.drawable.navigation_48px))
|
||||
.build())
|
||||
return row.build()
|
||||
}
|
||||
@@ -180,10 +180,10 @@ class CategoryScreen(
|
||||
@DrawableRes iconRes: Int,
|
||||
scale: Int
|
||||
): Action {
|
||||
val navigationMessage = NavigationMessage(carContext)
|
||||
val navigationUtils = NavigationUtils(carContext)
|
||||
return Action.Builder()
|
||||
.setOnClickListener { surfaceRenderer.handleScale(scale) }
|
||||
.setIcon(navigationMessage.createCarIcon(iconRes))
|
||||
.setIcon(navigationUtils.createCarIcon(iconRes))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.kouros.navigation.car.ViewStyle
|
||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||
import com.kouros.navigation.car.screen.observers.NavigationObserverCallback
|
||||
import com.kouros.navigation.car.screen.observers.NavigationObserverManager
|
||||
import com.kouros.navigation.car.screen.settings.SettingsScreen
|
||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.data.overpass.Elements
|
||||
|
||||
@@ -16,7 +16,6 @@ import androidx.car.app.model.Header
|
||||
import androidx.car.app.model.ItemList
|
||||
import androidx.car.app.model.ListTemplate
|
||||
import androidx.car.app.model.MessageTemplate
|
||||
import androidx.car.app.model.OnClickListener
|
||||
import androidx.car.app.model.Row
|
||||
import androidx.car.app.model.Template
|
||||
import androidx.car.app.navigation.model.MapController
|
||||
@@ -25,12 +24,11 @@ import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.SurfaceRenderer
|
||||
import com.kouros.navigation.car.navigation.NavigationMessage
|
||||
import com.kouros.navigation.car.navigation.NavigationUtils
|
||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
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.runBlocking
|
||||
@@ -49,7 +47,7 @@ class RoutePreviewScreen(
|
||||
|
||||
val routeModel = RouteCarModel()
|
||||
|
||||
val navigationMessage = NavigationMessage(carContext)
|
||||
val navigationUtils = NavigationUtils(carContext)
|
||||
val observer = Observer<String> { route ->
|
||||
if (route.isNotEmpty()) {
|
||||
val repository = getSettingsRepository(carContext)
|
||||
@@ -228,8 +226,6 @@ class RoutePreviewScreen(
|
||||
private fun onRouteSelected(index: Int) {
|
||||
routeModel.navState = routeModel.navState.copy(currentRouteIndex = index)
|
||||
surfaceRenderer.setPreviewRouteData(routeModel)
|
||||
//setResult(destination)
|
||||
//finish()
|
||||
}
|
||||
|
||||
fun getMapActionStrip(): ActionStrip {
|
||||
@@ -249,7 +245,7 @@ class RoutePreviewScreen(
|
||||
): Action {
|
||||
return Action.Builder()
|
||||
.setOnClickListener { surfaceRenderer.handleScale(-1) }
|
||||
.setIcon(navigationMessage.createCarIcon(iconRes))
|
||||
.setIcon(navigationUtils.createCarIcon(iconRes))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.kouros.navigation.car.screen.settings
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.CarIcon
|
||||
import androidx.car.app.model.Header
|
||||
import androidx.car.app.model.ItemList
|
||||
import androidx.car.app.model.ListTemplate
|
||||
import androidx.car.app.model.Row
|
||||
import androidx.car.app.model.SectionedItemList
|
||||
import androidx.car.app.model.Template
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.navigation.NavigationUtils
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class AudioSettings(
|
||||
private val carContext: CarContext,
|
||||
) :
|
||||
Screen(carContext) {
|
||||
|
||||
private var guidanceAudioSettings = 0
|
||||
|
||||
val settingsViewModel = getSettingsViewModel(carContext)
|
||||
|
||||
init {
|
||||
lifecycleScope.launch {
|
||||
settingsViewModel.guidanceAudio.first()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onGetTemplate(): Template {
|
||||
guidanceAudioSettings = settingsViewModel.guidanceAudio.value
|
||||
val templateBuilder = ListTemplate.Builder()
|
||||
val radioList =
|
||||
ItemList.Builder()
|
||||
.addItem(
|
||||
NavigationUtils(carContext).buildRowForTemplate(
|
||||
R.string.muted,
|
||||
R.drawable.volume_off_24px
|
||||
)
|
||||
)
|
||||
.addItem(
|
||||
NavigationUtils(carContext).buildRowForTemplate(
|
||||
R.string.unmuted,
|
||||
R.drawable.volume_up_24px,
|
||||
)
|
||||
)
|
||||
.addItem(
|
||||
NavigationUtils(carContext).buildRowForTemplate(
|
||||
R.string.alerts_only,
|
||||
R.drawable.warning_24px,
|
||||
)
|
||||
)
|
||||
.setOnSelectedListener { index: Int ->
|
||||
this.onSelected(index)
|
||||
}
|
||||
.setSelectedIndex(guidanceAudioSettings)
|
||||
.build()
|
||||
|
||||
return templateBuilder
|
||||
.addSectionedList(
|
||||
SectionedItemList.create(
|
||||
radioList,
|
||||
carContext.getString(R.string.audio_settings)
|
||||
)
|
||||
)
|
||||
.setHeader(
|
||||
Header.Builder()
|
||||
.setTitle(carContext.getString(R.string.audio_settings))
|
||||
.setStartHeaderAction(Action.BACK)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
||||
private fun onSelected(index: Int) {
|
||||
settingsViewModel.onGuidanceAudioChanged(index)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
package com.kouros.navigation.car.screen.settings
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.Header
|
||||
@@ -12,6 +11,7 @@ import androidx.car.app.model.SectionedItemList
|
||||
import androidx.car.app.model.Template
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.navigation.NavigationUtils
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -34,18 +34,21 @@ class DarkModeSettings(private val carContext: CarContext) : Screen(carContext)
|
||||
val radioList =
|
||||
ItemList.Builder()
|
||||
.addItem(
|
||||
buildRowForTemplate(
|
||||
NavigationUtils(carContext).buildRowForTemplate(
|
||||
R.string.off_action_title,
|
||||
R.drawable.light_mode_24px
|
||||
)
|
||||
)
|
||||
.addItem(
|
||||
buildRowForTemplate(
|
||||
NavigationUtils(carContext).buildRowForTemplate(
|
||||
R.string.on_action_title,
|
||||
R.drawable.dark_mode_24px
|
||||
)
|
||||
)
|
||||
.addItem(
|
||||
buildRowForTemplate(
|
||||
NavigationUtils(carContext).buildRowForTemplate(
|
||||
R.string.use_car_settings,
|
||||
R.drawable.directions_car_24px
|
||||
)
|
||||
)
|
||||
.setOnSelectedListener { index: Int ->
|
||||
@@ -74,11 +77,4 @@ class DarkModeSettings(private val carContext: CarContext) : Screen(carContext)
|
||||
private fun onSelected(index: Int) {
|
||||
settingsViewModel.onDarkModeChanged(index)
|
||||
}
|
||||
|
||||
private fun buildRowForTemplate(title: Int): Row {
|
||||
return Row.Builder()
|
||||
.setTitle(carContext.getString(title))
|
||||
.build()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
package com.kouros.navigation.car.screen.settings
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.Screen
|
||||
@@ -11,6 +11,7 @@ import androidx.car.app.model.Template
|
||||
import androidx.car.app.model.Toggle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.screen.settings.DistanceSettings
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
package com.kouros.navigation.car.screen.settings
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.Header
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
package com.kouros.navigation.car.screen.settings
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.Screen
|
||||
@@ -11,12 +11,13 @@ import androidx.car.app.model.Template
|
||||
import androidx.car.app.model.Toggle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.screen.settings.PasswordSettings
|
||||
import com.kouros.navigation.car.screen.settings.RoutingSettings
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class NavigationSettings(
|
||||
private val carContext: CarContext,
|
||||
private var navigationViewModel: NavigationViewModel
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
package com.kouros.navigation.car.screen.settings
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.Screen
|
||||
@@ -10,7 +10,6 @@ import androidx.car.app.model.signin.InputSignInMethod
|
||||
import androidx.car.app.model.signin.SignInTemplate
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
package com.kouros.navigation.car.screen.settings
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.Header
|
||||
@@ -56,7 +55,8 @@ class RoutingSettings(private val carContext: CarContext, private var navigation
|
||||
.build()
|
||||
|
||||
return templateBuilder
|
||||
.addSectionedList(SectionedItemList.create(
|
||||
.addSectionedList(
|
||||
SectionedItemList.create(
|
||||
radioList,
|
||||
carContext.getString(R.string.routing_engine)
|
||||
))
|
||||
@@ -1,19 +1,4 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.kouros.navigation.car.screen
|
||||
package com.kouros.navigation.car.screen.settings
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.Screen
|
||||
@@ -34,6 +19,12 @@ class SettingsScreen(
|
||||
|
||||
override fun onGetTemplate(): Template {
|
||||
val listBuilder = ItemList.Builder()
|
||||
listBuilder.addItem(
|
||||
buildRowForTemplate(
|
||||
AudioSettings(carContext),
|
||||
R.string.audio_settings
|
||||
)
|
||||
)
|
||||
listBuilder.addItem(
|
||||
buildRowForTemplate(
|
||||
DisplaySettings(carContext),
|
||||
@@ -67,4 +58,4 @@ class SettingsScreen(
|
||||
.setBrowsable(true)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user