DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Wear OS Tiles Complete Guide — Tile API/Layout/Data Update

What You'll Learn

Wear OS Tiles (TileService, layout building, data update, click actions, preview) explained.


Setup

dependencies {
    implementation("androidx.wear.tiles:tiles:1.4.1")
    implementation("androidx.wear.tiles:tiles-material3:1.4.1")
    implementation("androidx.wear.tiles:tiles-tooling-preview:1.4.1")
    debugImplementation("androidx.wear.tiles:tiles-tooling:1.4.1")
}
Enter fullscreen mode Exit fullscreen mode

TileService

class StepsTileService : TileService() {
    override suspend fun tileRequest(requestParams: RequestBuilders.TileRequest): TileBuilders.Tile {
        val steps = getStepsFromDataStore()

        return TileBuilders.Tile.Builder()
            .setResourcesVersion("1")
            .setTileTimeline(
                TimelineBuilders.Timeline.Builder()
                    .addTimelineEntry(
                        TimelineBuilders.TimelineEntry.Builder()
                            .setLayout(
                                LayoutElementBuilders.Layout.Builder()
                                    .setRoot(createLayout(steps))
                                    .build()
                            )
                            .build()
                    )
                    .build()
            )
            .setFreshnessIntervalMillis(300_000) // Update every 5 minutes
            .build()
    }

    override suspend fun resourcesRequest(
        requestParams: RequestBuilders.ResourcesRequest
    ): ResourceBuilders.Resources {
        return ResourceBuilders.Resources.Builder()
            .setVersion("1")
            .addIdToImageMapping("icon_walk", ResourceBuilders.ImageResource.Builder()
                .setAndroidResourceByResId(
                    ResourceBuilders.AndroidImageResourceByResId.Builder()
                        .setResourceId(R.drawable.ic_walk)
                        .build()
                ).build()
            )
            .build()
    }

    private fun createLayout(steps: Int): LayoutElementBuilders.LayoutElement {
        return LayoutElementBuilders.Column.Builder()
            .addContent(
                LayoutElementBuilders.Image.Builder()
                    .setResourceId("icon_walk")
                    .setWidth(DimensionBuilders.dp(24f))
                    .setHeight(DimensionBuilders.dp(24f))
                    .build()
            )
            .addContent(
                LayoutElementBuilders.Text.Builder()
                    .setText("$steps")
                    .setFontStyle(
                        LayoutElementBuilders.FontStyle.Builder()
                            .setSize(DimensionBuilders.sp(32f))
                            .setWeight(LayoutElementBuilders.FONT_WEIGHT_BOLD)
                            .build()
                    )
                    .build()
            )
            .addContent(
                LayoutElementBuilders.Text.Builder()
                    .setText("steps")
                    .setFontStyle(
                        LayoutElementBuilders.FontStyle.Builder()
                            .setSize(DimensionBuilders.sp(14f))
                            .build()
                    )
                    .build()
            )
            .setHorizontalAlignment(LayoutElementBuilders.HORIZONTAL_ALIGN_CENTER)
            .build()
    }
}
Enter fullscreen mode Exit fullscreen mode

Manifest Registration

<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>
    <meta-data
        android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_preview" />
</service>
Enter fullscreen mode Exit fullscreen mode

Click Actions

private fun createClickableLayout(): LayoutElementBuilders.LayoutElement {
    val clickable = ModifiersBuilders.Clickable.Builder()
        .setOnClick(
            ActionBuilders.LaunchAction.Builder()
                .setAndroidActivity(
                    ActionBuilders.AndroidActivity.Builder()
                        .setClassName("com.example.MainActivity")
                        .setPackageName("com.example.app")
                        .build()
                )
                .build()
        )
        .setId("open_app")
        .build()

    return LayoutElementBuilders.Box.Builder()
        .addContent(/* content */)
        .setModifiers(
            ModifiersBuilders.Modifiers.Builder()
                .setClickable(clickable)
                .build()
        )
        .build()
}
Enter fullscreen mode Exit fullscreen mode

Tile Update Trigger

// Request tile update on data change
class StepsRepository @Inject constructor(context: Context) {
    fun updateSteps(steps: Int) {
        // Save data
        saveSteps(steps)
        // Request tile update
        TileService.getUpdater(context).requestUpdate(StepsTileService::class.java)
    }
}
Enter fullscreen mode Exit fullscreen mode

Summary

Feature Implementation
Tile definition TileService
Layout LayoutElementBuilders
Resources ResourceBuilders
Click LaunchAction
Update TileService.getUpdater()
  • TileService defines Wear OS tiles
  • LayoutElementBuilders constructs UI
  • freshnessIntervalMillis for periodic update
  • requestUpdate() for immediate tile update

Ready-Made Android App Templates

8 production-ready Android app templates with Jetpack Compose, MVVM, Hilt, and Material 3.

Browse templatesGumroad

Top comments (0)