From fecd42736add5bc6e2a83a194f594bddc3ff3c91 Mon Sep 17 00:00:00 2001 From: garan Date: Fri, 22 Aug 2025 13:50:56 +0100 Subject: [PATCH 1/4] Adds complications snippets --- gradle/libs.versions.toml | 2 + settings.gradle.kts | 3 + wear/build.gradle.kts | 2 + wear/src/main/AndroidManifest.xml | 40 +++++++++ .../MyComplicationDataSourceService.kt | 49 +++++++++++ ...MyTimelineComplicationDataSourceService.kt | 82 +++++++++++++++++++ .../main/res/drawable/complication_icon.xml | 5 ++ wear/src/main/res/values/strings.xml | 2 + 8 files changed, 185 insertions(+) create mode 100644 wear/src/main/java/com/example/wear/snippets/complication/MyComplicationDataSourceService.kt create mode 100644 wear/src/main/java/com/example/wear/snippets/complication/MyTimelineComplicationDataSourceService.kt create mode 100644 wear/src/main/res/drawable/complication_icon.xml diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cff01387c..77f80c6d1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -69,6 +69,7 @@ tiles = "1.5.0" tracing = "1.3.0" validatorPush = "1.0.0-alpha06" version-catalog-update = "1.0.0" +watchfaceComplicationsDataSourceKtx = "1.2.1" wear = "1.3.0" wearComposeFoundation = "1.5.0-rc02" wearComposeMaterial = "1.5.0-rc02" @@ -151,6 +152,7 @@ androidx-tiles-testing = { module = "androidx.wear.tiles:tiles-testing", version androidx-tiles-tooling = { module = "androidx.wear.tiles:tiles-tooling", version.ref = "tiles" } androidx-tiles-tooling-preview = { module = "androidx.wear.tiles:tiles-tooling-preview", version.ref = "tiles" } androidx-tracing = { module = "androidx.tracing:tracing", version.ref = "tracing" } +androidx-watchface-complications-data-source-ktx = { module = "androidx.wear.watchface:watchface-complications-data-source-ktx", version.ref = "watchfaceComplicationsDataSourceKtx" } androidx-wear = { module = "androidx.wear:wear", version.ref = "wear" } androidx-wear-ongoing = { module = "androidx.wear:wear-ongoing", version.ref = "wearOngoing" } androidx-wear-tooling-preview = { module = "androidx.wear:wear-tooling-preview", version.ref = "wearToolingPreview" } diff --git a/settings.gradle.kts b/settings.gradle.kts index eb485975e..316110b4e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,6 +7,9 @@ pluginManagement { mavenCentral() } } +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" +} dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { diff --git a/wear/build.gradle.kts b/wear/build.gradle.kts index eb7c66445..d88421c1e 100644 --- a/wear/build.gradle.kts +++ b/wear/build.gradle.kts @@ -85,6 +85,8 @@ dependencies { implementation(libs.horologist.compose.layout) implementation(libs.horologist.compose.material) implementation(libs.androidx.material.icons.core) + implementation(libs.androidx.watchface.complications.data.source.ktx) + androidTestImplementation(libs.androidx.compose.ui.test.junit4) debugImplementation(libs.androidx.compose.ui.tooling) debugImplementation(libs.androidx.compose.ui.tooling.preview) diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index e72edbe49..89379228f 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -201,6 +201,46 @@ android:value="For Ongoing Activity"/> + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wear/src/main/java/com/example/wear/snippets/complication/MyComplicationDataSourceService.kt b/wear/src/main/java/com/example/wear/snippets/complication/MyComplicationDataSourceService.kt new file mode 100644 index 000000000..b5d1f5b1a --- /dev/null +++ b/wear/src/main/java/com/example/wear/snippets/complication/MyComplicationDataSourceService.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.wear.snippets.complication + +import androidx.wear.watchface.complications.data.ComplicationData +import androidx.wear.watchface.complications.data.ComplicationType +import androidx.wear.watchface.complications.data.PlainComplicationText +import androidx.wear.watchface.complications.data.ShortTextComplicationData +import androidx.wear.watchface.complications.datasource.ComplicationRequest +import androidx.wear.watchface.complications.datasource.SuspendingComplicationDataSourceService + +// [START android_wear_complication] +class MyComplicationDataSourceService : SuspendingComplicationDataSourceService() { + override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? { + // Retrieve latest info for inclusion in the data + val text = getLatestData() + return shortTextComplicationData(text) + } + + override fun getPreviewData(type: ComplicationType): ComplicationData? { + return shortTextComplicationData("Event 1") + } + + private fun shortTextComplicationData(text: String) = + ShortTextComplicationData.Builder( + text = PlainComplicationText.Builder(text).build(), + contentDescription = PlainComplicationText.Builder(text).build() + ) + // Add further optional details here such as icon, tap action, title etc + .build() + + // [START_EXCLUDE] + private fun getLatestData() = "Test" + // [END_EXCLUDE] +} +// [END android_wear_complication] \ No newline at end of file diff --git a/wear/src/main/java/com/example/wear/snippets/complication/MyTimelineComplicationDataSourceService.kt b/wear/src/main/java/com/example/wear/snippets/complication/MyTimelineComplicationDataSourceService.kt new file mode 100644 index 000000000..0170079fc --- /dev/null +++ b/wear/src/main/java/com/example/wear/snippets/complication/MyTimelineComplicationDataSourceService.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.wear.snippets.complication + +import androidx.wear.watchface.complications.data.ComplicationData +import androidx.wear.watchface.complications.data.ComplicationType +import androidx.wear.watchface.complications.data.NoDataComplicationData +import androidx.wear.watchface.complications.data.PlainComplicationText +import androidx.wear.watchface.complications.data.ShortTextComplicationData +import androidx.wear.watchface.complications.datasource.ComplicationDataTimeline +import androidx.wear.watchface.complications.datasource.ComplicationRequest +import androidx.wear.watchface.complications.datasource.SuspendingTimelineComplicationDataSourceService +import androidx.wear.watchface.complications.datasource.TimeInterval +import androidx.wear.watchface.complications.datasource.TimelineEntry +import java.time.Instant +import java.time.temporal.ChronoUnit + +data class CalendarEntry( + val start: Instant, + val end: Instant, + val name: String +) + +// [START android_wear_timeline_complication] +class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDataSourceService() { + override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? { + if (request.complicationType != ComplicationType.SHORT_TEXT) { + return ComplicationDataTimeline( + defaultComplicationData = NoDataComplicationData(), + timelineEntries = emptyList() + ) + } + // Retrieve list of events from your own datasource / database. + val events = getCalendarEvents() + return ComplicationDataTimeline( + defaultComplicationData = shortTextComplicationData("No event"), + timelineEntries = events.map { + TimelineEntry( + validity = TimeInterval(it.start, it.end), + complicationData = shortTextComplicationData(it.name) + ) + } + ) + } + + override fun getPreviewData(type: ComplicationType): ComplicationData? { + return shortTextComplicationData("Event 1") + } + + private fun shortTextComplicationData(text: String) = + ShortTextComplicationData.Builder( + text = PlainComplicationText.Builder(text).build(), + contentDescription = PlainComplicationText.Builder(text).build() + ) + // Add further optional details here such as icon, tap action, title etc + .build() + + // [START_EXCLUDE] + private fun getCalendarEvents(): List { + val now = Instant.now() + return listOf( + CalendarEntry(now, now.plus(1, ChronoUnit.HOURS), "Event 1"), + CalendarEntry(now.plus(2, ChronoUnit.HOURS), now.plus(3, ChronoUnit.HOURS), "Event 2"), + CalendarEntry(now.plus(4, ChronoUnit.HOURS), now.plus(5, ChronoUnit.HOURS), "Event 3"), + ) + } + // [END_EXCLUDE] +} +// [END android_wear_timeline_complication] \ No newline at end of file diff --git a/wear/src/main/res/drawable/complication_icon.xml b/wear/src/main/res/drawable/complication_icon.xml new file mode 100644 index 000000000..1793d6ba5 --- /dev/null +++ b/wear/src/main/res/drawable/complication_icon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/wear/src/main/res/values/strings.xml b/wear/src/main/res/values/strings.xml index 90f5cb258..ccf86dbde 100644 --- a/wear/src/main/res/values/strings.xml +++ b/wear/src/main/res/values/strings.xml @@ -6,4 +6,6 @@ Message Detail Hello Tile Hello Tile Description + My Complication + My Timeline Complication \ No newline at end of file From 3ee70aa80f67424c304e543cf8310b668d76d671 Mon Sep 17 00:00:00 2001 From: garan Date: Fri, 22 Aug 2025 13:53:34 +0100 Subject: [PATCH 2/4] Fix snippet tag --- wear/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index 89379228f..a809f1a5f 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -221,7 +221,7 @@ - + - + From 03f29766f9830c50057ba13c0f4f26c41d0ba840 Mon Sep 17 00:00:00 2001 From: garan Date: Fri, 22 Aug 2025 13:54:27 +0100 Subject: [PATCH 3/4] Fix snippet tag --- wear/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index a809f1a5f..8aebe45b5 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -221,7 +221,7 @@ - + - + From cd3cbb346a4a972f216e83defeeaed683af62ae5 Mon Sep 17 00:00:00 2001 From: garanj <25058277+garanj@users.noreply.github.com> Date: Fri, 22 Aug 2025 12:56:48 +0000 Subject: [PATCH 4/4] Apply Spotless --- .../snippets/complication/MyComplicationDataSourceService.kt | 3 ++- .../complication/MyTimelineComplicationDataSourceService.kt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/wear/src/main/java/com/example/wear/snippets/complication/MyComplicationDataSourceService.kt b/wear/src/main/java/com/example/wear/snippets/complication/MyComplicationDataSourceService.kt index b5d1f5b1a..ce08ea6ff 100644 --- a/wear/src/main/java/com/example/wear/snippets/complication/MyComplicationDataSourceService.kt +++ b/wear/src/main/java/com/example/wear/snippets/complication/MyComplicationDataSourceService.kt @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.example.wear.snippets.complication import androidx.wear.watchface.complications.data.ComplicationData @@ -46,4 +47,4 @@ class MyComplicationDataSourceService : SuspendingComplicationDataSourceService( private fun getLatestData() = "Test" // [END_EXCLUDE] } -// [END android_wear_complication] \ No newline at end of file +// [END android_wear_complication] diff --git a/wear/src/main/java/com/example/wear/snippets/complication/MyTimelineComplicationDataSourceService.kt b/wear/src/main/java/com/example/wear/snippets/complication/MyTimelineComplicationDataSourceService.kt index 0170079fc..00b6daea3 100644 --- a/wear/src/main/java/com/example/wear/snippets/complication/MyTimelineComplicationDataSourceService.kt +++ b/wear/src/main/java/com/example/wear/snippets/complication/MyTimelineComplicationDataSourceService.kt @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.example.wear.snippets.complication import androidx.wear.watchface.complications.data.ComplicationData @@ -79,4 +80,4 @@ class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDa } // [END_EXCLUDE] } -// [END android_wear_timeline_complication] \ No newline at end of file +// [END android_wear_timeline_complication]