Service
This commit is contained in:
+63
-32
@@ -8,24 +8,25 @@ import android.content.Intent
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresPermission
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
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.core.location.LocationListenerCompat
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.kouros.navigation.car.DeviceLocationManager
|
||||
import com.kouros.navigation.car.DeviceLocationManagerService
|
||||
import com.kouros.navigation.car.NavigationNotificationService
|
||||
import com.kouros.navigation.data.Constants.TAG
|
||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||
import io.ticofab.androidgpxparser.parser.GPXParser
|
||||
import io.ticofab.androidgpxparser.parser.domain.Gpx
|
||||
import io.ticofab.androidgpxparser.parser.domain.TrackSegment
|
||||
import org.joda.time.DateTime
|
||||
|
||||
|
||||
class NavigationService : Service() {
|
||||
@@ -56,6 +57,11 @@ class NavigationService : Service() {
|
||||
private var notificationManager: NotificationManager? = null
|
||||
private var carContext: CarContext? = null
|
||||
|
||||
var autoDriveEnabled = false
|
||||
|
||||
val simulation = Simulation()
|
||||
|
||||
|
||||
private lateinit var listener: Listener
|
||||
|
||||
// Model for managing route state and navigation logic for Android Auto
|
||||
@@ -84,6 +90,8 @@ class NavigationService : Service() {
|
||||
shouldShowLanes: Boolean,
|
||||
junctionImage: CarIcon?
|
||||
)
|
||||
|
||||
fun updateServiceLocation(location: Location)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +103,8 @@ class NavigationService : Service() {
|
||||
get() = this@NavigationService
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
@@ -132,8 +141,6 @@ class NavigationService : Service() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** Sets the [CarContext] to use while the service is connected. */
|
||||
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
|
||||
fun setCarContext(
|
||||
@@ -150,23 +157,40 @@ class NavigationService : Service() {
|
||||
Log.d(TAG, "Initial location: $location")
|
||||
}
|
||||
)
|
||||
deviceLocationManager.startLocationUpdates()
|
||||
|
||||
|
||||
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()
|
||||
// }
|
||||
// })
|
||||
// navigationManager =
|
||||
// carContext.getCarService(NavigationManager::class.java)
|
||||
// navigationManager.setNavigationManagerCallback(object : NavigationManagerCallback {
|
||||
// override fun onAutoDriveEnabled() {
|
||||
// // Called when the app should simulate navigation (e.g., for testing)
|
||||
// deviceLocationManager.stopLocationUpdates()
|
||||
// autoDriveEnabled = true
|
||||
//
|
||||
// simulation()
|
||||
//
|
||||
// startNavigation()
|
||||
// CarToast.makeText(carContext, "Auto drive enabled", CarToast.LENGTH_LONG)
|
||||
// .show()
|
||||
// }
|
||||
//
|
||||
// private fun simulation() {
|
||||
// //simulation.gpxSimulation() {
|
||||
// // listener.updateServiceLocation(it)
|
||||
// //}
|
||||
// }
|
||||
//
|
||||
// override fun onStopNavigation() {
|
||||
// // Called when the user stops navigation in the car screen
|
||||
// // Stop turn-by-turn logic and clean up
|
||||
// stopNavigation()
|
||||
// if (autoDriveEnabled) {
|
||||
// deviceLocationManager.startLocationUpdates()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
this.listener = listener
|
||||
|
||||
// Uncomment if navigating
|
||||
@@ -177,12 +201,12 @@ class NavigationService : Service() {
|
||||
fun clearCarContext() {
|
||||
Log.i(TAG, "clearContext");
|
||||
carContext = null;
|
||||
deviceLocationManager.stopLocationUpdates()
|
||||
// navigationManager.clearNavigationManagerCallback();
|
||||
//navigationManager.clearNavigationManagerCallback();
|
||||
}
|
||||
|
||||
/** Starts navigation. */
|
||||
fun startNavigation() {
|
||||
//deviceLocationManager.startLocationUpdates()
|
||||
Log.i(TAG, "Starting Navigation")
|
||||
startService(Intent(applicationContext, NavigationService::class.java))
|
||||
Log.i(TAG, "Starting foreground service")
|
||||
@@ -204,6 +228,10 @@ class NavigationService : Service() {
|
||||
|
||||
/** Starts navigation. */
|
||||
fun stopNavigation() {
|
||||
if (autoDriveEnabled) {
|
||||
autoDriveEnabled = false
|
||||
}
|
||||
deviceLocationManager.stopLocationUpdates()
|
||||
// if (navigationManagerInitialized)
|
||||
// navigationManager.navigationEnded()
|
||||
listener.navigationStateChanged(
|
||||
@@ -224,11 +252,14 @@ class NavigationService : Service() {
|
||||
|
||||
fun updateLocation(location: Location) {
|
||||
Log.d(TAG, "Update location: $location")
|
||||
if (autoDriveEnabled) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
// }
|
||||
// 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,8 +3,10 @@ package com.kouros.navigation.car.navigation
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import com.kouros.data.BuildConfig
|
||||
import com.kouros.navigation.data.Constants.TAG
|
||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||
import io.ticofab.androidgpxparser.parser.GPXParser
|
||||
import io.ticofab.androidgpxparser.parser.domain.Gpx
|
||||
@@ -27,8 +29,9 @@ class Simulation {
|
||||
) {
|
||||
if (routeModel.navState.route.isRouteValid()) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
//gpxSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
currentSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
gpxSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
//gpxSimulation(updateLocation)
|
||||
//currentSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
} else {
|
||||
currentSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
}
|
||||
@@ -66,7 +69,7 @@ class Simulation {
|
||||
lastLocation = fakeLocation
|
||||
}
|
||||
}
|
||||
// routeModel.stopNavigation()
|
||||
// routeModel.stopNavigation()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +90,7 @@ class Simulation {
|
||||
simulationJob?.join()
|
||||
}
|
||||
simulationJob?.cancel()
|
||||
simulationJob =lifecycleScope.launch() {
|
||||
simulationJob = lifecycleScope.launch() {
|
||||
var lastLocation = Location(LocationManager.FUSED_PROVIDER)
|
||||
var curBearing = 0f
|
||||
val parser = GPXParser()
|
||||
@@ -118,7 +121,7 @@ class Simulation {
|
||||
updateLocation(fakeLocation)
|
||||
// Wait before moving to the next point (e.g., every 1 second)
|
||||
if (duration > 100) {
|
||||
// delay(duration / 4)
|
||||
// delay(duration / 4)
|
||||
}
|
||||
delay(500)
|
||||
lastTime = p.time
|
||||
@@ -134,4 +137,62 @@ class Simulation {
|
||||
fun stopSimulation() {
|
||||
simulationJob?.cancel()
|
||||
}
|
||||
|
||||
private fun gpxSimulation(
|
||||
updateLocation: (Location) -> Unit
|
||||
) {
|
||||
Runnable {
|
||||
var route = ""
|
||||
simulationJob?.cancel()
|
||||
runBlocking {
|
||||
simulationJob = launch(Dispatchers.IO) {
|
||||
route = TomTomRepository().fetchUrl(
|
||||
"https://kouros-online.de/vh.gpx",
|
||||
false
|
||||
)
|
||||
}
|
||||
simulationJob?.join()
|
||||
}
|
||||
simulationJob?.cancel()
|
||||
var lastLocation = Location(LocationManager.FUSED_PROVIDER)
|
||||
var curBearing = 0f
|
||||
val parser = GPXParser()
|
||||
val parsedGpx: Gpx? =
|
||||
parser.parse(route.byteInputStream())
|
||||
parsedGpx?.let {
|
||||
val tracks = parsedGpx.tracks
|
||||
tracks.forEach { tr ->
|
||||
val segments: MutableList<TrackSegment?>? = tr.trackSegments
|
||||
segments!!.forEach { seg ->
|
||||
var lastTime = DateTime.now()
|
||||
seg!!.trackPoints.forEach { p ->
|
||||
val ext = p.extensions
|
||||
var curSpeed = 0F
|
||||
if (ext != null) {
|
||||
curSpeed = ext.speed.toFloat()
|
||||
}
|
||||
val duration = p.time.millis - lastTime.millis
|
||||
val fakeLocation = Location(LocationManager.FUSED_PROVIDER).apply {
|
||||
latitude = p.latitude
|
||||
longitude = p.longitude
|
||||
speedAccuracyMetersPerSecond = 1.0f // ~1 m/s
|
||||
speed = curSpeed
|
||||
time = System.currentTimeMillis()
|
||||
elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
|
||||
}
|
||||
// Update your app's state as if a real GPS update occurred
|
||||
updateLocation(fakeLocation)
|
||||
// Wait before moving to the next point (e.g., every 1 second)
|
||||
if (duration > 100) {
|
||||
// delay(duration / 4)
|
||||
}
|
||||
Thread.sleep(500)
|
||||
lastTime = p.time
|
||||
lastLocation = fakeLocation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.run()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user