Skip to content

Commit 5956dee

Browse files
committed
fix!: upgrade to Maps SDK v20 and resolve build issues
- Upgrade Google Maps SDK to v20.0.0 (BREAKING CHANGE: requires new renderer). - Fix WearOS build by replacing deprecated kotlinOptions with jvmToolchain. - Resolve WearOS dependency conflicts by using Kotlin BOM. - Migrate WearOS dependencies and SDK versions to Version Catalog. - Refactor Version Catalog: extract versions and organize groups. - Fix FireMarkers sample: correct Google Services plugin application logic. - FireMarkers: Add explicit error handling for 'Permission Denied'. BREAKING CHANGE: This release upgrades the Maps SDK to v20.0.0, which may require code changes for the new renderer and other API adjustments.
1 parent f128137 commit 5956dee

File tree

14 files changed

+154
-109
lines changed

14 files changed

+154
-109
lines changed

FireMarkers/app/build.gradle.kts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,11 @@ plugins {
4545
alias(libs.plugins.kotlin.serialization) // Provides Kotlin serialization capabilities.
4646
}
4747

48-
gradle.projectsEvaluated {
49-
if (rootProject.file("app/google-services.json").exists()) {
50-
project(":app").pluginManager.apply("com.google.gms.google-services")
51-
println("Applied Google Services plugin.")
52-
} else {
53-
println("google-services.json not found — skipping plugin application")
54-
}
48+
if (file("google-services.json").exists()) {
49+
apply(plugin = "com.google.gms.google-services")
50+
println("Applied Google Services plugin.")
51+
} else {
52+
println("google-services.json not found — skipping Google Services plugin")
5553
}
5654

5755
android {

FireMarkers/app/src/main/java/com/example/firemarkers/FireMarkersApplication.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class FireMarkersApplication : Application() {
5959
val mapsApiKey =
6060
bundle.getString("com.google.android.geo.API_KEY") // Key name is important!
6161

62-
if (mapsApiKey == null || mapsApiKey.isBlank() || mapsApiKey == "DEFAULT_API_KEY") {
62+
if (mapsApiKey.isNullOrBlank() || mapsApiKey == "DEFAULT_API_KEY") {
6363
Toast.makeText(
6464
this,
6565
"Maps API Key was not set in secrets.properties",

FireMarkers/app/src/main/java/com/example/firemarkers/viewmodel/MarkersViewModel.kt

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,7 @@ class MarkersViewModel @Inject constructor(
154154
}
155155

156156
override fun onCancelled(error: DatabaseError) {
157-
Log.e(TAG, "[$viewModelId] Database error on markers: ${error.message}")
158-
viewModelScope.launch {
159-
_errorEvents.emit("Database error on markers: ${error.message}")
160-
}
157+
handleDatabaseError(error, "markers")
161158
}
162159
})
163160
}
@@ -187,14 +184,23 @@ class MarkersViewModel @Inject constructor(
187184
}
188185

189186
override fun onCancelled(error: DatabaseError) {
190-
Log.e(TAG, "[$viewModelId] DB error on animation: ${error.message}")
191-
viewModelScope.launch {
192-
_errorEvents.emit("DB error on animation: ${error.message}")
193-
}
187+
handleDatabaseError(error, "animation")
194188
}
195189
})
196190
}
197191

