CarInfo and CarSensors
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
<!-- <uses-permission android:name="android.permission.READ_CONTACTS"/>-->
|
<!-- <uses-permission android:name="android.permission.READ_CONTACTS"/>-->
|
||||||
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
|
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
|
||||||
tools:ignore="MockLocation" />
|
tools:ignore="MockLocation" />
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class MainApplication : Application() {
|
|||||||
super.onCreate()
|
super.onCreate()
|
||||||
ObjectBox.init(this);
|
ObjectBox.init(this);
|
||||||
appContext = applicationContext
|
appContext = applicationContext
|
||||||
setIntKeyValue(appContext!!, RouteEngine.OSRM.ordinal, ROUTE_ENGINE)
|
setIntKeyValue(appContext!!, RouteEngine.VALHALLA.ordinal, ROUTE_ENGINE)
|
||||||
navigationViewModel = getRouteEngine(appContext!!)
|
navigationViewModel = getRouteEngine(appContext!!)
|
||||||
startKoin {
|
startKoin {
|
||||||
androidLogger(Level.DEBUG)
|
androidLogger(Level.DEBUG)
|
||||||
@@ -43,8 +43,6 @@ class MainApplication : Application() {
|
|||||||
var appContext: Context? = null
|
var appContext: Context? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var useContacts = false
|
|
||||||
|
|
||||||
lateinit var navigationViewModel : ViewModel
|
lateinit var navigationViewModel : ViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,20 +39,20 @@ import androidx.lifecycle.Observer
|
|||||||
import com.google.android.gms.location.FusedLocationProviderClient
|
import com.google.android.gms.location.FusedLocationProviderClient
|
||||||
import com.google.android.gms.location.LocationServices
|
import com.google.android.gms.location.LocationServices
|
||||||
import com.kouros.navigation.MainApplication.Companion.navigationViewModel
|
import com.kouros.navigation.MainApplication.Companion.navigationViewModel
|
||||||
|
import com.kouros.navigation.data.Constants
|
||||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
||||||
import com.kouros.navigation.data.Constants.homeLocation
|
import com.kouros.navigation.data.Constants.homeLocation
|
||||||
import com.kouros.navigation.data.StepData
|
import com.kouros.navigation.data.StepData
|
||||||
|
import com.kouros.navigation.model.BaseStyleModel
|
||||||
import com.kouros.navigation.model.MockLocation
|
import com.kouros.navigation.model.MockLocation
|
||||||
import com.kouros.navigation.model.RouteModel
|
import com.kouros.navigation.model.RouteModel
|
||||||
import com.kouros.navigation.ui.theme.NavigationTheme
|
import com.kouros.navigation.ui.theme.NavigationTheme
|
||||||
|
import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue
|
||||||
import com.kouros.navigation.utils.bearing
|
import com.kouros.navigation.utils.bearing
|
||||||
import com.kouros.navigation.utils.calculateZoom
|
import com.kouros.navigation.utils.calculateZoom
|
||||||
import com.kouros.navigation.utils.location
|
import com.kouros.navigation.utils.location
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.async
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.maplibre.compose.camera.CameraPosition
|
import org.maplibre.compose.camera.CameraPosition
|
||||||
@@ -60,6 +60,7 @@ import org.maplibre.compose.location.DesiredAccuracy
|
|||||||
import org.maplibre.compose.location.Location
|
import org.maplibre.compose.location.Location
|
||||||
import org.maplibre.compose.location.rememberDefaultLocationProvider
|
import org.maplibre.compose.location.rememberDefaultLocationProvider
|
||||||
import org.maplibre.compose.location.rememberUserLocationState
|
import org.maplibre.compose.location.rememberUserLocationState
|
||||||
|
import org.maplibre.compose.style.BaseStyle
|
||||||
import org.maplibre.spatialk.geojson.Position
|
import org.maplibre.spatialk.geojson.Position
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
@@ -101,6 +102,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
private var overpass = false
|
private var overpass = false
|
||||||
|
|
||||||
|
lateinit var baseStyle : BaseStyle.Json
|
||||||
|
|
||||||
init {
|
init {
|
||||||
navigationViewModel.route.observe(this, observer)
|
navigationViewModel.route.observe(this, observer)
|
||||||
}
|
}
|
||||||
@@ -108,6 +111,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
|
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
val darkModeSettings = getIntKeyValue(applicationContext, Constants.DARK_MODE_SETTINGS)
|
||||||
|
baseStyle = BaseStyleModel().readStyle(applicationContext, darkModeSettings, false)
|
||||||
if (useMock) {
|
if (useMock) {
|
||||||
checkMockLocationEnabled()
|
checkMockLocationEnabled()
|
||||||
}
|
}
|
||||||
@@ -196,7 +201,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
step,
|
step,
|
||||||
cameraPosition,
|
cameraPosition,
|
||||||
routeData,
|
routeData,
|
||||||
tilt
|
tilt,
|
||||||
|
baseStyle
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,14 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.window.layout.WindowMetricsCalculator
|
import androidx.window.layout.WindowMetricsCalculator
|
||||||
import com.kouros.navigation.car.ViewStyle
|
import com.kouros.navigation.car.ViewStyle
|
||||||
import com.kouros.navigation.car.map.DarkMode
|
|
||||||
import com.kouros.navigation.car.map.MapLibre
|
import com.kouros.navigation.car.map.MapLibre
|
||||||
import com.kouros.navigation.car.map.NavigationImage
|
import com.kouros.navigation.car.map.NavigationImage
|
||||||
import com.kouros.navigation.data.Constants
|
import com.kouros.navigation.car.map.rememberBaseStyle
|
||||||
import com.kouros.navigation.data.StepData
|
import com.kouros.navigation.data.StepData
|
||||||
import org.maplibre.compose.camera.CameraPosition
|
import org.maplibre.compose.camera.CameraPosition
|
||||||
import org.maplibre.compose.camera.rememberCameraState
|
import org.maplibre.compose.camera.rememberCameraState
|
||||||
@@ -34,10 +31,12 @@ fun MapView(
|
|||||||
step: StepData?,
|
step: StepData?,
|
||||||
cameraPosition: MutableLiveData<CameraPosition>,
|
cameraPosition: MutableLiveData<CameraPosition>,
|
||||||
routeData: MutableLiveData<String>,
|
routeData: MutableLiveData<String>,
|
||||||
tilt: Double
|
tilt: Double,
|
||||||
|
baseStyle: BaseStyle.Json,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(applicationContext)
|
val metrics =
|
||||||
|
WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(applicationContext)
|
||||||
val width = metrics.bounds.width()
|
val width = metrics.bounds.width()
|
||||||
val height = metrics.bounds.height()
|
val height = metrics.bounds.height()
|
||||||
val paddingValues = PaddingValues(start = 0.dp, top = 350.dp)
|
val paddingValues = PaddingValues(start = 0.dp, top = 350.dp)
|
||||||
@@ -55,17 +54,15 @@ fun MapView(
|
|||||||
zoom = 15.0,
|
zoom = 15.0,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val baseStyle = remember {
|
|
||||||
mutableStateOf(BaseStyle.Uri(Constants.STYLE))
|
val rememberBaseStyle = rememberBaseStyle( baseStyle)
|
||||||
}
|
|
||||||
DarkMode(applicationContext, baseStyle)
|
|
||||||
Column {
|
Column {
|
||||||
NavigationInfo(step)
|
NavigationInfo(step)
|
||||||
Box(contentAlignment = Alignment.Center) {
|
Box(contentAlignment = Alignment.Center) {
|
||||||
MapLibre(
|
MapLibre(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
cameraState,
|
cameraState,
|
||||||
baseStyle,
|
rememberBaseStyle,
|
||||||
route,
|
route,
|
||||||
ViewStyle.VIEW
|
ViewStyle.VIEW
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ dependencies {
|
|||||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||||
implementation(libs.androidx.ui)
|
implementation(libs.androidx.ui)
|
||||||
implementation(libs.maplibre.compose)
|
implementation(libs.maplibre.compose)
|
||||||
|
implementation(libs.androidx.app.projected)
|
||||||
//implementation(libs.maplibre.composeMaterial3)
|
//implementation(libs.maplibre.composeMaterial3)
|
||||||
|
|
||||||
implementation(project(":common:data"))
|
implementation(project(":common:data"))
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
|
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
|
||||||
|
<uses-permission android:name="com.google.android.gms.permission.CAR_SPEED"/>
|
||||||
|
<uses-permission android:name="android.car.permission.READ_CAR_DISPLAY_UNITS"/>
|
||||||
|
|
||||||
<application android:requestLegacyExternalStorage="true"
|
<application android:requestLegacyExternalStorage="true"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
|
|||||||
@@ -38,9 +38,4 @@ class NavigationCarAppService : CarAppService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LocationCallback {
|
|
||||||
|
|
||||||
fun onLocationChanged(location: Location) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import android.location.LocationManager
|
import android.location.LocationManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -12,6 +13,13 @@ import androidx.car.app.CarContext
|
|||||||
import androidx.car.app.Screen
|
import androidx.car.app.Screen
|
||||||
import androidx.car.app.ScreenManager
|
import androidx.car.app.ScreenManager
|
||||||
import androidx.car.app.Session
|
import androidx.car.app.Session
|
||||||
|
import androidx.car.app.hardware.CarHardwareManager
|
||||||
|
import androidx.car.app.hardware.common.CarValue
|
||||||
|
import androidx.car.app.hardware.common.OnCarDataAvailableListener
|
||||||
|
import androidx.car.app.hardware.info.CarHardwareLocation
|
||||||
|
import androidx.car.app.hardware.info.CarSensors
|
||||||
|
import androidx.car.app.hardware.info.Speed
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.core.location.LocationListenerCompat
|
import androidx.core.location.LocationListenerCompat
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
@@ -22,17 +30,16 @@ import com.kouros.navigation.car.navigation.RouteCarModel
|
|||||||
import com.kouros.navigation.car.screen.NavigationScreen
|
import com.kouros.navigation.car.screen.NavigationScreen
|
||||||
import com.kouros.navigation.car.screen.RequestPermissionScreen
|
import com.kouros.navigation.car.screen.RequestPermissionScreen
|
||||||
import com.kouros.navigation.car.screen.SearchScreen
|
import com.kouros.navigation.car.screen.SearchScreen
|
||||||
|
import com.kouros.navigation.data.Constants
|
||||||
import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION
|
import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION
|
||||||
import com.kouros.navigation.data.Constants.MAXIMAL_SNAP_CORRECTION
|
import com.kouros.navigation.data.Constants.MAXIMAL_SNAP_CORRECTION
|
||||||
import com.kouros.navigation.data.Constants.ROUTE_ENGINE
|
|
||||||
import com.kouros.navigation.data.Constants.TAG
|
import com.kouros.navigation.data.Constants.TAG
|
||||||
import com.kouros.navigation.data.NavigationRepository
|
import com.kouros.navigation.model.BaseStyleModel
|
||||||
import com.kouros.navigation.data.osrm.OsrmRepository
|
|
||||||
import com.kouros.navigation.data.valhalla.ValhallaRepository
|
|
||||||
import com.kouros.navigation.model.ViewModel
|
import com.kouros.navigation.model.ViewModel
|
||||||
import com.kouros.navigation.utils.GeoUtils.snapLocation
|
import com.kouros.navigation.utils.GeoUtils.snapLocation
|
||||||
import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue
|
import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue
|
||||||
import com.kouros.navigation.utils.NavigationUtils.getRouteEngine
|
import com.kouros.navigation.utils.NavigationUtils.getRouteEngine
|
||||||
|
import org.maplibre.compose.style.BaseStyle
|
||||||
|
|
||||||
class NavigationSession : Session(), NavigationScreen.Listener {
|
class NavigationSession : Session(), NavigationScreen.Listener {
|
||||||
|
|
||||||
@@ -66,6 +73,10 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy(owner: LifecycleOwner) {
|
override fun onDestroy(owner: LifecycleOwner) {
|
||||||
|
val carSensors = carContext.getCarService(CarHardwareManager::class.java).carSensors
|
||||||
|
val carInfo = carContext.getCarService(CarHardwareManager::class.java).carInfo
|
||||||
|
carSensors.removeCarHardwareLocationListener(locationListener)
|
||||||
|
carInfo.removeSpeedListener(speedListener)
|
||||||
Log.i(TAG, "In onDestroy()")
|
Log.i(TAG, "In onDestroy()")
|
||||||
val locationManager =
|
val locationManager =
|
||||||
carContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
carContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
@@ -73,24 +84,45 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var navigationViewModel : ViewModel
|
lateinit var navigationViewModel: ViewModel
|
||||||
|
|
||||||
|
lateinit var baseStyle: BaseStyle.Json
|
||||||
|
|
||||||
|
val locationListener: OnCarDataAvailableListener<CarHardwareLocation?> =
|
||||||
|
OnCarDataAvailableListener { data ->
|
||||||
|
if (data.location.status == CarValue.STATUS_SUCCESS) {
|
||||||
|
val location = data.location.value
|
||||||
|
surfaceRenderer.updateCarLocation(location!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val speedListener = OnCarDataAvailableListener<Speed> { data ->
|
||||||
|
if (data.displaySpeedMetersPerSecond.status == CarValue.STATUS_SUCCESS) {
|
||||||
|
val speed = data.displaySpeedMetersPerSecond.value
|
||||||
|
surfaceRenderer.updateCarSpeed(speed!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
init {
|
init {
|
||||||
val lifecycle: Lifecycle = lifecycle
|
val lifecycle: Lifecycle = lifecycle
|
||||||
lifecycle.addObserver(mLifeCycleObserver)
|
lifecycle.addObserver(mLifeCycleObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateScreen(intent: Intent): Screen {
|
override fun onCreateScreen(intent: Intent): Screen {
|
||||||
|
|
||||||
navigationViewModel = getRouteEngine(carContext)
|
navigationViewModel = getRouteEngine(carContext)
|
||||||
routeModel = RouteCarModel()
|
routeModel = RouteCarModel()
|
||||||
|
|
||||||
surfaceRenderer = SurfaceRenderer(carContext, lifecycle, routeModel)
|
val darkMode = getIntKeyValue(carContext, Constants.DARK_MODE_SETTINGS)
|
||||||
|
baseStyle = BaseStyleModel().readStyle(carContext, darkMode, carContext.isDarkMode)
|
||||||
|
|
||||||
navigationScreen = NavigationScreen(carContext, surfaceRenderer, routeModel, this, navigationViewModel)
|
surfaceRenderer = SurfaceRenderer(carContext, lifecycle, routeModel, baseStyle)
|
||||||
|
|
||||||
|
navigationScreen =
|
||||||
|
NavigationScreen(carContext, surfaceRenderer, routeModel, this, navigationViewModel)
|
||||||
|
|
||||||
if (carContext.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
|
if (carContext.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
== PackageManager.PERMISSION_GRANTED && !useContacts
|
== PackageManager.PERMISSION_GRANTED
|
||||||
|
&& carContext.checkSelfPermission("com.google.android.gms.permission.CAR_SPEED") == PackageManager.PERMISSION_GRANTED
|
||||||
|
&& !useContacts
|
||||||
|| (useContacts && carContext.checkSelfPermission(Manifest.permission.READ_CONTACTS)
|
|| (useContacts && carContext.checkSelfPermission(Manifest.permission.READ_CONTACTS)
|
||||||
== PackageManager.PERMISSION_GRANTED)
|
== PackageManager.PERMISSION_GRANTED)
|
||||||
) {
|
) {
|
||||||
@@ -111,9 +143,23 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addSensors()
|
||||||
|
|
||||||
return navigationScreen
|
return navigationScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addSensors() {
|
||||||
|
val carSensors = carContext.getCarService(CarHardwareManager::class.java).carSensors
|
||||||
|
val carInfo = carContext.getCarService(CarHardwareManager::class.java).carInfo
|
||||||
|
carSensors.addCarHardwareLocationListener(
|
||||||
|
CarSensors.UPDATE_RATE_NORMAL,
|
||||||
|
carContext.mainExecutor,
|
||||||
|
locationListener
|
||||||
|
)
|
||||||
|
carInfo.addSpeedListener(carContext.mainExecutor, speedListener)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
val screenManager = carContext.getCarService(ScreenManager::class.java)
|
val screenManager = carContext.getCarService(ScreenManager::class.java)
|
||||||
if ((CarContext.ACTION_NAVIGATE == intent.action)) {
|
if ((CarContext.ACTION_NAVIGATE == intent.action)) {
|
||||||
@@ -151,6 +197,11 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCarConfigurationChanged(newConfiguration: Configuration) {
|
||||||
|
println("Configuration: ${newConfiguration.isNightModeActive}")
|
||||||
|
super.onCarConfigurationChanged(newConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
fun requestLocationUpdates() {
|
fun requestLocationUpdates() {
|
||||||
val locationManager =
|
val locationManager =
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
@@ -27,13 +25,12 @@ import androidx.lifecycle.LifecycleOwner
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.setViewTreeLifecycleOwner
|
import androidx.lifecycle.setViewTreeLifecycleOwner
|
||||||
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
||||||
import com.kouros.navigation.car.map.DarkMode
|
|
||||||
import com.kouros.navigation.car.map.DrawNavigationImages
|
import com.kouros.navigation.car.map.DrawNavigationImages
|
||||||
import com.kouros.navigation.car.map.MapLibre
|
import com.kouros.navigation.car.map.MapLibre
|
||||||
import com.kouros.navigation.car.map.cameraState
|
import com.kouros.navigation.car.map.cameraState
|
||||||
import com.kouros.navigation.car.map.getPaddingValues
|
import com.kouros.navigation.car.map.getPaddingValues
|
||||||
|
import com.kouros.navigation.car.map.rememberBaseStyle
|
||||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||||
import com.kouros.navigation.data.Constants
|
|
||||||
import com.kouros.navigation.data.Constants.homeLocation
|
import com.kouros.navigation.data.Constants.homeLocation
|
||||||
import com.kouros.navigation.data.ObjectBox
|
import com.kouros.navigation.data.ObjectBox
|
||||||
import com.kouros.navigation.model.RouteModel
|
import com.kouros.navigation.model.RouteModel
|
||||||
@@ -51,7 +48,8 @@ import org.maplibre.spatialk.geojson.Position
|
|||||||
|
|
||||||
class SurfaceRenderer(
|
class SurfaceRenderer(
|
||||||
private var carContext: CarContext, lifecycle: Lifecycle,
|
private var carContext: CarContext, lifecycle: Lifecycle,
|
||||||
private var routeModel: RouteCarModel
|
private var routeModel: RouteCarModel,
|
||||||
|
private var baseStyle: BaseStyle.Json
|
||||||
) : DefaultLifecycleObserver {
|
) : DefaultLifecycleObserver {
|
||||||
|
|
||||||
var lastLocation = location(0.0, 0.0)
|
var lastLocation = location(0.0, 0.0)
|
||||||
@@ -174,12 +172,8 @@ class SurfaceRenderer(
|
|||||||
val speedCameras: String? by speedCamerasData.observeAsState()
|
val speedCameras: String? by speedCamerasData.observeAsState()
|
||||||
val paddingValues = getPaddingValues(height, viewStyle)
|
val paddingValues = getPaddingValues(height, viewStyle)
|
||||||
val cameraState = cameraState(paddingValues, position, tilt)
|
val cameraState = cameraState(paddingValues, position, tilt)
|
||||||
|
val rememberBaseStyle = rememberBaseStyle(baseStyle)
|
||||||
val baseStyle = remember {
|
MapLibre(carContext, cameraState, rememberBaseStyle, route, viewStyle, speedCameras)
|
||||||
mutableStateOf(BaseStyle.Uri(Constants.STYLE))
|
|
||||||
}
|
|
||||||
DarkMode(carContext, baseStyle)
|
|
||||||
MapLibre(carContext, cameraState, baseStyle, route, viewStyle, speedCameras)
|
|
||||||
ShowPosition(cameraState, position, paddingValues)
|
ShowPosition(cameraState, position, paddingValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +256,7 @@ class SurfaceRenderer(
|
|||||||
)
|
)
|
||||||
lastBearing = cameraPosition.value!!.bearing
|
lastBearing = cameraPosition.value!!.bearing
|
||||||
lastLocation = location
|
lastLocation = location
|
||||||
speed.value = location.speed
|
//speed.value = location.speed
|
||||||
if (!countDownTimerActive) {
|
if (!countDownTimerActive) {
|
||||||
countDownTimerActive = true
|
countDownTimerActive = true
|
||||||
val mainThreadHandler = Handler(carContext.mainLooper)
|
val mainThreadHandler = Handler(carContext.mainLooper)
|
||||||
@@ -331,6 +325,14 @@ class SurfaceRenderer(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateCarLocation(location: Location) {
|
||||||
|
// updateLocation(location)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateCarSpeed(newSpeed: Float) {
|
||||||
|
speed.value = newSpeed
|
||||||
|
}
|
||||||
|
|
||||||
fun setCategoryLocation(location: Location, category: String) {
|
fun setCategoryLocation(location: Location, category: String) {
|
||||||
viewStyle = ViewStyle.AMENITY_VIEW
|
viewStyle = ViewStyle.AMENITY_VIEW
|
||||||
cameraPosition.postValue(
|
cameraPosition.postValue(
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.kouros.navigation.car.map
|
package com.kouros.navigation.car.map
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.AssetFileDescriptor
|
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -13,13 +11,17 @@ import androidx.compose.foundation.layout.size
|
|||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.scale
|
import androidx.compose.ui.draw.scale
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.drawscope.scale
|
import androidx.compose.ui.graphics.drawscope.scale
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.drawText
|
import androidx.compose.ui.text.drawText
|
||||||
@@ -88,20 +90,19 @@ fun cameraState(
|
|||||||
fun MapLibre(
|
fun MapLibre(
|
||||||
context: Context,
|
context: Context,
|
||||||
cameraState: CameraState,
|
cameraState: CameraState,
|
||||||
baseStyle: MutableState<BaseStyle.Uri>,
|
baseStyle: BaseStyle.Json,
|
||||||
route: String?,
|
route: String?,
|
||||||
viewStyle: ViewStyle,
|
viewStyle: ViewStyle,
|
||||||
speedCameras: String? = ""
|
speedCameras: String? = ""
|
||||||
) {
|
) {
|
||||||
|
|
||||||
//val baseStyle = BaseStyleModel().readStyle(context)
|
|
||||||
MaplibreMap(
|
MaplibreMap(
|
||||||
options = MapOptions(
|
options = MapOptions(
|
||||||
ornamentOptions =
|
ornamentOptions =
|
||||||
OrnamentOptions(isScaleBarEnabled = false)
|
OrnamentOptions(isScaleBarEnabled = false)
|
||||||
),
|
),
|
||||||
cameraState = cameraState,
|
cameraState = cameraState,
|
||||||
baseStyle = baseStyle.value
|
baseStyle = baseStyle
|
||||||
) {
|
) {
|
||||||
getBaseSource(id = "openmaptiles")?.let { tiles ->
|
getBaseSource(id = "openmaptiles")?.let { tiles ->
|
||||||
if (!getBooleanKeyValue(context = context, SHOW_THREED_BUILDING)) {
|
if (!getBooleanKeyValue(context = context, SHOW_THREED_BUILDING)) {
|
||||||
@@ -372,23 +373,14 @@ private fun MaxSpeed(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DarkMode(context: Context, baseStyle: MutableState<BaseStyle.Uri>) {
|
fun rememberBaseStyle( baseStyle : BaseStyle.Json): BaseStyle.Json {
|
||||||
val darkMode = getIntKeyValue(context, Constants.DARK_MODE_SETTINGS)
|
val rememberBaseStyle by remember() {
|
||||||
|
mutableStateOf(baseStyle)
|
||||||
if (darkMode == 0) {
|
|
||||||
baseStyle.value = BaseStyle.Uri(Constants.STYLE)
|
|
||||||
}
|
|
||||||
if (darkMode == 1) {
|
|
||||||
baseStyle.value = BaseStyle.Uri(Constants.STYLE_DARK)
|
|
||||||
}
|
|
||||||
if (darkMode == 2) {
|
|
||||||
baseStyle.value =
|
|
||||||
(if (isSystemInDarkTheme()) BaseStyle.Uri(Constants.STYLE_DARK) else BaseStyle.Uri(
|
|
||||||
Constants.STYLE
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
return rememberBaseStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getPaddingValues(height: Int, viewStyle: ViewStyle): PaddingValues {
|
fun getPaddingValues(height: Int, viewStyle: ViewStyle): PaddingValues {
|
||||||
return when (viewStyle) {
|
return when (viewStyle) {
|
||||||
ViewStyle.VIEW, ViewStyle.PAN_VIEW -> PaddingValues(
|
ViewStyle.VIEW, ViewStyle.PAN_VIEW -> PaddingValues(
|
||||||
|
|||||||
@@ -26,9 +26,10 @@ class RequestPermissionScreen(
|
|||||||
override fun onGetTemplate(): Template {
|
override fun onGetTemplate(): Template {
|
||||||
val permissions: MutableList<String?> = ArrayList()
|
val permissions: MutableList<String?> = ArrayList()
|
||||||
permissions.add(permission.ACCESS_FINE_LOCATION)
|
permissions.add(permission.ACCESS_FINE_LOCATION)
|
||||||
|
permissions.add("com.google.android.gms.permission.CAR_SPEED")
|
||||||
//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"
|
val message = "This app needs access to location and to car speed"
|
||||||
|
|
||||||
val listener: OnClickListener = ParkedOnlyOnClickListener.create {
|
val listener: OnClickListener = ParkedOnlyOnClickListener.create {
|
||||||
carContext.requestPermissions(
|
carContext.requestPermissions(
|
||||||
|
|||||||
@@ -1,13 +1,31 @@
|
|||||||
package com.kouros.navigation.model
|
package com.kouros.navigation.model
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import com.kouros.data.R
|
import com.kouros.data.R
|
||||||
import org.maplibre.compose.style.BaseStyle
|
import org.maplibre.compose.style.BaseStyle
|
||||||
|
|
||||||
class BaseStyleModel {
|
class BaseStyleModel {
|
||||||
fun readStyle(context: Context): BaseStyle.Json {
|
|
||||||
println("Read Style")
|
fun isDarkTheme(context: Context): Boolean {
|
||||||
val liberty = context.resources.openRawResource(R.raw.liberty)
|
return context.resources.configuration.uiMode and
|
||||||
|
Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readStyle(context: Context, darkModeSettings: Int, isCarDarkMode: Boolean): BaseStyle.Json {
|
||||||
|
println("BaseStyle ${isDarkTheme(context)}")
|
||||||
|
val liberty = when(darkModeSettings) {
|
||||||
|
0 -> context.resources.openRawResource(R.raw.liberty)
|
||||||
|
1 -> context.resources.openRawResource(R.raw.liberty_night)
|
||||||
|
else -> {
|
||||||
|
if (isDarkTheme(context) || isCarDarkMode) {
|
||||||
|
context.resources.openRawResource(R.raw.liberty_night)
|
||||||
|
} else {
|
||||||
|
context.resources.openRawResource(R.raw.liberty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
val libertyString = liberty.bufferedReader().use { it.readText() }
|
val libertyString = liberty.bufferedReader().use { it.readText() }
|
||||||
val baseStyle = BaseStyle.Json(libertyString)
|
val baseStyle = BaseStyle.Json(libertyString)
|
||||||
return baseStyle
|
return baseStyle
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ foundationLayout = "1.10.0"
|
|||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
android-sdk-turf = { module = "org.maplibre.gl:android-sdk-turf", version.ref = "androidSdkTurf" }
|
android-sdk-turf = { module = "org.maplibre.gl:android-sdk-turf", version.ref = "androidSdkTurf" }
|
||||||
|
androidx-app-projected = { module = "androidx.car.app:app-projected" }
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
|
gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
|
||||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||||
|
|||||||
Reference in New Issue
Block a user