Skip to content

Commit fecd427

Browse files
committed
Adds complications snippets
1 parent 982ea5e commit fecd427

File tree

8 files changed

+185
-0
lines changed

8 files changed

+185
-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_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_complication_manifest] -->
243+
204244
</application>
205245

206246
</manifest>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
package com.example.wear.snippets.complication
17+
18+
import androidx.wear.watchface.complications.data.ComplicationData
19+
import androidx.wear.watchface.complications.data.ComplicationType
20+
import androidx.wear.watchface.complications.data.PlainComplicationText
21+
import androidx.wear.watchface.complications.data.ShortTextComplicationData
22+
import androidx.wear.watchface.complications.datasource.ComplicationRequest
23+
import androidx.wear.watchface.complications.datasource.SuspendingComplicationDataSourceService
24+
25+
// [START android_wear_complication]
26+
class MyComplicationDataSourceService : SuspendingComplicationDataSourceService() {
27+
override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
28+
// Retrieve latest info for inclusion in the data
29+
val text = getLatestData()
30+
return shortTextComplicationData(text)
31+
}
32+
33+
override fun getPreviewData(type: ComplicationType): ComplicationData? {
34+
return shortTextComplicationData("Event 1")
35+
}
36+
37+
private fun shortTextComplicationData(text: String) =
38+
ShortTextComplicationData.Builder(
39+
text = PlainComplicationText.Builder(text).build(),
40+
contentDescription = PlainComplicationText.Builder(text).build()
41+
)
42+
// Add further optional details here such as icon, tap action, title etc
43+
.build()
44+
45+
// [START_EXCLUDE]
46+
private fun getLatestData() = "Test"
47+
// [END_EXCLUDE]
48+
}
49+
// [END android_wear_complication]
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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+
package com.example.wear.snippets.complication
17+
18+
import androidx.wear.watchface.complications.data.ComplicationData
19+
import androidx.wear.watchface.complications.data.ComplicationType
20+
import androidx.wear.watchface.complications.data.NoDataComplicationData
21+
import androidx.wear.watchface.complications.data.PlainComplicationText
22+
import androidx.wear.watchface.complications.data.ShortTextComplicationData
23+
import androidx.wear.watchface.complications.datasource.ComplicationDataTimeline
24+
import androidx.wear.watchface.complications.datasource.ComplicationRequest
25+
import androidx.wear.watchface.complications.datasource.SuspendingTimelineComplicationDataSourceService
26+
import androidx.wear.watchface.complications.datasource.TimeInterval
27+
import androidx.wear.watchface.complications.datasource.TimelineEntry
28+
import java.time.Instant
29+
import java.time.temporal.ChronoUnit
30+
31+
data class CalendarEntry(
32+
val start: Instant,
33+
val end: Instant,
34+
val name: String
35+
)
36+
37+
// [START android_wear_timeline_complication]
38+
class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDataSourceService() {
39+
override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? {
40+
if (request.complicationType != ComplicationType.SHORT_TEXT) {
41+
return ComplicationDataTimeline(
42+
defaultComplicationData = NoDataComplicationData(),
43+
timelineEntries = emptyList()
44+
)
45+
}
46+
// Retrieve list of events from your own datasource / database.
47+
val events = getCalendarEvents()
48+
return ComplicationDataTimeline(
49+
defaultComplicationData = shortTextComplicationData("No event"),
50+
timelineEntries = events.map {
51+
TimelineEntry(
52+
validity = TimeInterval(it.start, it.end),
53+
complicationData = shortTextComplicationData(it.name)
54+
)
55+
}
56+
)
57+
}
58+
59+
override fun getPreviewData(type: ComplicationType): ComplicationData? {
60+
return shortTextComplicationData("Event 1")
61+
}
62+
63+
private fun shortTextComplicationData(text: String) =
64+
ShortTextComplicationData.Builder(
65+
text = PlainComplicationText.Builder(text).build(),
66+
contentDescription = PlainComplicationText.Builder(text).build()
67+
)
68+
// Add further optional details here such as icon, tap action, title etc
69+
.build()
70+
71+
// [START_EXCLUDE]
72+
private fun getCalendarEvents(): List<CalendarEntry> {
73+
val now = Instant.now()
74+
return listOf(
75+
CalendarEntry(now, now.plus(1, ChronoUnit.HOURS), "Event 1"),
76+
CalendarEntry(now.plus(2, ChronoUnit.HOURS), now.plus(3, ChronoUnit.HOURS), "Event 2"),
77+
CalendarEntry(now.plus(4, ChronoUnit.HOURS), now.plus(5, ChronoUnit.HOURS), "Event 3"),
78+
)
79+
}
80+
// [END_EXCLUDE]
81+
}
82+
// [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)