192+
private fun handleDatabaseError(error: DatabaseError, context: String) {
193+
val msg = if (error.code == DatabaseError.PERMISSION_DENIED) {
194+
"Permission Denied ($context): Check your Firebase Database Rules."
195+
} else {
196+
"Database error ($context): ${error.message}"
197+
}
198+
Log.e(TAG, "[$viewModelId] $msg")
199+
viewModelScope.launch {
200+
_errorEvents.emit(msg)
201+
}
202+
}
203+
198204
/**
199205
* Toggles the animation state (running/paused) in Firebase.
200206
*

WearOS/Wearable/build.gradle.kts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024 Google LLC
2+
* Copyright 2026 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,20 +21,20 @@ plugins {
2121
}
2222

2323
android {
24-
compileSdk = 35
24+
compileSdk = libs.versions.compileSdk.get().toInt()
2525

2626
defaultConfig {
2727
applicationId = "com.example.wearos"
28-
minSdk = 23
29-
targetSdk = 31
28+
minSdk = libs.versions.minSdk.get().toInt()
29+
targetSdk = libs.versions.targetSdk.get().toInt()
3030
versionCode = 1
3131
versionName = libs.versions.versionName.get()
3232
}
3333

3434
buildTypes {
3535
getByName("release") {
3636
isMinifyEnabled = false
37-
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
37+
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
3838
}
3939
}
4040

@@ -45,10 +45,6 @@ android {
4545
sarifOutput = layout.buildDirectory.file("reports/lint-results-debug.sarif").get().asFile
4646
}
4747

48-
kotlinOptions {
49-
jvmTarget = "21"
50-
}
51-
5248
kotlin {
5349
jvmToolchain(21)
5450
}
@@ -57,15 +53,16 @@ android {
5753
// [START maps_wear_os_dependencies]
5854
dependencies {
5955
// [START_EXCLUDE]
60-
implementation("androidx.core:core-ktx:1.15.0")
61-
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.0.21")
56+
implementation(libs.core.ktx)
57+
implementation(platform(libs.kotlin.bom))
58+
implementation(libs.kotlin.stdlib)
6259
// [END_EXCLUDE]
63-
compileOnly("com.google.android.wearable:wearable:2.9.0")
64-
implementation("com.google.android.support:wearable:2.9.0")
65-
implementation("com.google.android.gms:play-services-maps:19.0.0")
60+
compileOnly(libs.wearable.compile)
61+
implementation(libs.wearable.support)
62+
implementation(libs.play.services.maps)
6663

6764
// This dependency is necessary for ambient mode
68-
implementation("androidx.wear:wear:1.3.0")
65+
implementation(libs.wear)
6966
}
7067
// [END maps_wear_os_dependencies]
7168

gradle/libs.versions.toml

Lines changed: 113 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,157 @@
11
[versions]
2+
# Project Configuration
3+
androidGradlePlugin = "8.13.2"
24
minSdk = "24"
35
compileSdk = "36"
46
targetSdk = "36"
7+
versionCode = "1"
8+
versionName = "1.20.1" # {x-release-please-version}
9+
javaVersion = "17"
10+
11+
# Kotlin & Coroutines
12+
kotlin = "2.2.0"
13+
kotlinxCoroutinesTest = "1.10.2"
14+
kotlinxDatetime = "0.7.1"
15+
ksp = "2.2.20-2.0.4"
516

6-
activity = "1.12.1"
7-
activityKtx = "1.11.0"
8-
androidxJunit = "1.3.0"
17+
# AndroidX Core & Jetpack
18+
activity = "1.12.2"
19+
activityKtx = "1.12.2"
20+
androidxJunit = "1.3.0" # Test ext
921
appcompat = "1.7.1"
1022
cardview = "1.0.0"
23+
constraintlayout = "2.2.1"
1124
coreKtx = "1.17.0"
12-
easypermissions = "3.0.0"
13-
espresso = "3.7.0"
14-
gradle = "8.13.2"
15-
hilt = "2.57.2"
16-
junit = "4.13.2"
17-
kotlin = "2.2.21"
1825
lifecycle = "2.10.0"
19-
mapsKtx = "5.2.1"
20-
mapsCompose = "6.12.1"
21-
material = "1.13.0"
2226
multidex = "2.0.1"
2327
navigation = "2.9.6"
24-
playServicesMaps = "19.2.0"
25-
places = "5.1.1"
2628
recyclerview = "1.4.0"
29+
30+
# Jetpack Compose
31+
compose = "1.10.1"
32+
composeBom = "2026.01.00"
33+
hiltNavigationCompose = "1.3.0"
34+
material = "1.13.0" # View-based Material
35+
material3 = "1.4.0"
36+
materialIconsExtended = "1.7.8"
37+
38+
# Google Maps & Places
39+
mapsCompose = "7.0.0"
40+
mapsKtx = "5.2.2"
41+
mapsRx = "1.0.1"
42+
places = "5.1.1"
43+
placesRx = "1.0.1"
44+
playServicesMaps = "20.0.0"
2745
secretsGradlePlugin = "2.0.1"
28-
volley = "1.2.1"
29-
truth = "1.4.5"
30-
uiautomator = "2.3.0"
31-
compose = "1.7.6"
32-
composeBom = "2024.12.01"
33-
hiltNavigationCompose = "1.2.0"
46+
47+
# Wear OS
48+
wear = "1.3.0"
49+
wearable = "2.9.0"
50+
51+
# Dependency Injection
3452
dagger = "2.57.2"
35-
firebaseBom = "33.10.0"
36-
kotlinxDatetime = "0.7.1"
37-
kotlinxCoroutinesTest = "1.10.2"
38-
robolectric = "4.16"
53+
hilt = "2.57.2"
54+
55+
# Testing
56+
espresso = "3.7.0"
57+
junit = "4.13.2"
58+
mockito = "6.2.2"
59+
robolectric = "4.16.1"
60+
truth = "1.4.5"
3961
turbine = "1.2.1"
40-
mockito = "6.1.0"
41-
versionCode = "1"
42-
# {x-release-please-start-version}
43-
versionName = "1.20.1"
44-
# {x-release-please-end}
45-
javaVersion = "17"
62+
uiautomator = "2.3.0"
63+
64+
# Firebase
65+
firebaseBom = "34.8.0"
66+
firebaseDatabase = "22.0.1"
67+
68+
# Third Party
69+
easypermissions = "3.0.0"
70+
rxlifecycle = "4.0.2"
71+
volley = "1.2.1"
4672

4773
[libraries]
74+
# Kotlin
75+
kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
76+
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
77+
kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
78+
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" }
79+
80+
# AndroidX
4881
activity = { module = "androidx.activity:activity", version.ref = "activity" }
4982
activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityKtx" }
50-
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxJunit" }
51-
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxJunit" }
5283
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
5384
cardview = { group = "androidx.cardview", name = "cardview", version.ref = "cardview" }
54-
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
85+
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
5586
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
56-
espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" }
57-
espresso-idling-resource = { module = "androidx.test.espresso:espresso-idling-resource", version.ref = "espresso" }
58-
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
59-
hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
60-
junit = { group = "junit", name = "junit", version.ref = "junit" }
61-
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
6287
lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
63-
maps-ktx = { group = "com.google.maps.android", name = "maps-ktx", version.ref = "mapsKtx" }
64-
maps-utils-ktx = { group = "com.google.maps.android", name = "maps-utils-ktx", version.ref = "mapsKtx" }
65-
maps-compose = { module = "com.google.maps.android:maps-compose", version.ref = "mapsCompose" }
66-
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
67-
material3 = { module = "androidx.compose.material3:material3", version = "1.3.1" }
6888
multidex = { group = "androidx.multidex", name = "multidex", version.ref = "multidex" }
6989
navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigation" }
7090
navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigation" }
71-
play-services-maps = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesMaps" }
72-
places = { group = "com.google.android.libraries.places", name = "places", version.ref = "places" }
7391
recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerview" }
74-
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version = "2.2.0" }
92+
93+
# Compose
94+
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
7595
compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
7696
compose-material = { module = "androidx.compose.material:material", version.ref = "compose" }
77-
volley = { group = "com.android.volley", name = "volley", version.ref = "volley" }
78-
truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
79-
uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" }
80-
easypermissions = { group = "pub.devrel", name = "easypermissions", version.ref = "easypermissions" }
81-
82-
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
83-
material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" }
97+
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
98+
material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "materialIconsExtended" }
99+
material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
84100
ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
85101
ui-graphics = { module = "androidx.compose.ui:ui-graphics", version.ref = "compose" }
86102
ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
87103
ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
88-
ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "compose" }
89-
ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "compose" }
90-
kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
91-
maps-rx = { module = "com.google.maps.android:maps-rx", version = "1.0.0" }
92-
places-rx = { module = "com.google.maps.android:places-rx", version = "1.0.0" }
93-
rxlifecycle-android-lifecycle-kotlin = { module = "com.trello.rxlifecycle4:rxlifecycle-android-lifecycle-kotlin", version = "4.0.2" }
94104

105+
# Maps & Places
106+
maps-compose = { module = "com.google.maps.android:maps-compose", version.ref = "mapsCompose" }
107+
maps-ktx = { group = "com.google.maps.android", name = "maps-ktx", version.ref = "mapsKtx" }
108+
maps-rx = { module = "com.google.maps.android:maps-rx", version.ref = "mapsRx" }
109+
maps-utils-ktx = { group = "com.google.maps.android", name = "maps-utils-ktx", version.ref = "mapsKtx" }
110+
places = { group = "com.google.android.libraries.places", name = "places", version.ref = "places" }
111+
places-rx = { module = "com.google.maps.android:places-rx", version.ref = "placesRx" }
112+
play-services-maps = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesMaps" }
113+
114+
# Wear OS
115+
wear = { group = "androidx.wear", name = "wear", version.ref = "wear" }
116+
wearable-compile = { group = "com.google.android.wearable", name = "wearable", version.ref = "wearable" }
117+
wearable-support = { group = "com.google.android.support", name = "wearable", version.ref = "wearable" }
118+
119+
# Dependency Injection
95120
dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" }
96-
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
97-
firebase-database = { module = "com.google.firebase:firebase-database", version = "21.0.0" }
98-
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" }
121+
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
122+
hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
123+
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
124+
125+
# Testing
126+
espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" }
127+
espresso-idling-resource = { module = "androidx.test.espresso:espresso-idling-resource", version.ref = "espresso" }
128+
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxJunit" }
129+
junit = { group = "junit", name = "junit", version.ref = "junit" }
99130
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutinesTest" }
131+
mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version.ref = "mockito" }
100132
robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" }
133+
truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
101134
turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }
102-
mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version.ref = "mockito" }
135+
ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "compose" }
136+
ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "compose" }
137+
uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" }
138+
139+
# Firebase
140+
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
141+
firebase-database = { module = "com.google.firebase:firebase-database", version.ref = "firebaseDatabase" }
142+
143+
# Third Party
144+
easypermissions = { group = "pub.devrel", name = "easypermissions", version.ref = "easypermissions" }
145+
rxlifecycle-android-lifecycle-kotlin = { module = "com.trello.rxlifecycle4:rxlifecycle-android-lifecycle-kotlin", version.ref = "rxlifecycle" }
146+
volley = { group = "com.android.volley", name = "volley", version.ref = "volley" }
103147

104148
[plugins]
105-
android-application = { id = "com.android.application", version.ref = "gradle" }
106-
android-library = { id = "com.android.library", version.ref = "gradle" }
149+
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
150+
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
151+
hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
107152
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
108-
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
109153
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
110-
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
111154
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
112-
hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
155+
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
156+
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
113157
secrets-gradle-plugin = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secretsGradlePlugin" }
114-
ksp = { id = "com.google.devtools.ksp", version = "2.2.20-2.0.4" }

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pluginManagement {
2828
dependencyResolutionManagement {
2929
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
3030
repositories {
31+
mavenLocal()
3132
google()
3233
mavenCentral()
3334
}

snippets/app-compose/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
plugins {
1818
alias(libs.plugins.android.application)
19-
alias(libs.plugins.jetbrains.kotlin.android)
19+
alias(libs.plugins.kotlin.android)
2020
alias(libs.plugins.kotlin.compose)
2121
alias(libs.plugins.secrets.gradle.plugin)
2222
}

snippets/app-ktx/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
plugins {
1818
alias(libs.plugins.android.application)
19-
alias(libs.plugins.jetbrains.kotlin.android)
19+
alias(libs.plugins.kotlin.android)
2020
alias(libs.plugins.secrets.gradle.plugin)
2121
}
2222

snippets/app-places-ktx/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
plugins {
1818
alias(libs.plugins.android.application)
19-
alias(libs.plugins.jetbrains.kotlin.android)
19+
alias(libs.plugins.kotlin.android)
2020
alias(libs.plugins.secrets.gradle.plugin)
2121
}
2222

0 commit comments

Comments
 (0)