Skip to content

Commit 97d93a1

Browse files
authored
Adds complications snippets (#597)
* Adds complications snippets * Fix snippet tag * Fix snippet tag * Apply Spotless --------- Co-authored-by: garanj <[email protected]>
1 parent 982ea5e commit 97d93a1

File tree

8 files changed

+187
-0
lines changed

8 files changed

+187
-0
lines changed

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ tiles = "1.5.0"
6969
tracing = "1.3.0"
7070
validatorPush = "1.0.0-alpha06"
7171
version-catalog-update = "1.0.0"
72+
watchfaceComplicationsDataSourceKtx = "1.2.1"
7273
wear = "1.3.0"
7374
wearComposeFoundation = "1.5.0-rc02"
7475
wearComposeMaterial = "1.5.0-rc02"
@@ -151,6 +152,7 @@ androidx-tiles-testing = { module = "androidx.wear.tiles:tiles-testing", version
151152
androidx-tiles-tooling = { module = "androidx.wear.tiles:tiles-tooling", version.ref = "tiles" }
152153
androidx-tiles-tooling-preview = { module = "androidx.wear.tiles:tiles-tooling-preview", version.ref = "tiles" }
153154
androidx-tracing = { module = "androidx.tracing:tracing", version.ref = "tracing" }
155+
androidx-watchface-complications-data-source-ktx = { module = "androidx.wear.watchface:watchface-complications-data-source-ktx", version.ref = "watchfaceComplicationsDataSourceKtx" }
154156
androidx-wear = { module = "androidx.wear:wear", version.ref = "wear" }
155157
androidx-wear-ongoing = { module = "androidx.wear:wear-ongoing", version.ref = "wearOngoing" }
156158
androidx-wear-tooling-preview = { module = "androidx.wear:wear-tooling-preview", version.ref = "wearToolingPreview" }

settings.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ pluginManagement {
77
mavenCentral()
88
}
99
}
10+
plugins {
11+
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
12+
}
1013
dependencyResolutionManagement {
1114
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
1215
repositories {

wear/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ dependencies {
8585
implementation(libs.horologist.compose.layout)
8686
implementation(libs.horologist.compose.material)
8787
implementation(libs.androidx.material.icons.core)
88+
implementation(libs.androidx.watchface.complications.data.source.ktx)
89+
8890
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
8991
debugImplementation(libs.androidx.compose.ui.tooling)
9092
debugImplementation(libs.androidx.compose.ui.tooling.preview)

wear/src/main/AndroidManifest.xml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,46 @@
201201
android:value="For Ongoing Activity"/>
202202
</service>
203203

204+
<!-- [START android_wear_complication_manifest] -->
205+
<service
206+
android:name=".snippets.complication.MyComplicationDataSourceService"
207+
android:exported="true"
208+
android:label="@string/my_complication_service_label"
209+
android:icon="@drawable/complication_icon"
210+
android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
211+
<intent-filter>
212+
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
213+
</intent-filter>
214+
215+
<meta-data
216+
android:name="android.support.wearable.complications.SUPPORTED_TYPES"
217+
android:value="SHORT_TEXT" />
218+
<meta-data
219+
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
220+
android:value="300" />
221+
</service>
222+
<!-- [END android_wear_complication_manifest] -->
223+
224+
<!-- [START android_wear_timeline_complication_manifest] -->
225+
<service
226+
android:name=".snippets.complication.MyTimelineComplicationDataSourceService"
227+
android:exported="true"
228+
android:label="@string/my_complication_timeline_service_label"
229+
android:icon="@drawable/complication_icon"
230+
android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
231+
<intent-filter>
232+
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
233+
</intent-filter>
234+
235+
<meta-data
236+
android:name="android.support.wearable.complications.SUPPORTED_TYPES"
237+
android:value="SHORT_TEXT" />
238+
<meta-data
239+
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
240+
android:value="300" />
241+
</service>
242+
<!-- [END android_wear_timeline_complication_manifest] -->
243+
204244
</application>
205245

206246
</manifest>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.wear.snippets.complication
18+
19+
import androidx.wear.watchface.complications.data.ComplicationData
20+
import androidx.wear.watchface.complications.data.ComplicationType
21+
import androidx.wear.watchface.complications.data.PlainComplicationText
22+
import androidx.wear.watchface.complications.data.ShortTextComplicationData
23+
import androidx.wear.watchface.complications.datasource.ComplicationRequest
24+
import androidx.wear.watchface.complications.datasource.SuspendingComplicationDataSourceService
25+
26+
// [START android_wear_complication]
27+
class MyComplicationDataSourceService : SuspendingComplicationDataSourceService() {
28+
override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
29+
// Retrieve latest info for inclusion in the data
30+
val text = getLatestData()
31+
return shortTextComplicationData(text)
32+
}
33+
34+
override fun getPreviewData(type: ComplicationType): ComplicationData? {
35+
return shortTextComplicationData("Event 1")
36+
}
37+
38+
private fun shortTextComplicationData(text: String) =
39+
ShortTextComplicationData.Builder(
40+
text = PlainComplicationText.Builder(text).build(),
41+
contentDescription = PlainComplicationText.Builder(text).build()
42+
)
43+
// Add further optional details here such as icon, tap action, title etc
44+
.build()
45+
46+
// [START_EXCLUDE]
47+
private fun getLatestData() = "Test"
48+
// [END_EXCLUDE]
49+
}
50+
// [END android_wear_complication]
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.wear.snippets.complication
18+
19+
import androidx.wear.watchface.complications.data.ComplicationData
20+
import androidx.wear.watchface.complications.data.ComplicationType
21+
import androidx.wear.watchface.complications.data.NoDataComplicationData
22+
import androidx.wear.watchface.complications.data.PlainComplicationText
23+
import androidx.wear.watchface.complications.data.ShortTextComplicationData
24+
import androidx.wear.watchface.complications.datasource.ComplicationDataTimeline
25+
import androidx.wear.watchface.complications.datasource.ComplicationRequest
26+
import androidx.wear.watchface.complications.datasource.SuspendingTimelineComplicationDataSourceService
27+
import androidx.wear.watchface.complications.datasource.TimeInterval
28+
import androidx.wear.watchface.complications.datasource.TimelineEntry
29+
import java.time.Instant
30+
import java.time.temporal.ChronoUnit
31+
32+
data class CalendarEntry(
33+
val start: Instant,
34+
val end: Instant,
35+
val name: String
36+
)
37+
38+
// [START android_wear_timeline_complication]
39+
class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDataSourceService() {
40+
override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? {
41+
if (request.complicationType != ComplicationType.SHORT_TEXT) {
42+
return ComplicationDataTimeline(
43+
defaultComplicationData = NoDataComplicationData(),
44+
timelineEntries = emptyList()
45+
)
46+
}
47+
// Retrieve list of events from your own datasource / database.
48+
val events = getCalendarEvents()
49+
return ComplicationDataTimeline(
50+
defaultComplicationData = shortTextComplicationData("No event"),
51+
timelineEntries = events.map {
52+
TimelineEntry(
53+
validity = TimeInterval(it.start, it.end),
54+
complicationData = shortTextComplicationData(it.name)
55+
)
56+
}
57+
)
58+
}
59+
60+
override fun getPreviewData(type: ComplicationType): ComplicationData? {
61+
return shortTextComplicationData("Event 1")
62+
}
63+
64+
private fun shortTextComplicationData(text: String) =
65+
ShortTextComplicationData.Builder(
66+
text = PlainComplicationText.Builder(text).build(),
67+
contentDescription = PlainComplicationText.Builder(text).build()
68+
)
69+
// Add further optional details here such as icon, tap action, title etc
70+
.build()
71+
72+
// [START_EXCLUDE]
73+
private fun getCalendarEvents(): List<CalendarEntry> {
74+
val now = Instant.now()
75+
return listOf(
76+
CalendarEntry(now, now.plus(1, ChronoUnit.HOURS), "Event 1"),
77+
CalendarEntry(now.plus(2, ChronoUnit.HOURS), now.plus(3, ChronoUnit.HOURS), "Event 2"),
78+
CalendarEntry(now.plus(4, ChronoUnit.HOURS), now.plus(5, ChronoUnit.HOURS), "Event 3"),
79+
)
80+
}
81+
// [END_EXCLUDE]
82+
}
83+
// [END android_wear_timeline_complication]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">
2+
3+
<path android:fillColor="@android:color/white" android:pathData="M480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM253,707L480,480L480,160Q346,160 253,253Q160,346 160,480Q160,544 184,603Q208,662 253,707Z"/>
4+
5+
</vector>

wear/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66
<string name="message_detail">Message Detail</string>
77
<string name="tile_label">Hello Tile</string>
88
<string name="tile_description">Hello Tile Description</string>
9+
<string name="my_complication_service_label">My Complication</string>
10+
<string name="my_complication_timeline_service_label">My Timeline Complication</string>
911
</resources>

0 commit comments

Comments
 (0)