Building a Plugin for Wear OS Tiles with Flutter
Aug 14, 2025



Summary
Summary
Summary
Summary
This tutorial guides you through building a Flutter plugin for Wear OS Tiles. You’ll set up the plugin scaffold, register and implement an Android TileService in Kotlin, expose a Dart API with MethodChannel, and integrate tile updates in a Flutter app. By following these steps, you can push dynamic content to Wear OS Tiles and maintain a clean separation between your Flutter UI and native service logic.
This tutorial guides you through building a Flutter plugin for Wear OS Tiles. You’ll set up the plugin scaffold, register and implement an Android TileService in Kotlin, expose a Dart API with MethodChannel, and integrate tile updates in a Flutter app. By following these steps, you can push dynamic content to Wear OS Tiles and maintain a clean separation between your Flutter UI and native service logic.
This tutorial guides you through building a Flutter plugin for Wear OS Tiles. You’ll set up the plugin scaffold, register and implement an Android TileService in Kotlin, expose a Dart API with MethodChannel, and integrate tile updates in a Flutter app. By following these steps, you can push dynamic content to Wear OS Tiles and maintain a clean separation between your Flutter UI and native service logic.
This tutorial guides you through building a Flutter plugin for Wear OS Tiles. You’ll set up the plugin scaffold, register and implement an Android TileService in Kotlin, expose a Dart API with MethodChannel, and integrate tile updates in a Flutter app. By following these steps, you can push dynamic content to Wear OS Tiles and maintain a clean separation between your Flutter UI and native service logic.
Key insights:
Key insights:
Key insights:
Key insights:
Prerequisites and Setup: Ensure Flutter SDK, Android SDK, and a Wear OS target are ready before scaffolding the plugin.
Plugin Scaffold: Define a Dart MethodChannel to expose updateTile and match it on the Android side.
Android Tile Service Implementation: Subclass TileService in Kotlin to build and update the ge1ar tile layout.
Dart-Android Bridge: Handle updateTile in onMethodCall to pass data to the TileService for dynamic rendering.
Flutter Integration: Call updateTile from your Flutter UI to push new content to the Wear OS Tile.
Introduction
Building custom Tiles on Wear OS enhances user engagement by surfacing glanceable actions directly on the watch. Flutter does not ship a built-in API for Wear OS Tiles, so you need a plugin that bridges Dart with the native Android TileService. In this tutorial you will create a Flutter plugin that exposes a simple Tile, register it in Android manifest, implement the TileService on the Java/Kotlin side, and invoke it from Dart using platform channels.
Prerequisites and Setup
Before you begin, make sure your development machine has:
Flutter SDK (stable channel)
Android Studio or VS Code with Android SDK
A Wear OS emulator or physical watch for testing
Create a plugin template by running flutter create --template=plugin wear_tiles_plugin
In your project root you will see android/
, ios/
, lib/
, example/
. Focus on the android/
and lib/
folders.
Open android/build.gradle
and ensure compileSdkVersion
is at least 31. In android/src/main/AndroidManifest.xml
add the TileService declaration under the <application>
tag:
<service
android:name=".MyTileService"
android:exported="true">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
This registers the TileService entry point for Wear OS.
Creating the Plugin Scaffold
In lib/wear_tiles_plugin.dart
define a class with a method channel to communicate with Android. Keep it minimal:
import 'package:flutter/services.dart';
class WearTilesPlugin {
static const MethodChannel _channel =
MethodChannel('wear_tiles_plugin');
static Future<void> updateTile(String data) async {
await _channel.invokeMethod('updateTile', {'data': data});
}
}
This Dart API exposes updateTile, which you will call from your Flutter app. The method channel name must match the one declared in Android.
Implementing the Android Tile Service
In android/src/main/java/com/example/wear_tiles_plugin/MyTileService.kt
implement a subclass of TileService. Use the Tiles API to push layout and actions.
class MyTileService: TileService() {
override fun onTileRequest(requestParams: RequestBuilders.TileRequest) {
val layout = ResourceBuilders.Layout.Builder()
.setRoot(
LayoutElementBuilders.Text.Builder()
.setText("Hello Wear Tile")
.build()
).build()
val tile = TileBuilders.Tile.Builder()
.setResourcesVersion("1")
.setTileLiveDataTimetable(
TileLiveDataBuilders.TimelineSchedule.Builder()
.addTimelineEntry(
TimelineBuilders.TimelineEntry.Builder()
.setLayout(layout)
.build()
).build()
).build()
val response = TileBuilders.TileResponse.Builder()
.setTile(tile)
.build()
requestParams.getHostTileManager(this)
.updateTile(tile, null
Also add the channel handler in android/src/main/java/com/example/wear_tiles_plugin/WearTilesPlugin.kt
. Inside onMethodCall
handle updateTile
by invalidating the tile or pushing fresh data to the service.
Exposing Dart API via Platform Channels
In the plugin’s main class implement MethodCallHandler
. Resolve calls from Dart to Android:
class WearTilesPlugin: FlutterPlugin, MethodCallHandler {
private lateinit var channel : MethodChannel
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(binding.binaryMessenger, "wear_tiles_plugin")
channel.setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"updateTile" -> {
val data = call.argument<String>("data")
// Send broadcast or update shared prefs for TileService
result.success(null)
}
else -> result.notImplemented()
}
}
Drop data into a shared storage or send a broadcast so your TileService
can pick it up in onTileRequest
and render dynamic content.
Integrating the Tile in the Flutter App
Open example/lib/main.dart
. Import the plugin and call updateTile
whenever you need to push new content:
import 'package:flutter/material.dart';
import 'package:wear_tiles_plugin/wear_tiles_plugin.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Wear Tile Demo')),
body: Center(
child: ElevatedButton(
onPressed: () async {
await WearTilesPlugin.updateTile('New data at ${DateTime.now()}');
},
child: Text('Update Wear OS Tile'),
),
),
),
);
}
}
Run the example on your Wear OS device. Open the Tiles menu, swipe to find your new Tile and verify it shows the updated text.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
You have created a Flutter plugin that registers a native Wear OS TileService, bridges data via platform channels, and displays dynamic content on the watch. This architecture keeps Dart code concise while leveraging the full power of the Android Tiles API. Extend your Tile with action triggers or timeline schedules for richer interactions.
Introduction
Building custom Tiles on Wear OS enhances user engagement by surfacing glanceable actions directly on the watch. Flutter does not ship a built-in API for Wear OS Tiles, so you need a plugin that bridges Dart with the native Android TileService. In this tutorial you will create a Flutter plugin that exposes a simple Tile, register it in Android manifest, implement the TileService on the Java/Kotlin side, and invoke it from Dart using platform channels.
Prerequisites and Setup
Before you begin, make sure your development machine has:
Flutter SDK (stable channel)
Android Studio or VS Code with Android SDK
A Wear OS emulator or physical watch for testing
Create a plugin template by running flutter create --template=plugin wear_tiles_plugin
In your project root you will see android/
, ios/
, lib/
, example/
. Focus on the android/
and lib/
folders.
Open android/build.gradle
and ensure compileSdkVersion
is at least 31. In android/src/main/AndroidManifest.xml
add the TileService declaration under the <application>
tag:
<service
android:name=".MyTileService"
android:exported="true">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
This registers the TileService entry point for Wear OS.
Creating the Plugin Scaffold
In lib/wear_tiles_plugin.dart
define a class with a method channel to communicate with Android. Keep it minimal:
import 'package:flutter/services.dart';
class WearTilesPlugin {
static const MethodChannel _channel =
MethodChannel('wear_tiles_plugin');
static Future<void> updateTile(String data) async {
await _channel.invokeMethod('updateTile', {'data': data});
}
}
This Dart API exposes updateTile, which you will call from your Flutter app. The method channel name must match the one declared in Android.
Implementing the Android Tile Service
In android/src/main/java/com/example/wear_tiles_plugin/MyTileService.kt
implement a subclass of TileService. Use the Tiles API to push layout and actions.
class MyTileService: TileService() {
override fun onTileRequest(requestParams: RequestBuilders.TileRequest) {
val layout = ResourceBuilders.Layout.Builder()
.setRoot(
LayoutElementBuilders.Text.Builder()
.setText("Hello Wear Tile")
.build()
).build()
val tile = TileBuilders.Tile.Builder()
.setResourcesVersion("1")
.setTileLiveDataTimetable(
TileLiveDataBuilders.TimelineSchedule.Builder()
.addTimelineEntry(
TimelineBuilders.TimelineEntry.Builder()
.setLayout(layout)
.build()
).build()
).build()
val response = TileBuilders.TileResponse.Builder()
.setTile(tile)
.build()
requestParams.getHostTileManager(this)
.updateTile(tile, null
Also add the channel handler in android/src/main/java/com/example/wear_tiles_plugin/WearTilesPlugin.kt
. Inside onMethodCall
handle updateTile
by invalidating the tile or pushing fresh data to the service.
Exposing Dart API via Platform Channels
In the plugin’s main class implement MethodCallHandler
. Resolve calls from Dart to Android:
class WearTilesPlugin: FlutterPlugin, MethodCallHandler {
private lateinit var channel : MethodChannel
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(binding.binaryMessenger, "wear_tiles_plugin")
channel.setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"updateTile" -> {
val data = call.argument<String>("data")
// Send broadcast or update shared prefs for TileService
result.success(null)
}
else -> result.notImplemented()
}
}
Drop data into a shared storage or send a broadcast so your TileService
can pick it up in onTileRequest
and render dynamic content.
Integrating the Tile in the Flutter App
Open example/lib/main.dart
. Import the plugin and call updateTile
whenever you need to push new content:
import 'package:flutter/material.dart';
import 'package:wear_tiles_plugin/wear_tiles_plugin.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Wear Tile Demo')),
body: Center(
child: ElevatedButton(
onPressed: () async {
await WearTilesPlugin.updateTile('New data at ${DateTime.now()}');
},
child: Text('Update Wear OS Tile'),
),
),
),
);
}
}
Run the example on your Wear OS device. Open the Tiles menu, swipe to find your new Tile and verify it shows the updated text.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
You have created a Flutter plugin that registers a native Wear OS TileService, bridges data via platform channels, and displays dynamic content on the watch. This architecture keeps Dart code concise while leveraging the full power of the Android Tiles API. Extend your Tile with action triggers or timeline schedules for richer interactions.
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.











