Wear Widgets
Android (Google)OfficialCreated by Google LLCDistributed by Android (Google)
- Skill
- Tool integration
- Software development
- Apache-2.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach to building, migrating, and updating Wear OS widgets within an Android project. It leverages the Glance Wear library and Remote Compose to define declarative UI and state that serializes to the watch host process. The skill covers the full lifecycle, including manifest configuration, adaptive layout design for different container sizes, state management, and the creation of visual previews for the system widget picker.
What it does
- Configures GlanceWearWidget and GlanceWearWidgetService for Wear OS.
- Provides patterns for adaptive layouts using Remote Compose primitives.
- Manages widget state using remote-specific wrappers like rememberMutableRemoteInt.
- Handles click actions via pendingIntentAction for interactive widgets.
- Guides the migration of legacy TileService implementations to modern widgets.
- Facilitates the creation of required widget picker preview assets.
When to use it
- When creating new Wear OS widgets using the Glance framework.
- When migrating existing ProtoLayout TileService implementations to the current widget API.
- When implementing adaptive UI that needs to respond to SMALL and LARGE container types.
- When setting up widget preview suites and generating system picker PNGs.
Advantages
- Ensures correct integration with the Wear OS host process via Remote Compose.
- Promotes consistent UI behavior across different watch shapes.
- Provides clear separation between mobile and Wear OS widget implementations.
- Includes specific guidance on avoiding common pitfalls like incorrect state management.
Usage examples
- “How do I set up a new GlanceWearWidget in my Android project?”
- The agent will guide you through adding the necessary dependencies, registering the GlanceWearWidgetService in the AndroidManifest.xml, and implementing the GlanceWearWidget class.
- “Migrate my existing TileService to the new Wear OS widget format.”
- The agent will provide steps to replace your TileService with a GlanceWearWidgetService, annotate it with @AssociateWithGlanceWearWidget, and adapt your layout to Remote Compose.
- “How do I handle button clicks in a Remote Compose widget?”
- The agent will explain how to use RemoteModifier.clickable with a pendingIntentAction lambda to trigger activities or broadcasts from your widget.
- “What are the requirements for widget picker preview images?”
- The agent will detail the required dimensions (448x168 for SMALL, 464x288 for LARGE), the need for unmasked PNGs, and how to use preview suites to generate them.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/android/wear-widgets/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip wear-widgets.zip -d .agents/skills
Documentation by Google LLC
Wear OS widgets use androidx.glance.wear (GlanceWearWidget and
GlanceWearWidgetService) with androidx.compose.remote (Remote Compose).
They serialize declarative UI and state documents to the watch host process.
Prerequisites and setup
Resolve library versions : Resolve the latest versions for
{GLANCE_WEAR_VERSION}(androidx.glance.wear),{COMPOSE_REMOTE_VERSION}(androidx.compose.remote), and{WEAR_COMPOSE_REMOTE_VERSION}(androidx.wear.compose.remote). Include-alpha,-beta, or-rcreleases when no stable version exists yet. Don't run./gradlew dependenciesto resolve versions:Use an available dependency lookup tool if present.
Otherwise, fetch the latest version from Google Maven metadata (Glance Wear metadata, Compose Remote metadata, Wear Compose Remote metadata).
SDK and Compose compiler requirements : Ask permission before modifying repo-wide Gradle files unless the user requested widget creation, tile migration, or dependency setup. Set
compileSdk = 37or higher and enablebuildFeatures { compose = true }. Keep the project's existing Android and Kotlin Gradle plugin declarations intact.dependencies { implementation("androidx.glance.wear:wear:{GLANCE_WEAR_VERSION}") implementation("androidx.glance.wear:wear-core:{GLANCE_WEAR_VERSION}") implementation("androidx.glance.wear:wear-tooling-preview:{GLANCE_WEAR_VERSION}") implementation("androidx.compose.remote:remote-creation-compose:{COMPOSE_REMOTE_VERSION}") implementation("androidx.compose.remote:remote-creation:{COMPOSE_REMOTE_VERSION}") implementation("androidx.compose.remote:remote-core:{COMPOSE_REMOTE_VERSION}") implementation("androidx.compose.remote:remote-tooling-preview:{COMPOSE_REMOTE_VERSION}") implementation("androidx.wear.compose.remote:remote-material3:{WEAR_COMPOSE_REMOTE_VERSION}") }
Codebase exploration
Search the module for existing
TileService,Material3TileService, orGlanceWearWidgetimplementations,<service>entries inapp/src/main/AndroidManifest.xml, and@drawable/preview assets underapp/src/main/res/.When migrating an existing tile or modifying an unfamiliar multi-module project, run
./gradlew :app:assembleDebugto verify baseline build health.
Workflow
Step 1: Configure AndroidManifest.xml and provider XML
Register the GlanceWearWidgetService subclass in
app/src/main/AndroidManifest.xml with the BIND_TILE_PROVIDER permission and
BIND_WIDGET_PROVIDER intent action. Attach <meta-data> pointing to an
@xml/ <wearwidget-provider> resource with SMALL and LARGE <container>
entries. When configuring the service, provider XML, or legacy TileService
migration, you MUST follow Widget service and manifest reference.
<service
android:name=".snippets.widget.skill.MyWidgetService"
android:exported="true"
android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
<intent-filter>
<action android:name="androidx.glance.wear.action.BIND_WIDGET_PROVIDER" />
</intent-filter>
<meta-data
android:name="androidx.glance.wear.widget.provider"
android:resource="@xml/my_widget_info" />
</service>Step 2: Implement GlanceWearWidget and GlanceWearWidgetService
Extend GlanceWearWidget and override provideWidgetData returning
WearWidgetDocument. Annotate the GlanceWearWidgetService subclass with
@AssociateWithGlanceWearWidget for static provider resolution:
// WRONG: Mobile GlanceAppWidget API (don't use on Wear OS)
class BrokenWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {}
}
// CORRECT: Wear OS GlanceWearWidget + GlanceWearWidgetService
@AssociateWithGlanceWearWidget(MyWidget::class)
class MyWidgetService : GlanceWearWidgetService() {
override val widget: GlanceWearWidget = MyWidget()
}
class MyWidget : GlanceWearWidget() {
override suspend fun provideWidgetData(
context: Context,
params: WearWidgetParams,
): WearWidgetData =
WearWidgetDocument(
background = WearWidgetBrush.color(Color(0xFF1C1B1F).rc)
) {
MyWidgetContent(params = params)
}
}Step 3: Build Remote Compose layouts, state, and actions
Remote Compose evaluates UI and state inside the Wear OS host process rather than the app process. When building adaptive layouts or full-bleed backgrounds, you MUST follow Remote Compose layouts reference. When implementing state or click actions, you MUST follow State and actions reference.
Remote value wrappers : Convert primitives using
.rs(RemoteString),.rc(RemoteColor),.rdp(RemoteDp), and.ri(RemoteInt). Format integers with theRemoteInt.toRemoteStringmember method.Adaptive container sizing : Branch layout density, typography, and item counts on
params.containerType(ContainerInfo.CONTAINER_TYPE_SMALLversusContainerInfo.CONTAINER_TYPE_LARGE).Unmasked full-bleed backgrounds : Render background bitmaps inside a root
RemoteBox(RemoteModifier.fillMaxSize) usingRemoteImageandRemoteImageBitmap(bitmap.asImageBitmap). Keep background artwork unmasked (cornerRadius = 0dp) withoutCircleShapeorRoundedCornerShapeclipping. The host clips edges to the watch shape.Declarative host state and PendingIntent actions : Mutate local widget state with
rememberMutableRemoteIntandvalueChange(state, newValue)instead of in-memory Compose state (mutableStateOformutableIntStateOf). Trigger activity launches or background broadcasts usingpendingIntentAction { ctx -> ... }(always passing a(Context) -> PendingIntentlambda). Refresh active widgets withwidget.triggerUpdateAll(context).
Step 4: Add WearWidgetPreview functions and picker preview PNGs
Composable border previews (
androidx.glance.wear.tooling.preview) : ImportWearWidgetPreview,SquircleAllWidgetPreviewParams,RoundAllWidgetPreviewParams, andRectangularAllWidgetPreviewParamsfromandroidx.glance.wear.tooling.preview(NEVERandroidx.glance.wear.testing). Define@Previewfunctions invokingWearWidgetPreview(widget, params).Rectangular picker PNGs (
res/drawable-nodpi/) : UseRectangularAllWidgetPreviewParamsat320 dpior render non-blank, unmasked rectangular PNGs for every<container>in the provider XML:SMALL(CONTAINER_TYPE_SMALL):448x168px (224x84dp at 320 dpi, aspect ratio2.67).LARGE(CONTAINER_TYPE_LARGE):464x288px (232x144dp at 320 dpi, aspect ratio1.61).Each preview PNG MUST depict the widget's actual UI elements, including backgrounds, text labels, icons, avatar initials, and buttons. NEVER use a blank placeholder, empty unlabeled shapes, or a 1:1 tile preview. When adding composable previews, picker PNGs, or unit tests, you MUST follow Previews and testing reference.
Component mapping
Use this sample table to load complete implementation patterns and imports:
| Capability or API surface | Reference guide |
|---|---|
GlanceWearWidget, GlanceWearWidgetService, AndroidManifest.xml, <wearwidget-provider>, legacy TileService migration | Widget service and manifest reference |
RemoteBox, RemoteColumn, RemoteRow, RemoteText, RemoteImage, ContainerInfo (SMALL and LARGE adaptive layouts) | Remote Compose layouts reference |
RemoteButton, rememberMutableRemoteInt, valueChange, pendingIntentAction, BroadcastReceiver, triggerUpdateAll | State and actions reference |
WearWidgetPreview, SquircleAllWidgetPreviewParams, RoundAllWidgetPreviewParams, RectangularAllWidgetPreviewParams, picker PNGs, captureRawContent tests | Previews and testing reference |
Legacy ProtoLayout and mobile Glance equivalents
| Legacy or mobile API | Wear OS widget API | Action to take |
|---|---|---|
androidx.wear.tiles.TileService | GlanceWearWidgetService + GlanceWearWidget | Replace service and annotate with @AssociateWithGlanceWearWidget. |
GlanceAppWidget / provideGlance | GlanceWearWidget / provideWidgetData | Return WearWidgetDocument from provideWidgetData. |
LayoutElementBuilders / primaryLayout | RemoteColumn, RemoteRow, RemoteBox | Build layouts with @RemoteComposable functions. |
mutableStateOf / mutableIntStateOf | rememberMutableRemoteInt + valueChange | Mutate remote state declaratively using valueChange. |
ModifiersBuilders.Clickable | RemoteModifier.clickable(pendingIntentAction { ... }) | Pass a (Context) -> PendingIntent lambda to pendingIntentAction. |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Unresolved reference GlanceWearWidget | Missing androidx.glance.wear:wear:{GLANCE_WEAR_VERSION} or low compileSdk | Set compileSdk = 37 and add androidx.glance.wear:wear:{GLANCE_WEAR_VERSION}. |
Unresolved reference toRemoteString | Imported toRemoteString as top-level extension | Remove the import; call remoteInt.toRemoteString as a member method. |
Type mismatch on pendingIntentAction | Passed bare PendingIntent instead of lambda | Wrap in a lambda: pendingIntentAction { ctx -> pendingIntent }. |
Unresolved wear.tiles or protolayout references after migration | Other classes or source sets in the module still use legacy tile APIs | Migrate or update the remaining references before removing legacy wear.tiles and protolayout dependencies from build.gradle.kts. |
Verification
Run
./gradlew :app:assembleDebugto verify that the widget, service,AndroidManifest.xmldeclarations, and@xml/<wearwidget-provider>resources compile and link without errors.If the project includes unit tests or new widget tests, run
./gradlew :app:testDebugUnitTestand confirm all tests pass. When adding composable previews, picker PNGs, or unit tests, you MUST follow Previews and testing reference.
Antipatterns
NEVER extend mobile
GlanceAppWidgetorAppWidgetProvider, or use deprecatedGlanceTileServiceorTileServicefor Wear OS widgets.NEVER use in-memory client Compose state (
mutableStateOf,mutableIntStateOf) or in-process click lambdas for Remote Compose UI.NEVER pass a bare
PendingIntentinstance topendingIntentAction; always pass a(Context) -> PendingIntentlambda.NEVER apply
CircleShapeorRoundedCornerShapeclipping to full-bleed widget background artwork. NEVER reuse 1:1 (400x400) tile previews or blank solid-color placeholders for widget picker PNGs.
Best practices
MUST declare
com.google.android.wearable.permission.BIND_TILE_PROVIDERandandroidx.glance.wear.action.BIND_WIDGET_PROVIDERon<service>.MUST declare
SMALLandLARGE<container>entries in@xml/with domain-accurate448x168and464x288PNGs inres/drawable-nodpi/.MUST adapt layout content to
params.containerTypeand include@Previewfunctions for bothSquircleAllWidgetPreviewParamsandRoundAllWidgetPreviewParams.
Files
- ATTRIBUTION.mdAdded by AutoGineer943 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md12.5 KiB
- references/previews-and-testing.md5.4 KiB
- references/remote-compose-layouts.md8.0 KiB
- references/state-and-actions.md5.6 KiB
- references/widget-service-and-manifest.md4.5 KiB
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs network access
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Google LLC
- Publisher
- Android (Google) (Official)
- Distributed by
- Android (Google)
- Source
- android/skills · wear/wear-widgets · commit bf68e2d
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.txt)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Google LLC or Android (Google).
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download wear-widgets.zip