This commit is contained in:
Dimitris
2025-12-04 08:10:03 +01:00
parent cddb193260
commit 9f53db8e76
29 changed files with 590 additions and 623 deletions

View File

@@ -32,7 +32,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<application android:requestLegacyExternalStorage="true">
<!--

View File

@@ -47,13 +47,10 @@ import org.maplibre.spatialk.geojson.Position
@Composable
fun cameraState(
width: Int,
height: Int,
padding : PaddingValues,
position: CameraPosition?,
tilt: Double,
preview: Boolean
): CameraState {
val padding = getPaddingValues(height, preview)
return rememberCameraState(
firstPosition =
CameraPosition(
@@ -117,20 +114,18 @@ fun BuildingLayer(tiles: Source) {
}
@Composable
fun DrawImage(width: Int, height: Int, location: Location, street: String) {
NavigationImage(height, street)
fun DrawImage(padding: PaddingValues, location: Location, width: Int, height: Int, street: String) {
NavigationImage(padding, street)
Speed(width, height, location)
}
@Composable
fun NavigationImage(height: Int, street: String) {
fun NavigationImage(padding: PaddingValues, street: String) {
val vector = ImageVector.vectorResource(id = R.drawable.assistant_navigation_48px)
val color = remember { NavigationColor }
BadgedBox(
modifier = Modifier
.padding(
start = 0.dp, top = distanceFromTop(height).dp
),
.padding(padding),
badge = {
Badge()
}
@@ -156,7 +151,7 @@ private fun Speed(
Box(
modifier = Modifier
.padding(
start = width.dp- 300.dp,
start = width.dp- 250.dp,
top = height.dp- 80.dp
),
contentAlignment = Alignment.Center
@@ -210,18 +205,17 @@ private fun Speed(
}
}
fun getPaddingValues(height: Int, preView: Boolean): PaddingValues {
val padding = PaddingValues(start = 0.dp, top = distanceFromTop(height).dp)
val prePadding = PaddingValues(start = 150.dp, bottom = 0.dp)
fun getPaddingValues(width: Int, height: Int, preView: Boolean): PaddingValues {
return if (preView) {
prePadding
PaddingValues(start = 150.dp, bottom = 0.dp)
} else {
padding
// PaddingValues(start = width.dp, top = distanceFromTop(height).dp)
PaddingValues(start = 0.dp, top = distanceFromTop(height).dp)
}
}
fun distanceFromTop(height: Int): Int {
return height - percent(height, 20)
return height - percent(height, 25)
}
fun percent(maxValue: Int, value: Int): Int {

View File

@@ -7,9 +7,7 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.car.app.CarContext
import androidx.car.app.Screen
import androidx.car.app.ScreenManager
@@ -27,13 +25,7 @@ import com.kouros.navigation.car.screen.SearchScreen
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.ObjectBox
import com.kouros.navigation.utils.NavigationUtils.snapLocation
import com.kouros.navigation.utils.location
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class NavigationSession : Session(), NavigationScreen.Listener {
val uriScheme = "samples";
@@ -46,16 +38,10 @@ class NavigationSession : Session(), NavigationScreen.Listener {
lateinit var surfaceRenderer: SurfaceRenderer
var locationIndex = 0
val simulate = false
var mLocationListener: LocationListenerCompat = LocationListenerCompat { location: Location? ->
updateLocation(location)
updateLocation(location!!)
}
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
private val mLifeCycleObserver: LifecycleObserver = object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
Log.i(TAG, "In onCreate()")
@@ -161,56 +147,24 @@ class NavigationSession : Session(), NavigationScreen.Listener {
val locationManager =
carContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
updateLocation(location)
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
/* minTimeMs= */ 500,
/* minDistanceM= */ 0f,
mLocationListener
)
}
fun updateLocation(location: Location?) {
if (location != null) {
if (simulate) {
simulate(location)
} else {
update(location)
}
updateLocation(location)
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
/* minTimeMs= */ 500,
/* minDistanceM= */ 0f,
mLocationListener
)
}
}
fun simulate(location: Location?) {
if (routeModel.isNavigating() && locationIndex < routeModel.route.waypoints.size) {
coroutineScope.launch {
if (locationIndex >= routeModel.route.waypoints.size) {
return@launch
}
val loc = routeModel.route.waypoints[locationIndex]
val curLocation = Location(LocationManager.GPS_PROVIDER)
curLocation.longitude = loc[0]// + 0.00001 * locationIndex
curLocation.latitude = loc[1] //+ 0.00001 * locationIndex
curLocation.speed = 15F
update(curLocation)
locationIndex += 1
if (locationIndex > routeModel.route.waypoints.size) {
val locationManager =
carContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.removeUpdates(mLocationListener)
}
}
} else {
update(location = location!!)
}
}
fun update(location: Location) {
fun updateLocation(location: Location) {
if (routeModel.isNavigating()) {
val snapedLocation = snapLocation(location, routeModel.route.maneuverLocations())
val distance = location.distanceTo(snapedLocation)
if (distance > MAXIMAL_ROUTE_DEVIATION) {
// navigationScreen.calculateNewRoute()
//return
navigationScreen.calculateNewRoute(routeModel.destination)
return
}
routeModel.updateLocation(location)
navigationScreen.updateTrip()

View File

@@ -6,13 +6,13 @@ import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.location.Location
import android.location.LocationManager
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.car.app.AppManager
import androidx.car.app.CarContext
import androidx.car.app.SurfaceCallback
import androidx.car.app.SurfaceContainer
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -54,7 +54,7 @@ class SurfaceRenderer(
)
)
var visibleArea = MutableLiveData(
Rect(0,0,0,0)
Rect(0, 0, 0, 0)
)
var stableArea = Rect()
@@ -162,16 +162,17 @@ class SurfaceRenderer(
@Composable
fun MapView() {
val stateWidth = visibleArea.observeAsState()
val position: CameraPosition? by cameraPosition.observeAsState()
val route: String? by routeData.observeAsState()
val previewRoute: String? by previewRouteData.observeAsState()
val cameraState = cameraState(width, height, position, tilt, preview)
val paddingValues = getPaddingValues( width - stateWidth.value!!.width(), height, preview)
val cameraState = cameraState(paddingValues, position, tilt)
val baseStyle = BaseStyle.Uri(Constants.STYLE)
// if (isSystemInDarkTheme()) BaseStyle.Uri(Constants.STYLE_DARK) else BaseStyle.Uri(
// Constants.STYLE
// )
if (isSystemInDarkTheme()) BaseStyle.Uri(Constants.STYLE_DARK) else BaseStyle.Uri(
Constants.STYLE
)
MaplibreMap(
cameraState = cameraState,
baseStyle = baseStyle,
@@ -184,11 +185,11 @@ class SurfaceRenderer(
}
//Puck(cameraState, lastLocation)
}
ShowPosition(cameraState, position)
ShowPosition(cameraState, position, paddingValues)
}
@Composable
fun ShowPosition(cameraState: CameraState, position: CameraPosition?) {
fun ShowPosition(cameraState: CameraState, position: CameraPosition?, paddingValues: PaddingValues) {
val cameraDuration = duration(position)
var bearing = position!!.bearing
var zoom = position.zoom
@@ -196,9 +197,9 @@ class SurfaceRenderer(
var localTilt = tilt
if (!preview) {
if (routeModel.isNavigating()) {
DrawImage(width, height, lastLocation, "")
DrawImage(paddingValues, lastLocation, width, height,"")
} else {
DrawImage(width, height, lastLocation, "")
DrawImage(paddingValues, lastLocation,width, height, "")
}
} else {
bearing = 0.0
@@ -213,7 +214,7 @@ class SurfaceRenderer(
zoom = zoom,
target = target,
tilt = localTilt,
padding = getPaddingValues(height, preview)
padding = paddingValues
),
duration = cameraDuration
)
@@ -259,16 +260,21 @@ class SurfaceRenderer(
fun updateLocation(location: Location) {
synchronized(this) {
if (!preview) {
var bearing = cameraPosition.value!!.bearing
if (routeModel.isNavigating()) {
bearing = routeModel.currentStep().bearing
val bearing = if (routeModel.isNavigating()) {
routeModel.currentStep().bearing
} else {
lastLocation.bearingTo(location).toInt().toDouble().absoluteValue
}
val zoom = if (!panView) {
calculateZoom(location.speed.toDouble())
} else {
cameraPosition.value!!.zoom
}
updateCameraPosition(bearing, zoom, Position(location.longitude, location.latitude))
updateCameraPosition(
bearing,
zoom,
Position(location.longitude, location.latitude)
)
lastBearing = cameraPosition.value!!.bearing
lastLocation = location
} else {
@@ -289,7 +295,7 @@ class SurfaceRenderer(
bearing = bearing,
zoom = zoom,
tilt = 0.0,
padding = getPaddingValues(height, preview),
padding = getPaddingValues(width-visibleArea.value!!.width(), height, preview),
target = target
)
)
@@ -315,9 +321,11 @@ class SurfaceRenderer(
in 0.0..10.0 -> {
return 13.0
}
in 10.0..20.0 -> {
return 11.0
}
in 20.0..30.0 -> {
return 10.0
}

View File

@@ -1,77 +0,0 @@
package com.kouros.navigation.car.navigation
import android.location.Location
import android.os.Environment
import org.xml.sax.SAXException
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.parsers.ParserConfigurationException
class Gpx {
fun loadGPX() {
val path = Environment.getExternalStorageDirectory()
.toString() + "/Download/VogelHohen.gpx"
var info = ""
val gpxFile = File(path)
info = info + gpxFile.path + "\n\n"
val gpxList = decodeGPX(gpxFile)
print(gpxList)
}
private fun decodeGPX(file: File): MutableList<Location?> {
val list: MutableList<Location?> = ArrayList()
val documentBuilderFactory = DocumentBuilderFactory.newInstance()
try {
val documentBuilder = documentBuilderFactory.newDocumentBuilder()
val fileInputStream = FileInputStream(file)
val document = documentBuilder.parse(fileInputStream)
val elementRoot = document.documentElement
val nodelist_trkpt = elementRoot.getElementsByTagName("trkpt")
for (i in 0..<nodelist_trkpt.getLength()) {
val node = nodelist_trkpt.item(i)
val attributes = node.getAttributes()
val newLatitude = attributes.getNamedItem("lat").getTextContent()
val newLatitude_double = newLatitude.toDouble()
val newLongitude = attributes.getNamedItem("lon").getTextContent()
val newLongitude_double = newLongitude.toDouble()
val newLocationName = newLatitude + ":" + newLongitude
val newLocation = Location(newLocationName)
newLocation.setLatitude(newLatitude_double)
newLocation.setLongitude(newLongitude_double)
list.add(newLocation)
}
fileInputStream.close()
} catch (e: ParserConfigurationException) {
// TODO Auto-generated catch block
e.printStackTrace()
} catch (e: FileNotFoundException) {
// TODO Auto-generated catch block
e.printStackTrace()
} catch (e: SAXException) {
// TODO Auto-generated catch block
e.printStackTrace()
} catch (e: IOException) {
// TODO Auto-generated catch block
e.printStackTrace()
}
return list
}
}

View File

@@ -15,37 +15,6 @@ import com.kouros.android.cars.carappservice.R
class NavigationMessage (private var carContext: CarContext) {
/** Returns a sample [Alert]. */
fun createAlert(): Alert {
val title: CarText = createCarText(R.string.navigation_alert_title)
val subtitle: CarText = createCarText(R.string.navigation_alert_subtitle)
val icon = CarIcon.ALERT
val yesAction: Action = createToastAction(
R.string.yes_action_title,
R.string.yes_action_toast_msg, Action.FLAG_PRIMARY
)
val noAction: Action = createToastAction(
R.string.no_action_title, R.string.no_action_toast_msg,
Action.FLAG_DEFAULT
)
return Alert.Builder( /* alertId: */0, title, /* durationMillis: */10000)
.setSubtitle(subtitle)
.setIcon(icon)
.addAction(yesAction)
.addAction(noAction).setCallback(object : AlertCallback {
override fun onCancel(reason: Int) {
if (reason == AlertCallback.REASON_TIMEOUT) {
showToast(R.string.alert_timeout_toast_msg)
}
}
override fun onDismiss() {
}
}).build()
}
private fun createToastAction(
@StringRes titleRes: Int, @StringRes toastStringRes: Int,
flags: Int

View File

@@ -214,7 +214,7 @@ class RouteCarModel() : RouteModel() {
.build()
}
private fun createString(
fun createString(
text: String
): SpannableString {
val spannableString = SpannableString(text)

View File

@@ -40,7 +40,7 @@ class DisplaySettings(private val carContext: CarContext) : Screen(carContext) {
.setSingleList(listBuilder.build())
.setHeader(
Header.Builder()
.setTitle(carContext.getString(R.string.content_limits))
.setTitle(carContext.getString(R.string.display_settings))
.setStartHeaderAction(Action.BACK)
.build()
)

View File

@@ -17,7 +17,6 @@ import androidx.car.app.model.Header
import androidx.car.app.model.MessageTemplate
import androidx.car.app.model.Template
import androidx.car.app.navigation.model.Maneuver
import androidx.car.app.navigation.model.MapController
import androidx.car.app.navigation.model.MapWithContentTemplate
import androidx.car.app.navigation.model.MessageInfo
import androidx.car.app.navigation.model.NavigationTemplate
@@ -86,18 +85,17 @@ class NavigationScreen(
override fun onGetTemplate(): Template {
val actionStripBuilder = createActionStripBuilder()
if (calculateNewRoute) {
return navigationRerouteTemplate(actionStripBuilder)
}
return if (routeModel.isNavigating()) {
if (calculateNewRoute) {
getNavigationLoadingTemplate(actionStripBuilder)
} else {
getNavigationTemplate(actionStripBuilder)
}
navigationTemplate(actionStripBuilder)
} else {
getNavigationEndTemplate(actionStripBuilder)
navigationEndTemplate(actionStripBuilder)
}
}
private fun getNavigationTemplate(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
private fun navigationTemplate(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
actionStripBuilder.addAction(
stopAction()
)
@@ -112,7 +110,7 @@ class NavigationScreen(
.build()
}
private fun getNavigationEndTemplate(actionStripBuilder: ActionStrip.Builder): Template {
private fun navigationEndTemplate(actionStripBuilder: ActionStrip.Builder): Template {
if (routeModel.isArrived()) {
val timer = object : CountDownTimer(10000, 10000) {
override fun onTick(millisUntilFinished: Long) {}
@@ -122,30 +120,10 @@ class NavigationScreen(
}
}
timer.start()
return NavigationTemplate.Builder()
.setNavigationInfo(
MessageInfo.Builder(
carContext.getString(R.string.arrived_exclamation_msg)
)
.setText(routeModel.destination.street!!)
.setImage(
CarIcon.Builder(
IconCompat.createWithResource(
carContext,
R.drawable.ic_place_white_24dp
)
)
.build()
)
.build()
)
.setBackgroundColor(CarColor.GREEN)
.setActionStrip(actionStripBuilder.build())
.setMapActionStrip(mapActionStripBuilder().build())
.build()
return navigationArrivedTemplate(actionStripBuilder)
} else {
return if (recentPlaceFound && recentPlaceActive) {
return getRecentPlaceTemplate()
return recentPlaceTemplate()
} else {
NavigationTemplate.Builder()
.setBackgroundColor(CarColor.SECONDARY)
@@ -156,7 +134,31 @@ class NavigationScreen(
}
}
fun getRecentPlaceTemplate(): Template {
fun navigationArrivedTemplate(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
return NavigationTemplate.Builder()
.setNavigationInfo(
MessageInfo.Builder(
carContext.getString(R.string.arrived_exclamation_msg)
)
.setText(routeModel.destination.street!!)
.setImage(
CarIcon.Builder(
IconCompat.createWithResource(
carContext,
R.drawable.ic_place_white_24dp
)
)
.build()
)
.build()
)
.setBackgroundColor(CarColor.GREEN)
.setActionStrip(actionStripBuilder.build())
.setMapActionStrip(mapActionStripBuilder().build())
.build()
}
fun recentPlaceTemplate(): Template {
val messageTemplate = MessageTemplate.Builder(
recentPlace.name + "\n"
+ recentPlace.city
@@ -181,11 +183,27 @@ class NavigationScreen(
return builder.build()
}
fun getNavigationLoadingTemplate(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
fun navigationRerouteTemplate(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
return NavigationTemplate.Builder()
.setNavigationInfo(RoutingInfo.Builder().setLoading(true).build())
.setActionStrip(actionStripBuilder.build())
.setNavigationInfo(
MessageInfo.Builder(
carContext.getString(R.string.new_route)
)
.setText(routeModel.destination.street.toString())
.setImage(
CarIcon.Builder(
IconCompat.createWithResource(
carContext,
R.drawable.navigation_48px
)
)
.build()
)
.build()
)
.setBackgroundColor(CarColor.SECONDARY)
.setActionStrip(actionStripBuilder.build())
.setMapActionStrip(mapActionStripBuilder().build())
.build()
}
@@ -271,7 +289,7 @@ class NavigationScreen(
)
.setOnClickListener {
val navigateTo = location(recentPlace.latitude, recentPlace.longitude)
viewModel.loadRoute(surfaceRenderer.lastLocation, navigateTo)
viewModel.loadRoute(carContext, surfaceRenderer.lastLocation, navigateTo)
routeModel.destination = recentPlace
}
.build()
@@ -394,7 +412,7 @@ class NavigationScreen(
location.latitude = place.latitude
location.longitude = place.longitude
viewModel.saveRecent(place)
viewModel.loadRoute(surfaceRenderer.lastLocation, location)
viewModel.loadRoute(carContext, surfaceRenderer.lastLocation, location)
currentNavigationLocation = location
routeModel.destination = place
invalidate()
@@ -408,24 +426,25 @@ class NavigationScreen(
invalidate()
}
fun calculateNewRoute() {
fun calculateNewRoute(destination: Place) {
calculateNewRoute = true
stopNavigation()
invalidate()
val mainThreadhandler = Handler(carContext.mainLooper)
mainThreadhandler.post {
val mainThreadHandler = Handler(carContext.mainLooper)
mainThreadHandler.post {
object : CountDownTimer(5000, 1000) {
override fun onTick(millisUntilFinished: Long) {}
override fun onFinish() {
calculateNewRoute = false
stopNavigation()
reRoute(destination)
}
}.start()
}
}
fun reRoute() {
NavigationMessage(carContext).createAlert()
viewModel.loadRoute(surfaceRenderer.lastLocation, currentNavigationLocation)
fun reRoute(destination: Place) {
val dest = location(destination.latitude, destination.longitude)
viewModel.loadRoute(carContext, surfaceRenderer.lastLocation, dest)
}
fun updateTrip() {

View File

@@ -1,9 +1,7 @@
package com.kouros.navigation.car.screen
import androidx.car.app.CarContext
import androidx.car.app.CarToast
import androidx.car.app.Screen
import androidx.car.app.constraints.ConstraintManager
import androidx.car.app.model.Action
import androidx.car.app.model.Header
import androidx.car.app.model.ItemList
@@ -11,48 +9,65 @@ import androidx.car.app.model.ListTemplate
import androidx.car.app.model.Row
import androidx.car.app.model.Template
import androidx.car.app.model.Toggle
import androidx.lifecycle.DefaultLifecycleObserver
import com.kouros.android.cars.carappservice.R
import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING
import com.kouros.navigation.data.Constants.AVOID_MOTORWAY
import com.kouros.navigation.data.Constants.AVOID_TOLLWAY
import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue
import com.kouros.navigation.utils.NavigationUtils.setBooleanKeyValue
class NavigationSettings(private val carContext: CarContext) : Screen(carContext) {
private var motorWayToggleState = false
private var tollWayToggleState = false
init {
motorWayToggleState = getBooleanKeyValue(carContext, AVOID_MOTORWAY)
tollWayToggleState = getBooleanKeyValue(carContext, AVOID_MOTORWAY)
}
override fun onGetTemplate(): Template {
val listBuilder = ItemList.Builder()
val highwayToggle: Toggle =
Toggle.Builder { checked: Boolean ->
if (checked) {
setBooleanKeyValue(carContext, true, AVOID_MOTORWAY)
} else {
setBooleanKeyValue(carContext, false, AVOID_MOTORWAY)
}
motorWayToggleState = !motorWayToggleState
}.setChecked(motorWayToggleState).build()
listBuilder.addItem(buildRowForTemplate(R.string.avoid_highways_row_title, highwayToggle))
listBuilder.addItem(
buildRowForTemplate(
R.string.list_limit,
ConstraintManager.CONTENT_LIMIT_TYPE_LIST
)
)
// Tollway
val tollwayToggle: Toggle =
Toggle.Builder { checked: Boolean ->
if (checked) {
setBooleanKeyValue(carContext, true, AVOID_TOLLWAY)
} else {
setBooleanKeyValue(carContext, false, AVOID_TOLLWAY)
}
tollWayToggleState = !tollWayToggleState
}.setChecked(tollWayToggleState).build()
listBuilder.addItem(buildRowForTemplate(R.string.avoid_tolls_row_title, tollwayToggle))
return ListTemplate.Builder()
.setSingleList(listBuilder.build())
.setHeader(
Header.Builder()
.setTitle(carContext.getString(R.string.content_limits))
.setTitle(carContext.getString(R.string.display_settings))
.setStartHeaderAction(Action.BACK)
.build()
)
.build()
}
private fun buildRowForTemplate(title: Int, contentLimitType: Int): Row {
private fun buildRowForTemplate(title: Int, toggle: Toggle): Row {
return Row.Builder()
.setTitle(carContext.getString(title))
.addText(
carContext
.getCarService(ConstraintManager::class.java)
.getContentLimit(contentLimitType).toString()
)
.setToggle(toggle)
.build()
}
}

View File

@@ -53,7 +53,7 @@ class PlaceListScreen(
init {
if (category == Constants.RECENT) {
viewModel.places.observe(this, observer)
viewModel.loadPlaces(location)
viewModel.loadPlaces(carContext, location)
}
if (category == Constants.CONTACTS) {
viewModel.contactAddress.observe(this, observerAddress)

View File

@@ -26,7 +26,7 @@ class RequestPermissionScreen(
override fun onGetTemplate(): Template {
val permissions: MutableList<String?> = ArrayList()
permissions.add(permission.ACCESS_FINE_LOCATION)
permissions.add(permission.READ_CONTACTS)
//permissions.add(permission.READ_CONTACTS)
val message = "This app needs access to location in order to show the map around you"

View File

@@ -77,7 +77,7 @@ class RoutePreviewScreen(
val location = Location(LocationManager.GPS_PROVIDER)
location.latitude = destination.latitude
location.longitude = destination.longitude
vieModel.loadPreviewRoute(surfaceRenderer.lastLocation, location)
vieModel.loadPreviewRoute(carContext,surfaceRenderer.lastLocation, location)
}
override fun onGetTemplate(): Template {

View File

@@ -41,8 +41,6 @@
<string name="sign_out_action_title" msgid="1653943000866713010">"Abmelden"</string>
<string name="yes_action_title" msgid="5507096013762092189">"Ja"</string>
<string name="no_action_title" msgid="1452124604210014010">"Nein"</string>
<string name="disable_all_rows" msgid="3003225080532928046">"Alle Zeilen deaktivieren"</string>
<string name="enable_all_rows" msgid="7274285275711872091">"Alle Zeilen aktivieren"</string>
<string name="zoomed_in_toast_msg" msgid="8915301497303842649">"Herangezoomt"</string>
<string name="zoomed_out_toast_msg" msgid="6260981223227212493">"Herausgezoomt"</string>
<string name="triggered_toast_msg" msgid="3396166539208366382">"Ausgelöst"</string>
@@ -55,59 +53,13 @@
<string name="parked_toast_msg" msgid="2532422265890824446">"Aktion „Geparkt“"</string>
<string name="more_toast_msg" msgid="5938288138225509885">"„Mehr“ angeklickt"</string>
<string name="grant_location_permission_toast_msg" msgid="268046297444808010">"Standortermittlung erlauben, um aktuellen Standort anzuzeigen"</string>
<string name="sign_in_with_google_toast_msg" msgid="5720947549233124775">"Über Google anmelden beginnt hier"</string>
<string name="changes_selection_to_index_toast_msg_prefix" msgid="957766225794389167">"Auswahl auf Index geändert"</string>
<string name="yes_action_toast_msg" msgid="6216215197177241247">"Schaltfläche „Ja“ gedrückt."</string>
<string name="no_action_toast_msg" msgid="6165492423831023809">"Schaltfläche „Nein“ gedrückt."</string>
<string name="alert_timeout_toast_msg" msgid="5568380708832805374">"Zeitüberschreitung bei Benachrichtigung."</string>
<string name="first_row_title" msgid="219428344573165351">"Zeile mit großem Bild und langem Text langem Text langem Text langem Text langem Text"</string>
<string name="first_row_text" msgid="3887390298628338716">"Text Text Text"</string>
<string name="other_row_title_prefix" msgid="4702355788835253197">"Zeilentitel"</string>
<string name="other_row_text" msgid="7510279447493169945">"Zeilentext"</string>
<string name="navigate" msgid="2713090390373996139">"Navigieren"</string>
<string name="dial" msgid="3145707439707628311">"Wählen"</string>
<string name="address" msgid="9010635942573581302">"Adresse"</string>
<string name="phone" msgid="2504766809811627577">"Smartphone"</string>
<string name="fail_start_nav" msgid="6921321606009212189">"Fehler beim Starten der Navigation"</string>
<string name="fail_start_dialer" msgid="1471602619507306261">"Fehler beim Starten des Telefons"</string>
<string name="car_hardware_demo_title" msgid="3679106197233262689">"Demo der Auto-Hardware"</string>
<string name="car_hardware_info" msgid="1244783247616395012">"Informationen zur Auto-Hardware"</string>
<string name="model_info" msgid="494224423025683030">"Modellinformationen"</string>
<string name="manufacturer_unavailable" msgid="4978995415869838056">"Hersteller nicht verfügbar"</string>
<string name="model_unavailable" msgid="4075463010215406573">"Modell nicht verfügbar"</string>
<string name="year_unavailable" msgid="994338773299644607">"Jahr nicht verfügbar"</string>
<string name="energy_profile" msgid="81415433590192158">"Energieprofil"</string>
<string name="no_energy_profile_permission" msgid="4662285713731308888">"Keine Berechtigung für Energieprofil"</string>
<string name="fuel_types" msgid="6811375173343218212">"Kraftstofftypen"</string>
<string name="unavailable" msgid="3636401138255192934">"Nicht verfügbar"</string>
<string name="ev_connector_types" msgid="735458637011996125">"Elektrofahrzeug-Anschlusssteckertypen"</string>
<string name="example_title" msgid="530257630320010494">"Beispiel: %d"</string>
<string name="example_1_text" msgid="8631503055894800688">"Dieser Text ist "<annotation color="red">"rot"</annotation></string>
<string name="example_2_text" msgid="1359373957397219102">"Dieser Text ist "<annotation color="green">"grün"</annotation></string>
<string name="example_3_text" msgid="2409207170762049673">"Dieser Text ist "<annotation color="blue">"blau"</annotation></string>
<string name="example_4_text" msgid="9055989886645433000">"Dieser Text ist "<annotation color="yellow">"gelb"</annotation></string>
<string name="example_5_text" msgid="8828804968749423500">"Für diesen Text wird die Primärfarbe verwendet"</string>
<string name="example_6_text" msgid="7991523168517599600">"Dieser Text verwendet die Sekundärfarbe"</string>
<string name="color_demo" msgid="1822427636476178993">"Farbdemo"</string>
<string name="list_limit" msgid="3023536401535417286">"Listenbeschränkung"</string>
<string name="grid_limit" msgid="1350116012893549206">"Rasterbegrenzung"</string>
<string name="pane_limit" msgid="981518409516855230">"Bereichsbegrenzung"</string>
<string name="place_list_limit" msgid="6785181191763056582">"Limit für Ortsliste"</string>
<string name="route_list_limit" msgid="505793441615134116">"Limit für Routenliste"</string>
<string name="content_limits" msgid="5726880972110281095">"Beschränkungen für Inhalte"</string>
<string name="content_limits_demo_title" msgid="3207211638386727610">"Demo für „Beschränkungen für Inhalte“"</string>
<string name="finish_app_msg" msgid="8354334557053141891">"Dadurch wird die App geschlossen und beim nächsten Ausführen eine Berechtigungsanfrage eingeblendet"</string>
<string name="finish_app_title" msgid="9013328479438745074">"App-Demo beenden"</string>
<string name="finish_app_demo_title" msgid="8223819062053448384">"Beim nächsten Ausführen der Demo Berechtigungsbildschirm voranstellen"</string>
<string name="preseed_permission_app_title" msgid="182847662545676962">"Beim nächsten Ausführen Demo zu App-Berechtigungen voranstellen"</string>
<string name="preseed_permission_demo_title" msgid="5476541421753978071">"Beim nächsten Ausführen der Demo Berechtigungsbildschirm voranstellen"</string>
<string name="loading_demo_title" msgid="1086529475809143517">"Demo wird geladen"</string>
<string name="loading_demo_row_title" msgid="8933049915126088142">"Ladevorgang abgeschlossen!"</string>
<string name="pop_to_root" msgid="2078277386355064198">"Zu Stammverzeichnis wechseln"</string>
<string name="pop_to_marker" msgid="5007078308762725207">"Zur Markierung für verschiedene Demos wechseln"</string>
<string name="push_stack" msgid="2433062141810168976">"Weiter in Stack verschieben"</string>
<string name="pop_to_prefix" msgid="4288884615669751608">"Wechseln zu"</string>
<string name="pop_to_title" msgid="3924696281273379455">"Demo für „Wechseln zu“"</string>
<string name="display_settings" msgid="5726880972110281095">"Einstellungen für die Anzeige"</string>
<string name="package_not_found_error_msg" msgid="7525619456883627939">"Paket wurde nicht gefunden."</string>
<string name="permissions_granted_msg" msgid="2348556088141992714">"Alle Berechtigungen wurden erteilt. Du kannst sie in den Einstellungen deaktivieren."</string>
<string name="needs_access_msg_prefix" msgid="2204136858798832382">"Die App benötigt Zugriff auf die folgenden Berechtigungen:\n"</string>
@@ -154,7 +106,8 @@
<string name="long_route" msgid="4737969235741057506">"Lange Route"</string>
<string name="continue_start_nav" msgid="6231797535084469163">"Weiter, um die Navigation zu starten"</string>
<string name="continue_route" msgid="5172258139245088080">"Weiter zur Route"</string>
<string name="routes_title" msgid="7799772149932075357">"Routen"</string>
<string name="routes_title" msgid="7799772149932075357">"Route"</string>
<string name="new_route">Neue Route Berechnung</string>
<string name="place_list_nav_template_demo_title" msgid="8019588508812955290">"Demo der Navigationsvorlage für Ortslisten"</string>
<string name="route_preview_template_demo_title" msgid="7878704357953167555">"Demo der Routenvorschauvorlage"</string>
<string name="notification_template_demo_title" msgid="5076051497316030274">"Demo der Benachrichtigungsvorlage"</string>
@@ -355,7 +308,7 @@
<string name="map_template_toggle_demo_title" msgid="6510798293640092611">"Kartenvorlage mit Ein-/Aus-Schaltflächen"</string>
<string name="avoid_tolls_row_title" msgid="5194057244144831024">"Mautstraßen vermeiden"</string>
<string name="route_options_demo_title" msgid="4599699012716426514">"Routenoptionen"</string>
<string name="avoid_highways_row_title" msgid="4711913426200490304">"Autobahnen vermeiden"</string>
<string name="avoid_highways_row_title" msgid="4711913426200490304">"Autobahnen meiden"</string>
<string name="avoid_ferries_row_title" msgid="8232883866013711974">"Fähren vermeiden"</string>
<string name="map_demos_title" msgid="2169766615521476592">"Kartenbezogene Demos"</string>
<string name="map_with_content_demo_title" msgid="1032610482145018739">"Demos von Karten mit Inhalten"</string>

View File

@@ -41,8 +41,6 @@
<string name="sign_out_action_title">Sign out</string>
<string name="yes_action_title">Yes</string>
<string name="no_action_title">No</string>
<string name="disable_all_rows">Disable All Rows</string>
<string name="enable_all_rows">Enable All Rows</string>
<!-- Toast Messages -->
<string name="zoomed_in_toast_msg">Zoomed in</string>
@@ -57,17 +55,8 @@
<string name="parked_toast_msg">Parked action</string>
<string name="more_toast_msg">Clicked More</string>
<string name="grant_location_permission_toast_msg">Grant location Permission to see current location</string>
<string name="sign_in_with_google_toast_msg">Sign-in with Google starts here</string>
<string name="changes_selection_to_index_toast_msg_prefix">Changed selection to index</string>
<string name="yes_action_toast_msg">Yes button pressed!</string>
<string name="no_action_toast_msg">No button pressed!</string>
<string name="alert_timeout_toast_msg">Alert is timed out!</string>
<!-- Row text -->
<string name="first_row_title">Row with a large image and long text long text long text long text long text</string>
<string name="first_row_text">Text text text</string>
<string name="other_row_title_prefix">Row title </string>
<string name="other_row_text">Row text</string>
<!-- Place Details Screen -->
<string name="navigate">Navigate</string>
@@ -78,56 +67,8 @@
<!-- CarHardwareDemoScreen -->
<string name="fail_start_nav">Failure starting navigation</string>
<string name="fail_start_dialer">Failure starting dialer</string>
<string name="car_hardware_demo_title">Car Hardware Demo</string>
<!-- CarHardwareInfoScreen -->
<string name="car_hardware_info">Car Hardware Information</string>
<string name="model_info">Model Information</string>
<string name="manufacturer_unavailable">Manufacturer unavailable</string>
<string name="model_unavailable">Model unavailable</string>
<string name="year_unavailable">Year unavailable</string>
<string name="energy_profile">Energy Profile</string>
<string name="no_energy_profile_permission">No Energy Profile Permission</string>
<string name="fuel_types">Fuel Types</string>
<string name="unavailable">Unavailable</string>
<string name="ev_connector_types">EV Connector Types</string>
<!-- ColorDemoScreen -->
<string name="example_title">Example %d</string>
<string name="example_1_text">This text has a <annotation color="red">red</annotation> color</string>
<string name="example_2_text">This text has a <annotation color="green">green</annotation> color</string>
<string name="example_3_text">This text has a <annotation color="blue">blue</annotation> color</string>
<string name="example_4_text">This text has a <annotation color="yellow">yellow</annotation> color</string>
<string name="example_5_text">This text uses the primary color</string>
<string name="example_6_text">This text uses the secondary color</string>
<string name="color_demo">Color Demo</string>
<!-- ContentLimitsDemoScreen -->
<string name="list_limit">List Limit</string>
<string name="grid_limit">Grid Limit</string>
<string name="pane_limit">Pane Limit</string>
<string name="place_list_limit">Place List Limit</string>
<string name="route_list_limit">Route List Limit</string>
<string name="content_limits">Content Limits</string>
<string name="content_limits_demo_title">Content Limits Demo</string>
<!-- FinishAppScreen -->
<string name="finish_app_msg">This will finish the app, and when you return it will pre-seed a permission screen</string>
<string name="finish_app_title">Finish App Demo</string>
<string name="finish_app_demo_title">Pre-seed the Permission Screen on next run Demo</string>
<string name="preseed_permission_app_title">Pre-seed permission App Demo</string>
<string name="preseed_permission_demo_title">Pre-seed the Permission Screen on next run Demo</string>
<!-- LoadingDemoScreen -->
<string name="loading_demo_title">Loading Demo</string>
<string name="loading_demo_row_title">Loading Complete!</string>
<!-- PopToDemoScreen -->
<string name="pop_to_root">Pop to root</string>
<string name="pop_to_marker">Pop to Misc Demo Marker</string>
<string name="push_stack">Push further in stack</string>
<string name="pop_to_prefix">Pop To </string>
<string name="pop_to_title">PopTo Demo</string>
<string name="display_settings">Display settings</string>
<!-- RequestPermissionScreen -->
<string name="package_not_found_error_msg">Package Not found.</string>
@@ -193,7 +134,6 @@
<string name="take_520">Take 520</string>
<string name="gas_station">Gas Station</string>
<!-- RoutePreviewDemoScreen -->
<string name="short_route">Short route</string>
<string name="less_busy">Less busy</string>
<string name="hov_friendly">HOV friendly</string>
@@ -201,6 +141,7 @@
<string name="continue_start_nav">Continue to start navigation</string>
<string name="continue_route">Continue to route</string>
<string name="routes_title">Routes</string>
<string name="new_route">New Route calculation</string>
<!-- NavigationDemosScreen -->
<string name="place_list_nav_template_demo_title">Place List Navigation Template Demo</string>