Cluster
This commit is contained in:
@@ -137,7 +137,7 @@ class CarSensorManager(
|
||||
carCompassListener
|
||||
)
|
||||
carSensors.addCarHardwareLocationListener(
|
||||
CarSensors.UPDATE_RATE_NORMAL,
|
||||
CarSensors.UPDATE_RATE_FASTEST,
|
||||
carContext.mainExecutor,
|
||||
carLocationListener
|
||||
)
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.util.Log
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.Session
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.CarIcon
|
||||
import androidx.car.app.model.OnClickListener
|
||||
import androidx.car.app.navigation.model.Trip
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.lifecycle.ViewModelStore
|
||||
import androidx.lifecycle.ViewModelStoreOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.navigation.NavigationService
|
||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||
import com.kouros.navigation.car.screen.NavigationListener
|
||||
import com.kouros.navigation.car.screen.NavigationScreen
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/** Session class for the Navigation sample app. */
|
||||
internal class ClusterSession : Session(), NavigationListener {
|
||||
var mNavigationScreen: NavigationScreen? = null
|
||||
|
||||
var mNavigationCarSurface: SurfaceRenderer? = null
|
||||
|
||||
// A reference to the navigation service used to get location updates and routing.
|
||||
var service: NavigationService? = null
|
||||
|
||||
var mSettingsAction: Action? = null
|
||||
|
||||
var routeModel = RouteCarModel()
|
||||
|
||||
lateinit var viewModelStoreOwner: ViewModelStoreOwner
|
||||
|
||||
override fun onCreateScreen(intent: Intent): Screen {
|
||||
Log.i(TAG, "In onCreateScreen()")
|
||||
|
||||
setupViewModelStore()
|
||||
mSettingsAction =
|
||||
Action.Builder()
|
||||
.setIcon(
|
||||
CarIcon.Builder(
|
||||
IconCompat.createWithResource(
|
||||
carContext, R.drawable.alt_route_48px
|
||||
)
|
||||
)
|
||||
.build()
|
||||
)
|
||||
.setOnClickListener(
|
||||
OnClickListener {})
|
||||
.build()
|
||||
|
||||
mNavigationCarSurface = SurfaceRenderer(carContext, lifecycle, routeModel, viewModelStoreOwner)
|
||||
|
||||
// mNavigationScreen =
|
||||
// new NavigationScreen(getCarContext(), mSettingsAction, this, mNavigationCarSurface);
|
||||
val action = intent.action
|
||||
if (CarContext.ACTION_NAVIGATE == action) {
|
||||
CarToast.makeText(
|
||||
carContext,
|
||||
"Navigation intent: " + intent.dataString,
|
||||
CarToast.LENGTH_LONG
|
||||
)
|
||||
.show()
|
||||
}
|
||||
|
||||
return mNavigationScreen!!
|
||||
}
|
||||
|
||||
override fun onCarConfigurationChanged(newConfiguration: Configuration) {
|
||||
// mNavigationCarSurface.onCarConfigurationChanged();
|
||||
}
|
||||
|
||||
|
||||
override fun stopNavigation() {
|
||||
if (service != null) {
|
||||
service!!.stopNavigation()
|
||||
}
|
||||
}
|
||||
|
||||
override fun startNavigation() {
|
||||
}
|
||||
|
||||
override fun updateTrip(trip: Trip) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG: String = ClusterSession::class.java.getSimpleName()
|
||||
}
|
||||
|
||||
private fun setupViewModelStore() {
|
||||
viewModelStoreOwner = object : ViewModelStoreOwner {
|
||||
override val viewModelStore = ViewModelStore()
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
awaitCancellation()
|
||||
} finally {
|
||||
viewModelStoreOwner.viewModelStore.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.kouros.navigation.car
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.car.app.CarAppService
|
||||
import androidx.car.app.Session
|
||||
import androidx.car.app.SessionInfo
|
||||
import androidx.car.app.validation.HostValidator
|
||||
import com.kouros.navigation.data.Constants.TAG
|
||||
|
||||
|
||||
class NavigationCarAppService : CarAppService() {
|
||||
@@ -13,6 +17,7 @@ class NavigationCarAppService : CarAppService() {
|
||||
val INTENT_ACTION_NAV_NOTIFICATION_OPEN_APP =
|
||||
"com.kouros.navigation.INTENT_ACTION_NAV_NOTIFICATION_OPEN_APP"
|
||||
|
||||
val channelId: String = "NavigationSessionChannel"
|
||||
|
||||
fun createDeepLinkUri(deepLinkAction: String): Uri {
|
||||
return Uri.fromParts(NavigationSession.uriScheme, NavigationSession.uriHost, deepLinkAction)
|
||||
@@ -26,7 +31,26 @@ class NavigationCarAppService : CarAppService() {
|
||||
}
|
||||
|
||||
override fun onCreateSession(sessionInfo: SessionInfo): Session {
|
||||
return NavigationSession()
|
||||
Log.d(TAG, "Display Type: ${sessionInfo.displayType}")
|
||||
if (sessionInfo.displayType == SessionInfo.DISPLAY_TYPE_CLUSTER) {
|
||||
return ClusterSession()
|
||||
} else {
|
||||
createNotificationChannel()
|
||||
return NavigationSession()
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNotificationChannel() {
|
||||
val notificationManager =
|
||||
getSystemService(NotificationManager::class.java)
|
||||
val name: CharSequence = "Car App Service"
|
||||
val serviceChannel =
|
||||
NotificationChannel(
|
||||
channelId,
|
||||
name,
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
)
|
||||
notificationManager.createNotificationChannel(serviceChannel)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,27 @@
|
||||
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
|
||||
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
|
||||
@@ -22,6 +32,7 @@ import androidx.lifecycle.ViewModelStoreOwner
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.kouros.navigation.car.navigation.NavigationService
|
||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||
import com.kouros.navigation.car.navigation.Simulation
|
||||
import com.kouros.navigation.car.screen.NavigationListener
|
||||
@@ -36,7 +47,6 @@ import com.kouros.navigation.data.Constants.INSTRUCTION_DISTANCE
|
||||
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.Place
|
||||
import com.kouros.navigation.data.RouteEngine
|
||||
import com.kouros.navigation.data.ViewStyle
|
||||
import com.kouros.navigation.data.osrm.OsrmRepository
|
||||
@@ -47,9 +57,7 @@ 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.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
|
||||
@@ -90,11 +98,64 @@ class NavigationSession : Session(), NavigationListener {
|
||||
|
||||
var navigationManagerStarted = false
|
||||
|
||||
var navigationService : NavigationService? = null
|
||||
|
||||
|
||||
val serviceListener : NavigationService.Listener = object : NavigationService.Listener {
|
||||
override fun navigationStateChanged(
|
||||
isNavigating: Boolean,
|
||||
isRerouting: Boolean,
|
||||
hasArrived: Boolean,
|
||||
destinations: MutableList<Destination?>?,
|
||||
steps: MutableList<Step>?,
|
||||
nextDestinationTravelEstimate: TravelEstimate?,
|
||||
nextStepRemainingDistance: Distance?,
|
||||
shouldShowNextStep: Boolean,
|
||||
shouldShowLanes: Boolean,
|
||||
junctionImage: CarIcon?
|
||||
) {
|
||||
//navigationScreen.updateTrip()
|
||||
}
|
||||
}
|
||||
|
||||
// Monitors the state of the connection to the Navigation service.
|
||||
val serviceConnection: ServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
Log.i(TAG, "In onServiceConnected() Session component:$service")
|
||||
val binder: NavigationService.LocalBinder = service as NavigationService.LocalBinder
|
||||
navigationService = binder.service
|
||||
navigationService!!.setCarContext(carContext, serviceListener)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
Log.i(TAG, "In onServiceDisconnected() component: $name")
|
||||
// Unhook map models here
|
||||
navigationService!!.clearCarContext()
|
||||
navigationService = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lifecycle observer for managing session lifecycle events.
|
||||
* Cleans up resources when the session is destroyed.
|
||||
*/
|
||||
private val lifecycleObserver: LifecycleObserver = object : DefaultLifecycleObserver {
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
Log.i(TAG, "In onStart() Session")
|
||||
carContext
|
||||
.bindService(
|
||||
Intent(carContext, NavigationService::class.java),
|
||||
serviceConnection,
|
||||
Context.BIND_AUTO_CREATE
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
Log.i(TAG, "In onStop()")
|
||||
carContext.unbindService(serviceConnection)
|
||||
navigationService = null
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
if (::navigationManager.isInitialized) {
|
||||
navigationManager.clearNavigationManagerCallback()
|
||||
@@ -220,12 +281,9 @@ class NavigationSession : Session(), NavigationListener {
|
||||
// Called when the app should simulate navigation (e.g., for testing)
|
||||
deviceLocationManager.stopLocationUpdates()
|
||||
autoDriveEnabled = true
|
||||
surfaceRenderer.viewStyle = ViewStyle.VIEW
|
||||
simulation.startSimulation(
|
||||
routeModel, lifecycle.coroutineScope
|
||||
) { location ->
|
||||
updateLocation(location)
|
||||
}
|
||||
startNavigation()
|
||||
CarToast.makeText(carContext, "Auto drive enabled", CarToast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onStopNavigation() {
|
||||
@@ -427,6 +485,7 @@ class NavigationSession : Session(), NavigationListener {
|
||||
surfaceRenderer.routeData.value = ""
|
||||
surfaceRenderer.viewStyle = ViewStyle.VIEW
|
||||
navigationScreen.navigationType = NavigationType.VIEW
|
||||
navigationService!!.stopNavigation()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -64,7 +64,8 @@ import java.time.LocalDateTime
|
||||
* Manages camera position, zoom, tilt, and navigation state for the map view.
|
||||
*/
|
||||
class SurfaceRenderer(
|
||||
private var carContext: CarContext, lifecycle: Lifecycle,
|
||||
private var carContext: CarContext,
|
||||
private var lifecycle: Lifecycle,
|
||||
private var routeModel: RouteCarModel,
|
||||
private var viewModelStoreOwner: ViewModelStoreOwner
|
||||
) : DefaultLifecycleObserver {
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
package com.kouros.navigation.car.navigation
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.Service
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.model.CarIcon
|
||||
import androidx.car.app.model.Distance
|
||||
import androidx.car.app.navigation.NavigationManager
|
||||
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.notification.CarAppExtender
|
||||
import androidx.car.app.notification.CarPendingIntent
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.NavigationCarAppService
|
||||
import com.kouros.navigation.data.Constants.TAG
|
||||
import androidx.core.graphics.toColorInt
|
||||
|
||||
class NavigationService : Service() {
|
||||
|
||||
|
||||
val DEEP_LINK_ACTION: String = ("com.kouros.navigation.car.navigation"
|
||||
+ ".NavigationDeepLinkAction")
|
||||
|
||||
val channelId : String = "NavigationServiceChannel"
|
||||
|
||||
/** The identifier for the navigation notification displayed for the foreground service. */
|
||||
|
||||
val NAV_NOTIFICATION_ID: Int = 87356325
|
||||
|
||||
/** The identifier for the non-navigation notifications, such as a traffic accident warning. */
|
||||
|
||||
val NOTIFICATION_ID: Int = 71653346
|
||||
|
||||
// Constants for location broadcast
|
||||
val PACKAGE_NAME: String =
|
||||
"androidx.car.app.sample.navigation.common.nav.navigationservice"
|
||||
|
||||
val EXTRA_STARTED_FROM_NOTIFICATION: String = PACKAGE_NAME + ".started_from_notification"
|
||||
|
||||
val CANCEL_ACTION: String = "CANCEL"
|
||||
|
||||
private var notificationManager: NotificationManager? = null
|
||||
private var carContext: CarContext? = null
|
||||
|
||||
private lateinit var listener: Listener
|
||||
|
||||
// Model for managing route state and navigation logic for Android Auto
|
||||
var routeModel = RouteCarModel()
|
||||
|
||||
private lateinit var navigationManager: NavigationManager
|
||||
private var navigationManagerInitialized = false
|
||||
var binder: IBinder = LocalBinder()
|
||||
|
||||
override fun onBind(p0: Intent?): IBinder {
|
||||
return binder
|
||||
}
|
||||
|
||||
override fun onUnbind(intent: Intent): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
/** A listener for the navigation state changes. */
|
||||
interface Listener {
|
||||
/** Callback called when the navigation state changes. */
|
||||
fun navigationStateChanged(
|
||||
isNavigating: Boolean,
|
||||
isRerouting: Boolean,
|
||||
hasArrived: Boolean,
|
||||
destinations: MutableList<Destination?>?,
|
||||
steps: MutableList<Step>?,
|
||||
nextDestinationTravelEstimate: TravelEstimate?,
|
||||
nextStepRemainingDistance: Distance?,
|
||||
shouldShowNextStep: Boolean,
|
||||
shouldShowLanes: Boolean,
|
||||
junctionImage: CarIcon?
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used for the client Binder. Since this service runs in the same process as its clients,
|
||||
* we don't need to deal with IPC.
|
||||
*/
|
||||
inner class LocalBinder : Binder() {
|
||||
val service: NavigationService
|
||||
get() = this@NavigationService
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
Log.i(TAG, "In onCreate()");
|
||||
createNotificationChannel();
|
||||
}
|
||||
|
||||
/** Sets the [CarContext] to use while the service is connected. */
|
||||
fun setCarContext(
|
||||
carContext: CarContext,
|
||||
listener: Listener
|
||||
) {
|
||||
Log.d(TAG, "in setCarContext")
|
||||
this.carContext = carContext
|
||||
navigationManagerInitialized = true
|
||||
// navigationManager =
|
||||
// carContext.getCarService(NavigationManager::class.java)
|
||||
// navigationManager.setNavigationManagerCallback(
|
||||
// object : NavigationManagerCallback {
|
||||
// override fun onStopNavigation() {
|
||||
// this@NavigationService.stopNavigation()
|
||||
// }
|
||||
//
|
||||
// override fun onAutoDriveEnabled() {
|
||||
// Log.d(TAG, "onAutoDriveEnabled called")
|
||||
// CarToast.makeText(carContext, "Auto drive enabled", CarToast.LENGTH_LONG)
|
||||
// .show()
|
||||
// }
|
||||
// })
|
||||
this.listener = listener
|
||||
|
||||
// Uncomment if navigating
|
||||
// mNavigationManager.navigationStarted();
|
||||
}
|
||||
|
||||
/** Clears the currently used {@link CarContext}. */
|
||||
fun clearCarContext() {
|
||||
carContext = null;
|
||||
// navigationManager.clearNavigationManagerCallback();
|
||||
}
|
||||
|
||||
/** Starts navigation. */
|
||||
fun startNavigation() {
|
||||
Log.i(TAG, "Starting Navigation")
|
||||
startService(Intent(applicationContext, NavigationService::class.java))
|
||||
Log.i(TAG, "Starting foreground service")
|
||||
startForeground(
|
||||
NAV_NOTIFICATION_ID,
|
||||
getNotification(
|
||||
true,
|
||||
showInCar = false,
|
||||
navigatingDisplayTitle = getString(R.string.navigation_settings),
|
||||
navigatingDisplayContent = null,
|
||||
notificationIcon = R.drawable.navigation_48px
|
||||
)
|
||||
)
|
||||
|
||||
listener.navigationStateChanged(
|
||||
isNavigating = false,
|
||||
isRerouting = true,
|
||||
hasArrived = false,
|
||||
destinations = null,
|
||||
steps = null,
|
||||
nextDestinationTravelEstimate = null,
|
||||
nextStepRemainingDistance = null,
|
||||
shouldShowNextStep = false,
|
||||
shouldShowLanes = false,
|
||||
junctionImage = null
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
/** Starts navigation. */
|
||||
fun stopNavigation() {
|
||||
// if (navigationManagerInitialized)
|
||||
// navigationManager.navigationEnded()
|
||||
listener.navigationStateChanged(
|
||||
false,
|
||||
isRerouting = false,
|
||||
hasArrived = false,
|
||||
destinations = null,
|
||||
steps = null,
|
||||
nextDestinationTravelEstimate = null,
|
||||
nextStepRemainingDistance = null,
|
||||
shouldShowNextStep = false,
|
||||
shouldShowLanes = false,
|
||||
junctionImage = null,
|
||||
)
|
||||
stopForeground(STOP_FOREGROUND_REMOVE)
|
||||
stopSelf()
|
||||
}
|
||||
|
||||
private fun createNotificationChannel() {
|
||||
notificationManager =
|
||||
getSystemService(NotificationManager::class.java)
|
||||
val name: CharSequence = getString(R.string.navigation_settings)
|
||||
val serviceChannel =
|
||||
NotificationChannel(
|
||||
channelId,
|
||||
name,
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
)
|
||||
notificationManager!!.createNotificationChannel(serviceChannel)
|
||||
}
|
||||
|
||||
/** Returns the [NotificationCompat] used as part of the foreground service. */
|
||||
private fun getNotification(
|
||||
shouldNotify: Boolean,
|
||||
showInCar: Boolean,
|
||||
navigatingDisplayTitle: CharSequence?,
|
||||
navigatingDisplayContent: CharSequence?,
|
||||
notificationIcon: Int
|
||||
): Notification {
|
||||
val builder: NotificationCompat.Builder =
|
||||
NotificationCompat.Builder(this, channelId)
|
||||
//.setContentIntent(createMainActivityPendingIntent())
|
||||
.setContentTitle(navigatingDisplayTitle)
|
||||
.setContentText(navigatingDisplayContent)
|
||||
.setOngoing(true)
|
||||
.setCategory(NotificationCompat.CATEGORY_NAVIGATION)
|
||||
.setOnlyAlertOnce(!shouldNotify) // Set the notification's background color on the car screen.
|
||||
|
||||
.setColor(
|
||||
"#003000".toColorInt()
|
||||
)
|
||||
.setColorized(true)
|
||||
.setSmallIcon(R.drawable.ic_pan_24)
|
||||
.setLargeIcon(
|
||||
BitmapFactory.decodeResource(resources, notificationIcon)
|
||||
)
|
||||
.setTicker(navigatingDisplayTitle)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
|
||||
builder.setChannelId(channelId)
|
||||
builder.setPriority(NotificationManager.IMPORTANCE_HIGH)
|
||||
if (showInCar) {
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
.setComponent(ComponentName(this, NavigationCarAppService::class.java))
|
||||
.setData(NavigationCarAppService().createDeepLinkUri(Intent.ACTION_VIEW))
|
||||
builder.extend(
|
||||
CarAppExtender.Builder()
|
||||
.setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
|
||||
.setContentIntent(
|
||||
CarPendingIntent.getCarApp(
|
||||
this, intent.hashCode(),
|
||||
intent,
|
||||
0
|
||||
)
|
||||
)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
// private fun createMainActivityPendingIntent(): PendingIntent? {
|
||||
// val intent: Intent = Intent(this, MainActivity::class.java)
|
||||
// intent.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true)
|
||||
// return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
|
||||
// }
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package com.kouros.navigation.car.navigation
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.util.Log
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.car.app.AppManager
|
||||
import androidx.car.app.CarContext
|
||||
@@ -92,8 +91,17 @@ class RouteCarModel : RouteModel() {
|
||||
return step
|
||||
}
|
||||
|
||||
fun travelEstimate(carContext: CarContext, distanceMode: Int): TravelEstimate {
|
||||
val timeLeft = routeCalculator.travelLeftTime()
|
||||
fun travelEstimateTrip(carContext: CarContext, distanceMode: Int): TravelEstimate {
|
||||
|
||||
return travelEstimate(carContext, routeCalculator.travelLeftTime(), distanceMode)
|
||||
}
|
||||
|
||||
fun travelEstimateStep(carContext: CarContext, distanceMode: Int): TravelEstimate {
|
||||
return travelEstimate(carContext, routeCalculator.travelStepLeftTime(), distanceMode)
|
||||
}
|
||||
|
||||
fun travelEstimate(carContext: CarContext, timeLeft: Double, distanceMode: Int): TravelEstimate {
|
||||
|
||||
val timeToDestinationMillis =
|
||||
TimeUnit.SECONDS.toMillis(timeLeft.toLong())
|
||||
val distance = formattedDistance(distanceMode, routeCalculator.travelLeftDistance())
|
||||
|
||||
@@ -4,7 +4,7 @@ import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.os.SystemClock
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import com.kouros.android.cars.carappservice.BuildConfig
|
||||
import com.kouros.data.BuildConfig
|
||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||
import io.ticofab.androidgpxparser.parser.GPXParser
|
||||
import io.ticofab.androidgpxparser.parser.domain.Gpx
|
||||
|
||||
@@ -169,7 +169,7 @@ open class NavigationScreen(
|
||||
.setNavigationInfo(
|
||||
getRoutingInfo()
|
||||
)
|
||||
.setDestinationTravelEstimate(routeModel.travelEstimate(carContext, distanceMode))
|
||||
.setDestinationTravelEstimate(routeModel.travelEstimateTrip(carContext, distanceMode))
|
||||
.setActionStrip(actionStripBuilder.build())
|
||||
.setMapActionStrip(
|
||||
mapActionStrip(
|
||||
@@ -627,9 +627,11 @@ open class NavigationScreen(
|
||||
.build()
|
||||
tripBuilder.addDestination(
|
||||
destination,
|
||||
routeModel.travelEstimate(carContext, distanceMode)
|
||||
routeModel.travelEstimateTrip(carContext, distanceMode)
|
||||
)
|
||||
tripBuilder.setLoading(false)
|
||||
tripBuilder.setCurrentRoad(routeModel.currentStep.street)
|
||||
tripBuilder.addStep(routeModel.currentStep(carContext), routeModel.travelEstimateStep(carContext, distanceMode ))
|
||||
listener.updateTrip(tripBuilder.build())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.kouros.navigation.car.screen
|
||||
import android.net.Uri
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.util.Log
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.OnScreenResultListener
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.CarIcon
|
||||
|
||||
Reference in New Issue
Block a user