diff --git a/app/build.gradle.kts b/app/build.gradle.kts index aaeecc0..778fbe2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) @@ -12,10 +14,9 @@ android { applicationId = "com.kouros.navigation" minSdk = 33 targetSdk = 36 - versionCode = 2 - versionName = "0.1.3.1" - setProperty("archivesBaseName", "navi-$versionName") - + versionCode = 4 + versionName = "0.1.3.3" + base.archivesName = "navi-$versionName" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -61,21 +62,21 @@ android { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } - kotlinOptions { - jvmTarget = "11" + kotlin { + compilerOptions { + jvmTarget = JvmTarget.JVM_11 + } } buildFeatures { compose = true } } - dependencies { implementation(libs.androidx.core.ktx) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.ui) - implementation(libs.androidx.car.app) implementation(libs.androidx.material3) implementation(libs.androidx.runtime.livedata) implementation(libs.koin.androidx.compose) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 29b64a3..ed14074 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,7 +6,6 @@ - diff --git a/app/src/main/java/com/kouros/navigation/MainApplication.kt b/app/src/main/java/com/kouros/navigation/MainApplication.kt index 02d0255..6ada8ad 100644 --- a/app/src/main/java/com/kouros/navigation/MainApplication.kt +++ b/app/src/main/java/com/kouros/navigation/MainApplication.kt @@ -12,7 +12,7 @@ class MainApplication : Application() { override fun onCreate() { super.onCreate() - ObjectBox.init(applicationContext); + ObjectBox.init(this); appContext = applicationContext startKoin { androidLogger(Level.DEBUG) @@ -25,6 +25,6 @@ class MainApplication : Application() { var appContext: Context? = null private set - var useContacts = true + var useContacts = false } } \ No newline at end of file diff --git a/app/src/main/java/com/kouros/navigation/model/MockLocation.kt b/app/src/main/java/com/kouros/navigation/model/MockLocation.kt index b615c62..5c54fcd 100644 --- a/app/src/main/java/com/kouros/navigation/model/MockLocation.kt +++ b/app/src/main/java/com/kouros/navigation/model/MockLocation.kt @@ -48,7 +48,7 @@ class MockLocation (private var locationManager: LocationManager) { this.longitude = longitude this.altitude = 0.0 this.accuracy = 1.0f - this.speed = 15F + this.speed = 0F this.time = System.currentTimeMillis() this.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos() diff --git a/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt b/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt index e478680..b46edf9 100644 --- a/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt +++ b/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt @@ -132,7 +132,7 @@ class MainActivity : ComponentActivity() { checkContactsPermissions() } - checkMockLocationEnabled() +// checkMockLocationEnabled() enableEdgeToEdge() setContent { @@ -354,6 +354,8 @@ class MainActivity : ComponentActivity() { } fun updateLocation(location: org.maplibre.compose.location.Location?) { + if (1 == 1) + return if (location != null) { if (routeModel.isNavigating()) { routeModel.updateLocation(lastLocation) @@ -465,11 +467,11 @@ class MainActivity : ComponentActivity() { lastLocation.longitude = loc[0] lastLocation.latitude = loc[1] if (i == 20) { - mock.setMockLocation(loc[1] + 0.03, loc[0]) + mock.setMockLocation(loc[1] , loc[0]) } else { mock.setMockLocation(loc[1], loc[0]) } - delay(1000L) // + delay(500L) // } } } diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d1..0000000 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher.xml b/app/src/main/res/drawable/ic_launcher.xml deleted file mode 100644 index 20357f9..0000000 --- a/app/src/main/res/drawable/ic_launcher.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index 07d5da9..ca3826a 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,74 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns:android="http://schemas.android.com/apk/res/android"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..7010fed --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index eca70cf..bbd3e02 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index eca70cf..bbd3e02 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp index c209e78..da24c35 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp index b2dfe3d..2850a90 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp index 4f0f1d6..8042972 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp index 62b611d..940caf5 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp index 948a307..c52ae69 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp index 1b9a695..56b8e2b 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp index 28d4b77..284db5a 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp index 9287f50..2f729db 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index aa7d642..9b5e24c 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index 9126ae3..56a171b 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/automotive/.gitignore b/automotive/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/automotive/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/automotive/build.gradle.kts b/automotive/build.gradle.kts new file mode 100644 index 0000000..fbe1331 --- /dev/null +++ b/automotive/build.gradle.kts @@ -0,0 +1,53 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) +} + +android { + namespace = "com.kouros.navigation" + compileSdk { + version = release(36) + } + + defaultConfig { + applicationId = "com.kouros.navigation" + minSdk = 33 + targetSdk = 36 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } +} + +dependencies { + implementation(libs.androidx.app.automotive) + implementation(libs.androidx.car.app) + implementation(libs.androidx.material3) + implementation(libs.androidx.runtime.livedata) + implementation(project(":common:car")) + implementation(project(":common:data")) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.material) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) +} \ No newline at end of file diff --git a/automotive/proguard-rules.pro b/automotive/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/automotive/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/automotive/src/androidTest/java/com/kouros/navigation/ExampleInstrumentedTest.kt b/automotive/src/androidTest/java/com/kouros/navigation/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..06d6582 --- /dev/null +++ b/automotive/src/androidTest/java/com/kouros/navigation/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.kouros.navigation + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.kouros.navigation", appContext.packageName) + } +} \ No newline at end of file diff --git a/automotive/src/main/AndroidManifest.xml b/automotive/src/main/AndroidManifest.xml new file mode 100644 index 0000000..311eae5 --- /dev/null +++ b/automotive/src/main/AndroidManifest.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/automotive/src/main/res/drawable/ic_launcher_background.xml b/automotive/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/automotive/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/automotive/src/main/res/drawable/ic_launcher_foreground.xml b/automotive/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..7010fed --- /dev/null +++ b/automotive/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/automotive/src/main/res/mipmap-anydpi/ic_launcher.xml b/automotive/src/main/res/mipmap-anydpi/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/automotive/src/main/res/mipmap-anydpi/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/automotive/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/automotive/src/main/res/mipmap-anydpi/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/automotive/src/main/res/mipmap-anydpi/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/automotive/src/main/res/mipmap-hdpi/ic_launcher.webp b/automotive/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..da24c35 Binary files /dev/null and b/automotive/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/automotive/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/automotive/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..2850a90 Binary files /dev/null and b/automotive/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/automotive/src/main/res/mipmap-mdpi/ic_launcher.webp b/automotive/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..8042972 Binary files /dev/null and b/automotive/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/automotive/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/automotive/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..940caf5 Binary files /dev/null and b/automotive/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/automotive/src/main/res/mipmap-xhdpi/ic_launcher.webp b/automotive/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..c52ae69 Binary files /dev/null and b/automotive/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/automotive/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/automotive/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..56b8e2b Binary files /dev/null and b/automotive/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/automotive/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/automotive/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..284db5a Binary files /dev/null and b/automotive/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/automotive/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/automotive/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..2f729db Binary files /dev/null and b/automotive/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..9b5e24c Binary files /dev/null and b/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..56a171b Binary files /dev/null and b/automotive/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/automotive/src/main/res/values-night/themes.xml b/automotive/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..68b1bf6 --- /dev/null +++ b/automotive/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/automotive/src/main/res/values/colors.xml b/automotive/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/automotive/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/automotive/src/main/res/values/themes.xml b/automotive/src/main/res/values/themes.xml new file mode 100644 index 0000000..23e83b0 --- /dev/null +++ b/automotive/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/automotive/src/test/java/com/kouros/navigation/ExampleUnitTest.kt b/automotive/src/test/java/com/kouros/navigation/ExampleUnitTest.kt new file mode 100644 index 0000000..cb0e6f0 --- /dev/null +++ b/automotive/src/test/java/com/kouros/navigation/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.kouros.navigation + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/common/car/src/main/AndroidManifest.xml b/common/car/src/main/AndroidManifest.xml index 4e51f10..44a78a6 100644 --- a/common/car/src/main/AndroidManifest.xml +++ b/common/car/src/main/AndroidManifest.xml @@ -32,14 +32,8 @@ - - diff --git a/common/car/src/main/ic_delete-playstore.png b/common/car/src/main/ic_delete-playstore.png new file mode 100644 index 0000000..60f9cbd Binary files /dev/null and b/common/car/src/main/ic_delete-playstore.png differ diff --git a/common/car/src/main/java/com/kouros/navigation/car/MapView.kt b/common/car/src/main/java/com/kouros/navigation/car/MapView.kt index 265c50f..0816689 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/MapView.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/MapView.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.drawText @@ -115,12 +116,15 @@ fun BuildingLayer(tiles: Source) { @Composable fun DrawImage(padding: PaddingValues, location: Location, width: Int, height: Int, street: String) { - NavigationImage(padding, street) + NavigationImage(padding, width,height, street) Speed(width, height, location) } @Composable -fun NavigationImage(padding: PaddingValues, street: String) { +fun NavigationImage(padding: PaddingValues, width: Int, height: Int, street: String) { + + val imageSize = (height/6) + println("Image Size: $imageSize") val vector = ImageVector.vectorResource(id = R.drawable.assistant_navigation_48px) val color = remember { NavigationColor } BadgedBox( @@ -131,11 +135,18 @@ fun NavigationImage(padding: PaddingValues, street: String) { } ) { Icon( - modifier = Modifier.size(72.dp, 72.dp), - imageVector = vector, - contentDescription = "Navigation", - tint = color + painter = painterResource(id = R.drawable.navigation), + "Navigation", + tint = color, + modifier = Modifier.size(imageSize.dp, imageSize.dp), ) + +// Icon( +// modifier = Modifier.size(72.dp, 72.dp), +// imageVector = vector, +// contentDescription = "Navigation", +// tint = color +// ) if (street.isNotEmpty()) Text(text = street) } @@ -209,13 +220,12 @@ fun getPaddingValues(width: Int, height: Int, preView: Boolean): PaddingValues { return if (preView) { PaddingValues(start = 150.dp, bottom = 0.dp) } else { -// PaddingValues(start = width.dp, top = distanceFromTop(height).dp) - PaddingValues(start = 0.dp, top = distanceFromTop(height).dp) + PaddingValues(start = 50.dp, top = distanceFromTop(height).dp) } } fun distanceFromTop(height: Int): Int { - return height - percent(height, 25) + return height - percent(height, 40) } fun percent(maxValue: Int, value: Int): Int { diff --git a/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt b/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt index 41afc46..72f0857 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt @@ -25,12 +25,12 @@ 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 class NavigationSession : Session(), NavigationScreen.Listener { - val uriScheme = "samples"; - val uriHost = "navigation"; + val useContacts = false lateinit var routeModel: RouteCarModel; @@ -81,9 +81,9 @@ class NavigationSession : Session(), NavigationScreen.Listener { navigationScreen = NavigationScreen(carContext, surfaceRenderer, routeModel, this) if (carContext.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED - && carContext.checkSelfPermission(Manifest.permission.READ_CONTACTS) - == PackageManager.PERMISSION_GRANTED + == PackageManager.PERMISSION_GRANTED && !useContacts + || (useContacts && carContext.checkSelfPermission(Manifest.permission.READ_CONTACTS) + == PackageManager.PERMISSION_GRANTED) ) { requestLocationUpdates() } else { @@ -166,8 +166,7 @@ class NavigationSession : Session(), NavigationScreen.Listener { navigationScreen.calculateNewRoute(routeModel.destination) return } - routeModel.updateLocation(location) - navigationScreen.updateTrip() + navigationScreen.updateTrip(location) if (distance < MAXIMAL_SNAP_CORRECTION) { surfaceRenderer.updateLocation(snapedLocation) } else { @@ -181,4 +180,10 @@ class NavigationSession : Session(), NavigationScreen.Listener { override fun stopNavigation() { routeModel.stopNavigation() } + + companion object { + var uriHost: String = "navigation" + + var uriScheme: String = "samples" + } } \ No newline at end of file diff --git a/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt b/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt index a70cfe3..c5c7f9d 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt @@ -11,6 +11,7 @@ import androidx.car.app.AppManager import androidx.car.app.CarContext import androidx.car.app.SurfaceCallback import androidx.car.app.SurfaceContainer +import androidx.car.app.connection.CarConnection import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.Composable @@ -27,8 +28,10 @@ import androidx.savedstate.setViewTreeSavedStateRegistryOwner import com.kouros.navigation.car.navigation.RouteCarModel import com.kouros.navigation.data.Constants import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING +import com.kouros.navigation.data.ObjectBox import com.kouros.navigation.model.RouteModel import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue +import com.kouros.navigation.utils.bearing import com.kouros.navigation.utils.calculateZoom import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.CameraState @@ -160,17 +163,22 @@ class SurfaceRenderer( lifecycle.addObserver(this) } + fun onConnectionStateUpdated(connectionState: Int) { + when(connectionState) { + CarConnection.CONNECTION_TYPE_NATIVE -> ObjectBox.init(carContext) + } + } + @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 paddingValues = getPaddingValues( width - stateWidth.value!!.width(), height, 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( + val baseStyle =if (isSystemInDarkTheme()) BaseStyle.Uri(Constants.STYLE_DARK) else BaseStyle.Uri( Constants.STYLE ) MaplibreMap( @@ -189,7 +197,11 @@ class SurfaceRenderer( } @Composable - fun ShowPosition(cameraState: CameraState, position: CameraPosition?, paddingValues: PaddingValues) { + fun ShowPosition( + cameraState: CameraState, + position: CameraPosition?, + paddingValues: PaddingValues + ) { val cameraDuration = duration(position) var bearing = position!!.bearing var zoom = position.zoom @@ -197,9 +209,9 @@ class SurfaceRenderer( var localTilt = tilt if (!preview) { if (routeModel.isNavigating()) { - DrawImage(paddingValues, lastLocation, width, height,"") + DrawImage(paddingValues, lastLocation, width, height, "") } else { - DrawImage(paddingValues, lastLocation,width, height, "") + DrawImage(paddingValues, lastLocation, width, height, "") } } else { bearing = 0.0 @@ -222,6 +234,7 @@ class SurfaceRenderer( } override fun onCreate(owner: LifecycleOwner) { + CarConnection(carContext).type.observe(owner, ::onConnectionStateUpdated) Log.i(TAG, "SurfaceRenderer created") carContext.getCarService(AppManager::class.java) .setSurfaceCallback(mSurfaceCallback) @@ -260,11 +273,7 @@ class SurfaceRenderer( fun updateLocation(location: Location) { synchronized(this) { if (!preview) { - val bearing = if (routeModel.isNavigating()) { - routeModel.currentStep().bearing - } else { - lastLocation.bearingTo(location).toInt().toDouble().absoluteValue - } + val bearing = bearing(lastLocation, location) val zoom = if (!panView) { calculateZoom(location.speed.toDouble()) } else { @@ -278,10 +287,9 @@ class SurfaceRenderer( lastBearing = cameraPosition.value!!.bearing lastLocation = location } else { - val bearing = 0.0 val zoom = previewZoom() updateCameraPosition( - bearing, + 0.0, zoom, Position(centerLocation.longitude, centerLocation.latitude) ) @@ -295,7 +303,7 @@ class SurfaceRenderer( bearing = bearing, zoom = zoom, tilt = 0.0, - padding = getPaddingValues(width-visibleArea.value!!.width(), height, preview), + padding = getPaddingValues(width - visibleArea.value!!.width(), height, preview), target = target ) ) diff --git a/common/car/src/main/java/com/kouros/navigation/car/navigation/RouteCarModel.kt b/common/car/src/main/java/com/kouros/navigation/car/navigation/RouteCarModel.kt index 936a762..288a489 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/navigation/RouteCarModel.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/navigation/RouteCarModel.kt @@ -209,8 +209,8 @@ class RouteCarModel() : RouteModel() { ) .setRemainingTimeColor(CarColor.YELLOW) .setRemainingDistanceColor(CarColor.RED) - //.setTripText(createCarText(carContext,R.string.travel_est_trip_text)) - .setTripIcon(createCarIcon(carContext, R.drawable.ic_close_white_24dp)) + //.setTripText(createCarText(carContext,R.string.navigate)) + //.setTripIcon(createCarIcon(carContext, R.drawable.navigation_48px)) .build() } diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt index bcd1b74..858786c 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt @@ -28,7 +28,6 @@ import androidx.lifecycle.Observer import com.kouros.android.cars.carappservice.R import com.kouros.navigation.car.NavigationCarAppService import com.kouros.navigation.car.SurfaceRenderer -import com.kouros.navigation.car.navigation.NavigationMessage import com.kouros.navigation.car.navigation.RouteCarModel import com.kouros.navigation.data.NavigationRepository import com.kouros.navigation.data.Place @@ -288,7 +287,7 @@ class NavigationScreen( .build() ) .setOnClickListener { - val navigateTo = location(recentPlace.latitude, recentPlace.longitude) + val navigateTo = location(recentPlace.longitude, recentPlace.latitude) viewModel.loadRoute(carContext, surfaceRenderer.lastLocation, navigateTo) routeModel.destination = recentPlace } @@ -443,11 +442,12 @@ class NavigationScreen( } fun reRoute(destination: Place) { - val dest = location(destination.latitude, destination.longitude) + val dest = location( destination.longitude, destination.latitude) viewModel.loadRoute(carContext, surfaceRenderer.lastLocation, dest) } - fun updateTrip() { + fun updateTrip(location: Location) { + routeModel.updateLocation(location) if (routeModel.maneuverType == Maneuver.TYPE_DESTINATION && routeModel.leftStepDistance() * 1000 < 25.0) { routeModel.arrived = true routeModel.stopNavigation() diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt index 78e4800..76d7c14 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt @@ -34,7 +34,7 @@ import com.kouros.navigation.model.ViewModel class PlaceListScreen( private val carContext: CarContext, private val surfaceRenderer: SurfaceRenderer, - location: Location, + private val location: Location, private val category: String ) : Screen(carContext) { @@ -45,6 +45,7 @@ class PlaceListScreen( places = newPlaces invalidate() } + val observerAddress = Observer> { newContacts -> places = newContacts invalidate() @@ -53,17 +54,30 @@ class PlaceListScreen( init { if (category == Constants.RECENT) { viewModel.places.observe(this, observer) - viewModel.loadPlaces(carContext, location) } if (category == Constants.CONTACTS) { viewModel.contactAddress.observe(this, observerAddress) - viewModel.loadContacts(carContext, location) } + if (category == Constants.FAVORITES) { + viewModel.favorites.observe(this, observer) + } + loadPlaces() } + fun loadPlaces() { + if (category == Constants.RECENT) { + viewModel.loadPlaces(carContext, location) + } + if (category == Constants.CONTACTS) { + viewModel.loadContacts(carContext, location) + } + if (category == Constants.FAVORITES) { + viewModel.loadFavorites(carContext, location) + } + } override fun onGetTemplate(): Template { val itemListBuilder = ItemList.Builder() - .setNoItemsMessage("No places to show") + .setNoItemsMessage(carContext.getString(R.string.no_places)) places.forEach { itemListBuilder.addItem( Row.Builder() @@ -111,10 +125,11 @@ class PlaceListScreen( .build() ) } - val title = if (category == Constants.RECENT) { - carContext.getString(R.string.recent_destinations) - } else { - carContext.getString(R.string.contacts) + var title = "" + when(category) { + Constants.RECENT -> title = carContext.getString(R.string.recent_destinations) + Constants.CONTACTS -> title = carContext.getString(R.string.contacts) + Constants.FAVORITES -> title = carContext.getString(R.string.favorites) } val header = Header.Builder() .setStartHeaderAction(Action.BACK) @@ -131,16 +146,16 @@ class PlaceListScreen( .setIcon( RouteCarModel().createCarIcon( carContext, - R.drawable.ic_close_white_24dp + R.drawable.ic_delete_foreground ) ) .setOnClickListener { - viewModel.deleteRecent(place) + viewModel.deletePlace(place) CarToast.makeText( carContext, R.string.recent_Item_deleted, CarToast.LENGTH_LONG ).show() - invalidate() + loadPlaces() } .build() diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt index d48ce93..5793fad 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt @@ -15,6 +15,7 @@ */ package com.kouros.navigation.car.screen +import android.graphics.drawable.Icon import android.location.Location import android.location.LocationManager import android.os.CountDownTimer @@ -77,11 +78,10 @@ class RoutePreviewScreen( val location = Location(LocationManager.GPS_PROVIDER) location.latitude = destination.latitude location.longitude = destination.longitude - vieModel.loadPreviewRoute(carContext,surfaceRenderer.lastLocation, location) + vieModel.loadPreviewRoute(carContext, surfaceRenderer.lastLocation, location) } override fun onGetTemplate(): Template { - // Adjust the item limit according to the car constrains. mItemLimit = carContext.getCarService(ConstraintManager::class.java) .getContentLimit( @@ -127,7 +127,7 @@ class RoutePreviewScreen( carContext, if (mIsFavorite) carContext - .getString(R.string.favorite_toast_msg) + .getString(R.string.favorites) else carContext.getString( R.string.not_favorite_toast_msg @@ -135,18 +135,26 @@ class RoutePreviewScreen( CarToast.LENGTH_SHORT ) .show() + vieModel.saveFavorite(destination) + println(destination) invalidate() } .build() ) .addEndHeaderAction( Action.Builder() - .setOnClickListener { finish() } + .setOnClickListener { + if (mIsFavorite) { + vieModel.deleteFavorite(destination) + } + mIsFavorite = !mIsFavorite + finish() + } .setIcon( CarIcon.Builder( IconCompat.createWithResource( carContext, - R.drawable.ic_close_white_24dp + R.drawable.ic_delete_foreground ) ) .build() @@ -155,7 +163,7 @@ class RoutePreviewScreen( ) .build() - val timer = object: CountDownTimer(10000, 15000) { + val timer = object : CountDownTimer(10000, 15000) { override fun onTick(millisUntilFinished: Long) {} override fun onFinish() { onNavigate() @@ -183,7 +191,7 @@ class RoutePreviewScreen( return Row.Builder() .setTitle(route) .setOnClickListener { onRouteSelected(index) } - .addText( "${destination.street!!} ${destination.postalCode} ${destination.city}") + .addText("${destination.street!!} ${destination.postalCode} ${destination.city}") .addAction(action) .build() } @@ -194,7 +202,7 @@ class RoutePreviewScreen( val length = BigDecimal(routeModel.route.distance).setScale(1, RoundingMode.HALF_EVEN) val firstRoute = SpannableString(" \u00b7 $length km") firstRoute.setSpan( - DurationSpan.create(time.toLong()), 0, 1,0 + DurationSpan.create(time.toLong()), 0, 1, 0 ) return CarText.Builder(firstRoute) .build() diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/SearchScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/SearchScreen.kt index 218b6bf..ca519af 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/SearchScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/SearchScreen.kt @@ -31,7 +31,8 @@ class SearchScreen( var categories: List = listOf( Category(id = Constants.RECENT, name = carContext.getString(R.string.recent_destinations)), - Category(id = Constants.CONTACTS, name = carContext.getString(R.string.contacts)) + Category(id = Constants.CONTACTS, name = carContext.getString(R.string.contacts)), + Category(id = Constants.FAVORITES, name = carContext.getString(R.string.favorites)) ) lateinit var searchResult: List diff --git a/common/car/src/main/res/drawable-v24/ic_launcher_foreground.xml b/common/car/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d1..0000000 --- a/common/car/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/common/car/src/main/res/drawable/ic_delete_background.xml b/common/car/src/main/res/drawable/ic_delete_background.xml new file mode 100644 index 0000000..ca3826a --- /dev/null +++ b/common/car/src/main/res/drawable/ic_delete_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/car/src/main/res/drawable/ic_delete_foreground.xml b/common/car/src/main/res/drawable/ic_delete_foreground.xml new file mode 100644 index 0000000..e153c58 --- /dev/null +++ b/common/car/src/main/res/drawable/ic_delete_foreground.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/common/car/src/main/res/drawable/ic_launcher.xml b/common/car/src/main/res/drawable/ic_launcher.xml deleted file mode 100644 index 20357f9..0000000 --- a/common/car/src/main/res/drawable/ic_launcher.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/common/car/src/main/res/drawable/ic_launcher_background.xml b/common/car/src/main/res/drawable/ic_launcher_background.xml index 07d5da9..ca3826a 100644 --- a/common/car/src/main/res/drawable/ic_launcher_background.xml +++ b/common/car/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,74 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns:android="http://schemas.android.com/apk/res/android"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/car/src/main/res/drawable/navigation.png b/common/car/src/main/res/drawable/navigation.png new file mode 100644 index 0000000..7ebe828 Binary files /dev/null and b/common/car/src/main/res/drawable/navigation.png differ diff --git a/common/car/src/main/res/mipmap-anydpi-v26/ic_delete.xml b/common/car/src/main/res/mipmap-anydpi-v26/ic_delete.xml new file mode 100644 index 0000000..c76661e --- /dev/null +++ b/common/car/src/main/res/mipmap-anydpi-v26/ic_delete.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/common/car/src/main/res/mipmap-anydpi-v26/ic_delete_round.xml b/common/car/src/main/res/mipmap-anydpi-v26/ic_delete_round.xml new file mode 100644 index 0000000..c76661e --- /dev/null +++ b/common/car/src/main/res/mipmap-anydpi-v26/ic_delete_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/common/car/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/common/car/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index eca70cf..bbd3e02 100644 --- a/common/car/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/common/car/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/common/car/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/common/car/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index eca70cf..bbd3e02 100644 --- a/common/car/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/common/car/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/common/car/src/main/res/mipmap-hdpi/ic_delete.webp b/common/car/src/main/res/mipmap-hdpi/ic_delete.webp new file mode 100644 index 0000000..d991c89 Binary files /dev/null and b/common/car/src/main/res/mipmap-hdpi/ic_delete.webp differ diff --git a/common/car/src/main/res/mipmap-hdpi/ic_delete_round.webp b/common/car/src/main/res/mipmap-hdpi/ic_delete_round.webp new file mode 100644 index 0000000..9bb57ba Binary files /dev/null and b/common/car/src/main/res/mipmap-hdpi/ic_delete_round.webp differ diff --git a/common/car/src/main/res/mipmap-hdpi/ic_launcher.webp b/common/car/src/main/res/mipmap-hdpi/ic_launcher.webp index c209e78..da24c35 100644 Binary files a/common/car/src/main/res/mipmap-hdpi/ic_launcher.webp and b/common/car/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/common/car/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/common/car/src/main/res/mipmap-hdpi/ic_launcher_round.webp index b2dfe3d..2850a90 100644 Binary files a/common/car/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/common/car/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/common/car/src/main/res/mipmap-mdpi/ic_delete.webp b/common/car/src/main/res/mipmap-mdpi/ic_delete.webp new file mode 100644 index 0000000..51311ea Binary files /dev/null and b/common/car/src/main/res/mipmap-mdpi/ic_delete.webp differ diff --git a/common/car/src/main/res/mipmap-mdpi/ic_delete_round.webp b/common/car/src/main/res/mipmap-mdpi/ic_delete_round.webp new file mode 100644 index 0000000..27bd006 Binary files /dev/null and b/common/car/src/main/res/mipmap-mdpi/ic_delete_round.webp differ diff --git a/common/car/src/main/res/mipmap-mdpi/ic_launcher.webp b/common/car/src/main/res/mipmap-mdpi/ic_launcher.webp index 4f0f1d6..8042972 100644 Binary files a/common/car/src/main/res/mipmap-mdpi/ic_launcher.webp and b/common/car/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/common/car/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/common/car/src/main/res/mipmap-mdpi/ic_launcher_round.webp index 62b611d..940caf5 100644 Binary files a/common/car/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/common/car/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/common/car/src/main/res/mipmap-xhdpi/ic_delete.webp b/common/car/src/main/res/mipmap-xhdpi/ic_delete.webp new file mode 100644 index 0000000..4e2031e Binary files /dev/null and b/common/car/src/main/res/mipmap-xhdpi/ic_delete.webp differ diff --git a/common/car/src/main/res/mipmap-xhdpi/ic_delete_round.webp b/common/car/src/main/res/mipmap-xhdpi/ic_delete_round.webp new file mode 100644 index 0000000..d5c635e Binary files /dev/null and b/common/car/src/main/res/mipmap-xhdpi/ic_delete_round.webp differ diff --git a/common/car/src/main/res/mipmap-xhdpi/ic_launcher.webp b/common/car/src/main/res/mipmap-xhdpi/ic_launcher.webp index 948a307..c52ae69 100644 Binary files a/common/car/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/common/car/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/common/car/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/common/car/src/main/res/mipmap-xhdpi/ic_launcher_round.webp index 1b9a695..56b8e2b 100644 Binary files a/common/car/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/common/car/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/common/car/src/main/res/mipmap-xxhdpi/ic_delete.webp b/common/car/src/main/res/mipmap-xxhdpi/ic_delete.webp new file mode 100644 index 0000000..3cbf6d0 Binary files /dev/null and b/common/car/src/main/res/mipmap-xxhdpi/ic_delete.webp differ diff --git a/common/car/src/main/res/mipmap-xxhdpi/ic_delete_round.webp b/common/car/src/main/res/mipmap-xxhdpi/ic_delete_round.webp new file mode 100644 index 0000000..aa08b89 Binary files /dev/null and b/common/car/src/main/res/mipmap-xxhdpi/ic_delete_round.webp differ diff --git a/common/car/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/common/car/src/main/res/mipmap-xxhdpi/ic_launcher.webp index 28d4b77..284db5a 100644 Binary files a/common/car/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/common/car/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/common/car/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/common/car/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp index 9287f50..2f729db 100644 Binary files a/common/car/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/common/car/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/common/car/src/main/res/mipmap-xxxhdpi/ic_delete.webp b/common/car/src/main/res/mipmap-xxxhdpi/ic_delete.webp new file mode 100644 index 0000000..1aae1c1 Binary files /dev/null and b/common/car/src/main/res/mipmap-xxxhdpi/ic_delete.webp differ diff --git a/common/car/src/main/res/mipmap-xxxhdpi/ic_delete_round.webp b/common/car/src/main/res/mipmap-xxxhdpi/ic_delete_round.webp new file mode 100644 index 0000000..b5a8d51 Binary files /dev/null and b/common/car/src/main/res/mipmap-xxxhdpi/ic_delete_round.webp differ diff --git a/common/car/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/common/car/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index aa7d642..9b5e24c 100644 Binary files a/common/car/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/common/car/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/common/car/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/common/car/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index 9126ae3..56a171b 100644 Binary files a/common/car/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/common/car/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/common/car/src/main/res/values-de/strings.xml b/common/car/src/main/res/values-de/strings.xml index eeb15f0..d7acf7b 100644 --- a/common/car/src/main/res/values-de/strings.xml +++ b/common/car/src/main/res/values-de/strings.xml @@ -43,8 +43,7 @@ "Nein" "Herangezoomt" "Herausgezoomt" - "Ausgelöst" - "Favorit!" + "Favoriten" "Kein Favorit!" "Navigation angefragt" "Ausgewählte Route" @@ -166,19 +165,7 @@ "Demo der langen Nachrichtenvorlage" "Dein Host unterstützt keine lange Nachrichtenvorlage" "Inkompatibler Host" - "Demo der Nachrichtenvorlage" - "Nachricht wird hier angezeigt.\nMehr Text in der zweiten Zeile." - "Demo der kurzen Nachrichtenvorlage" - "Demo für Elementvorlage mit Abschnitten" - "Abschnitt „Optionsfeld“" - "Abschnitt wechseln" - "Abschnitt „Viele Zeilen“" - "Bereich für Rasterelement" - "Demo der Bereichsvorlage" - "Demo der Ortslistenvorlage" - "Orte durchsuchen" - "Suchvorlagendemo" - "Hier suchen" + "Keine Orte" "Bitte lies unsere ""Nutzungsbedingungen" "Google Log-in" "PIN nutzen" @@ -306,10 +293,10 @@ "Ladebildschirm" "Schieberegler zum Hinzufügen/Entfernen von Farben" "Kartenvorlage mit Ein-/Aus-Schaltflächen" - "Mautstraßen vermeiden" + "Mautstraßen meiden" "Routenoptionen" "Autobahnen meiden" - "Fähren vermeiden" + "Fähren meiden" "Kartenbezogene Demos" "Demos von Karten mit Inhalten" "Karte mit Demo der Nachrichtenvorlage" diff --git a/common/car/src/main/res/values/strings.xml b/common/car/src/main/res/values/strings.xml index f110b40..fa2c99d 100644 --- a/common/car/src/main/res/values/strings.xml +++ b/common/car/src/main/res/values/strings.xml @@ -45,8 +45,7 @@ Zoomed in Zoomed out - Triggered - Favorite! + Favorites Not a favorite! Navigation Requested Selected route @@ -55,7 +54,6 @@ Parked action Clicked More Grant location Permission to see current location - Changed selection to index @@ -212,28 +210,9 @@ Your host doesn\'t support Long Message template Incompatible host - - Message Template Demo - Message goes here.\nMore text on second line. - Short Message Template Demo - - Sectioned Item Template Demo - Radio Button Section - Toggle Section - Lots of Rows Section - Grid Item Section + No Places - - Pane Template Demo - - - Place List Template Demo - Browse Places - - - Search Template Demo - Search here Please review our terms of service diff --git a/common/data/src/main/java/com/kouros/navigation/data/Color.kt b/common/data/src/main/java/com/kouros/navigation/data/Color.kt index 81283bf..eaf2d4c 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Color.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Color.kt @@ -2,7 +2,7 @@ package com.kouros.navigation.data import androidx.compose.ui.graphics.Color -val NavigationColor = Color(0xFF052086) +val NavigationColor = Color(0xFF368605) val RouteColor = Color(0xFF5582D0) diff --git a/common/data/src/main/java/com/kouros/navigation/data/Data.kt b/common/data/src/main/java/com/kouros/navigation/data/Data.kt index 898595c..1c373cf 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Data.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Data.kt @@ -146,6 +146,8 @@ object Constants { const val RECENT: String = "Recent" + const val FAVORITES: String = "Favorites" + /** The initial location to use as an anchor for searches. */ val homeLocation: Location = Location(LocationManager.GPS_PROVIDER) val home2Location: Location = Location(LocationManager.GPS_PROVIDER) diff --git a/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt b/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt index 960ab2e..87cf7ec 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt @@ -18,6 +18,7 @@ package com.kouros.navigation.data import android.location.Location import com.kouros.navigation.model.RouteModel +import com.kouros.navigation.utils.NavigationUtils.getBoundingBox import org.json.JSONArray import java.net.Authenticator import java.net.HttpURLConnection @@ -62,8 +63,14 @@ class NavigationRepository { return routeModel.route.distance } - fun searchPlaces(search : String) : String { - return fetchUrl("${nominatimUrl}search?q=$search&format=jsonv2&addressdetails=true&countrycodes=de", false) + fun searchPlaces(search: String, location: Location) : String { +// val bbox = getBoundingBox(location.longitude, location.latitude, 10.0) +// val neLon = bbox["ne"]?.get("lon") +// val neLat = bbox["ne"]?.get("lat") +// val swLon = bbox["sw"]?.get("lon") +// val swLat = bbox["sw"]?.get("lat") +// val viewbox = "&viewbox=$swLon,$swLat,$neLon,$neLat" + return fetchUrl("${nominatimUrl}search?q=$search&format=jsonv2&addressdetails=true,&countrycodes=de", false) } fun reverseAddress(location: Location) : String { diff --git a/common/data/src/main/java/com/kouros/navigation/data/Route.kt b/common/data/src/main/java/com/kouros/navigation/data/Route.kt index 0e5ce48..67b8d10 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Route.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Route.kt @@ -97,7 +97,8 @@ data class Route ( } else { currentManeuver().endShapeIndex + 1 } - return pointLocations.subList(beginShapeIndex, endShapeIndex) + //return pointLocations.subList(beginShapeIndex, endShapeIndex) + return pointLocations } fun clear() { diff --git a/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt b/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt index b19cc0a..b0b6ee3 100644 --- a/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt +++ b/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt @@ -10,8 +10,6 @@ import com.kouros.navigation.utils.location import org.maplibre.geojson.FeatureCollection import org.maplibre.geojson.Point import org.maplibre.turf.TurfMeasurement -import org.maplibre.turf.TurfMisc -import kotlin.math.absoluteValue import kotlin.math.roundToInt open class RouteModel() { @@ -28,7 +26,7 @@ open class RouteModel() { /* current shapeIndex */ - private var currentShapeIndex = 0 + var currentShapeIndex = 0 var distanceToStepEnd = 0F @@ -53,7 +51,7 @@ open class RouteModel() { val future = TurfMeasurement.center(FeatureCollection.fromJson(route.routeGeoJson)) val point = future.geometry() as Point - return location(point.latitude(), point.longitude()) + return location(point.longitude(), point.latitude()) } val currentDistance: Double @@ -85,16 +83,16 @@ open class RouteModel() { text = maneuver.streetNames[0] } val curLocation = location( - route.pointLocations[currentShapeIndex].latitude(), - route.pointLocations[currentShapeIndex].longitude() + route.pointLocations[currentShapeIndex].longitude(), + route.pointLocations[currentShapeIndex].latitude() ) - if (currentShapeIndex < route.pointLocations.size) { - val nextLocation = location( - route.pointLocations[currentShapeIndex + 1].latitude(), - route.pointLocations[currentShapeIndex + 1].longitude() - ) - bearing = curLocation.bearingTo(nextLocation).absoluteValue - } +// if (currentShapeIndex < route.pointLocations.size) { +// val nextLocation = location( +// route.pointLocations[currentShapeIndex + 1].latitude(), +// route.pointLocations[currentShapeIndex + 1].longitude() +// ) +// bearing = curLocation.bearingTo(nextLocation) +// } val distanceStepLeft = leftStepDistance() * 1000 when (distanceStepLeft) { in 0.0..NEXT_STEP_THRESHOLD -> { diff --git a/common/data/src/main/java/com/kouros/navigation/model/ViewModel.kt b/common/data/src/main/java/com/kouros/navigation/model/ViewModel.kt index 628bf54..98620b1 100644 --- a/common/data/src/main/java/com/kouros/navigation/model/ViewModel.kt +++ b/common/data/src/main/java/com/kouros/navigation/model/ViewModel.kt @@ -40,6 +40,10 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { MutableLiveData>() } + val favorites: MutableLiveData> by lazy { + MutableLiveData>() + } + val searchPlaces: MutableLiveData> by lazy { MutableLiveData>() } @@ -60,7 +64,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { val results = query.find() query.close() for (place in results) { - val plLocation = location(place.latitude, place.longitude) + val plLocation = location(place.longitude,place.latitude) // val distance = repository.getRouteDistance(location, plLocation) //place.distance = distance.toFloat() if (place.distance == 0F) { @@ -78,13 +82,13 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { try { val placeBox = boxStore.boxFor(Place::class) val query = placeBox - .query(Place_.name.notEqual("")) + .query(Place_.name.notEqual("").and(Place_.category.equal(Constants.RECENT))) .orderDesc(Place_.lastDate) .build() val results = query.find() query.close() for (place in results) { - val plLocation = location(place.latitude, place.longitude) + val plLocation = location(place.longitude, place.latitude) val distance = repository.getRouteDistance(location, plLocation, getSearchFilter(context)) place.distance = distance.toFloat() } @@ -95,6 +99,28 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { } } + fun loadFavorites(context: Context, location: Location) { + viewModelScope.launch(Dispatchers.IO) { + try { + val placeBox = boxStore.boxFor(Place::class) + val query = placeBox + .query(Place_.name.notEqual("").and(Place_.category.equal(Constants.FAVORITES))) + .orderDesc(Place_.lastDate) + .build() + val results = query.find() + query.close() + for (place in results) { + val plLocation = location(place.longitude, place.latitude ) + val distance = repository.getRouteDistance(location, plLocation, getSearchFilter(context)) + place.distance = distance.toFloat() + } + favorites.postValue(results) + } catch (e: Exception) { + e.printStackTrace() + } + } + } + fun loadRoute(context: Context, currentLocation: Location, location: Location) { viewModelScope.launch(Dispatchers.IO) { try { @@ -129,7 +155,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { ) { for (adr in it) { if (addressLines.size > 1) { - val plLocation = location(adr.latitude, adr.longitude) + val plLocation = location( adr.longitude, adr.latitude) val distance = repository.getRouteDistance(currentLocation, plLocation, getSearchFilter(context)) contactList.add( @@ -159,13 +185,13 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { fun searchPlaces(search: String, location: Location) { viewModelScope.launch(Dispatchers.IO) { - val placesJson = repository.searchPlaces(search) + val placesJson = repository.searchPlaces(search, location) val gson = GsonBuilder().serializeNulls().create() val places = gson.fromJson(placesJson, Search::class.java) val distPlaces = mutableListOf() places.forEach { val plLocation = - location(latitude = it.lat.toDouble(), longitude = it.lon.toDouble()) + location(longitude = it.lon.toDouble(), latitude = it.lat.toDouble()) val distance = plLocation.distanceTo(location) it.distance = distance distPlaces.add(it) @@ -183,13 +209,20 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { return place.address.road } + fun saveFavorite(place: Place) { + place.category = Constants.FAVORITES + savePlace(place) + } fun saveRecent(place: Place) { + place.category = Constants.RECENT + savePlace(place) + } + fun savePlace(place: Place) { viewModelScope.launch(Dispatchers.IO) { - place.category = Constants.RECENT try { val placeBox = boxStore.boxFor(Place::class) val query = placeBox - .query(Place_.name.equal(place.name!!)) + .query(Place_.name.equal(place.name!!).and(Place_.category.equal(place.category!!))) .build() val results = query.find() query.close() @@ -205,13 +238,21 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { } } + fun deleteFavorite(place: Place) { + place.category = Constants.FAVORITES + deletePlace(place) + } + fun deleteRecent(place: Place) { + place.category = Constants.RECENT + deletePlace(place) + } + fun deletePlace(place: Place) { viewModelScope.launch(Dispatchers.IO) { - place.category = Constants.RECENT try { val placeBox = boxStore.boxFor(Place::class) val query = placeBox - .query(Place_.name.equal(place.name!!)) + .query(Place_.name.equal(place.name!!).and(Place_.category.equal(place.category!!))) .build() val results = query.find() query.close() diff --git a/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt b/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt index c7169a9..c7fa1fd 100644 --- a/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt +++ b/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt @@ -3,27 +3,15 @@ package com.kouros.navigation.utils import android.content.Context import android.location.Location import android.location.LocationManager -import android.os.Build -import androidx.annotation.RequiresApi import androidx.core.content.edit -import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION import com.kouros.navigation.data.Constants.SHARED_PREF_KEY -import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING import com.kouros.navigation.data.GeoJsonFeature import com.kouros.navigation.data.GeoJsonFeatureCollection import com.kouros.navigation.data.GeoJsonLineString import kotlinx.serialization.json.Json -import org.maplibre.geojson.Feature -import org.maplibre.geojson.FeatureCollection -import org.maplibre.geojson.LineString import org.maplibre.geojson.Point -import org.maplibre.turf.TurfClassification -import org.maplibre.turf.TurfConversion -import org.maplibre.turf.TurfJoins -import org.maplibre.turf.TurfMeasurement -import org.maplibre.turf.TurfMeta import org.maplibre.turf.TurfMisc -import org.maplibre.turf.TurfTransformation +import org.maplibre.turf.TurfMeasurement import java.lang.Math.toDegrees import java.lang.Math.toRadians import kotlin.math.asin @@ -45,7 +33,6 @@ object NavigationUtils { .getBoolean(key, false) } - @RequiresApi(Build.VERSION_CODES.GINGERBREAD) fun setBooleanKeyValue(context: Context, `val`: Boolean, key: String) { context .getSharedPreferences( @@ -60,18 +47,13 @@ object NavigationUtils { } } fun snapLocation(location: Location, stepCoordinates: List) : Location { - val newLocation = location(latitude = location.latitude, longitude = location.longitude) + val newLocation = Location(location) val oldPoint = Point.fromLngLat(location.longitude, location.latitude) if (stepCoordinates.size > 1) { val pointFeature = TurfMisc.nearestPointOnLine(oldPoint, stepCoordinates) val point = pointFeature.geometry() as Point newLocation.latitude = point.latitude() newLocation.longitude = point.longitude() - newLocation.speed = location.speed - newLocation.bearing = location.bearing - newLocation.time = location.time - newLocation.accuracy = location.accuracy - newLocation.altitude = location.altitude } return newLocation } @@ -129,10 +111,10 @@ object NavigationUtils { radius: Double ): Map> { val earthRadius = 6371.0 - val maxLat = lat + Math.toDegrees(radius / earthRadius) - val minLat = lat - Math.toDegrees(radius / earthRadius) - val maxLon = lon + Math.toDegrees(radius / earthRadius / cos(Math.toRadians(lat))) - val minLon = lon - Math.toDegrees(radius / earthRadius / cos(Math.toRadians(lat))) + val maxLat = lat + toDegrees(radius / earthRadius) + val minLat = lat - toDegrees(radius / earthRadius) + val maxLon = lon + toDegrees(radius / earthRadius / cos(toRadians(lat))) + val minLon = lon - toDegrees(radius / earthRadius / cos(toRadians(lat))) return mapOf( "nw" to mapOf("lat" to maxLat, "lon" to minLon), @@ -182,8 +164,12 @@ fun calculateZoom(speed: Double?): Double { } return zoom.toDouble() } +fun bearing(fromLocation: Location, toLocation: Location ) : Double { + val bearing = fromLocation.bearingTo(toLocation).toInt().toDouble() + return bearing +} -fun location(latitude: Double, longitude: Double): Location { +fun location(longitude : Double, latitude: Double): Location { val location = Location(LocationManager.GPS_PROVIDER) location.longitude = longitude location.latitude = latitude diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3df4f51..934646d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -17,6 +17,7 @@ composeBom = "2025.11.01" appcompat = "1.7.1" material = "1.13.0" carApp = "1.7.0" +androidx-car = "1.7.0-beta01" objectboxKotlin = "5.0.1" objectboxProcessor = "5.0.1" ui = "1.9.5" @@ -71,6 +72,7 @@ androidx-navigation-compose = { group = "androidx.navigation", name = "navigatio androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview", version.ref = "uiToolingPreview" } androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "uiTooling" } androidx-compose-material3-window-size-class1 = { group = "androidx.compose.material3", name = "material3-window-size-class", version.ref = "material3WindowSizeClass" } +androidx-app-automotive = { module = "androidx.car.app:app-automotive", version.ref = "androidx-car" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } diff --git a/settings.gradle.kts b/settings.gradle.kts index e8a721d..4078229 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -30,3 +30,4 @@ include( ) +include(":automotive")