Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Wear OS Tiles

Perry widgets can compile to Wear OS Tiles using --target wearos-tile. Tiles are glanceable surfaces in the Wear OS tile carousel and watch face complications.

Status: the snippet on this page compile-links cleanly on the host LLVM target via docs/examples/widgets/snippets.ts, so the Widget({...}) shape is verified against the codegen. --target wearos-tile itself is wired through crates/perry-codegen-wear-tiles but the doc-tests harness can’t drive that cross-target yet — --app-bundle-id plumbing is still pending (#194) and you’ll need an Android NDK + Wear OS Gradle deps. Build with the perry CLI to validate end-to-end.

Concepts

  • Tiles are full-screen cards users swipe through on their watch
  • Complications are small data displays on the watch face
  • Perry compiles Widget({...}) to a SuspendingTileService with layout builders

Supported Components

Widget APIWear OS Mapping
TextLayoutElementBuilders.Text
VStackLayoutElementBuilders.Column
HStackLayoutElementBuilders.Row
SpacerLayoutElementBuilders.Spacer
DividerSpacer with 1dp height
Gauge(circular)LayoutElementBuilders.Arc + ArcLine
Gauge(linear)Text fallback
ImageResource-based (provide drawable)

Example

Widget({
    kind: "StepsTile",
    displayName: "Steps",
    description: "Daily step count",
    supportedFamilies: ["accessoryCircular"],

    provider: async () => {
        return {
            entries: [{ steps: 7500, goal: 10000 }],
            reloadPolicy: { after: { minutes: 60 } },
        }
    },

    render(entry: { steps: number; goal: number }) {
        return VStack([
            Gauge(entry.steps / entry.goal, 1.0),
            Text(`${entry.steps}`),
        ])
    },
})

Compilation

perry widget.ts --target wearos-tile --app-bundle-id com.example.app -o tile_out

Output:

  • {Name}TileService.ktSuspendingTileService with tile layout
  • {Name}TileBridge.kt — JNI bridge for native provider (if provider exists)
  • AndroidManifest_snippet.xml — Service declaration

Gradle Integration

Add to your Wear OS module’s build.gradle:

dependencies {
    implementation "com.google.android.horologist:horologist-tiles:0.6.5"
    implementation "androidx.wear.tiles:tiles-material:1.4.0"
    implementation "androidx.wear.tiles:tiles:1.4.0"
}

Merge the manifest snippet into your AndroidManifest.xml:

<service
    android:name=".StepsTileService"
    android:exported="true"
    android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
    <intent-filter>
        <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
    </intent-filter>
</service>

Native Provider

Same as Android phone widgets — Wear OS is Android:

  • Target triple: aarch64-linux-android
  • libwidget_provider.so loaded via System.loadLibrary
  • JNI bridge pattern identical to phone Glance widgets
  • sharedStorage() uses SharedPreferences

Refresh

Wear Tiles use freshnessIntervalMillis on the Tile builder. Set via reloadPolicy: { after: { minutes: N } } in the provider return value. Default: 60 minutes.