On Wear OS devices, tiles are rendered by two key components with independent versioning. To ensure your apps tiles function correctly across all devices, it's important to understand this underlying architecture.
- Jetpack tile-related libraries: These libraries (including Wear Tiles
and Wear ProtoLayout) are embedded in your app, and you, as the developer,
control their versions. Your app uses these libraries to construct a
TileBuilder.Tile
object (the data structure representing your Tile) in response to the system'sonTileRequest()
call. - ProtoLayout Renderer: This system component is responsible for rendering
the
Tile
object on the display and handling user interactions. The version of the renderer is not controlled by the app developer and can vary across devices, even those with identical hardware.
A Tile's appearance or behavior can vary based on both your app's Jetpack Tiles library versions and the ProtoLayout Renderer version on the user's device. For example, one device may support rotation or the display of heart rate data, and another may not.
This document explains how to ensure your app is compatible with different versions of the Tiles library and ProtoLayout Renderer, and how to migrate to higher Jetpack library versions.
Consider compatibility
To create a Tile that functions correctly across a range of devices, you should consider the following.
Detect the renderer version
- Use the
getRendererSchemaVersion()
method of theDeviceParameters
object passed to your onTileRequest() method. This method returns the major and minor version numbers of the ProtoLayout Renderer on the device. - You can then use conditional logic in your
onTileRequest()
implementation to adapt your Tile's design or behavior based on the detected renderer version.- For example, if a specific animation is not supported, you could display a static image instead.
The @RequiresSchemaVersion
annotation
- The
@RequiresSchemaVersion
annotation on ProtoLayout methods indicates the minimum renderer schema version required for that method to behave as documented (example).- While calling a method that requires a higher renderer version than is available on the device won't cause your app to crash, it could lead to content not being displayed or the feature being ignored.
Example
override fun onTileRequest(
requestParams: TileService.TileRequest
): ListenableFuture<Tile> {
val rendererVersion =
requestParams.deviceConfiguration.rendererSchemaVersion
val tile = Tile.Builder()
if (
rendererVersion.major > 1 ||
(rendererVersion.major == 1 && rendererVersion.minor >= 300)
) {
// Use a feature supported in renderer version 1.300 or later
tile.setTileTimeline(/* ... */ )
} else {
// Provide fallback content for older renderers
tile.setTileTimeline(/* ... */ )
}
return Futures.immediateFuture(tile.build())
}
Test with different renderer versions
To test your tiles against different renderer versions, deploy them to different versions of the Wear OS emulator. (On physical devices, ProtoLayout Renderer updates are delivered by the Play Store or system updates. It's not possible to force a specific renderer version to be installed.)
Android Studio's Tile Preview feature makes use of a renderer embedded in the Jetpack ProtoLayout library your code depends on, so another approach is to depend on different Jetpack library versions when testing tiles.
Upgrade Jetpack libraries
Update your Jetpack Tile libraries to take advantage of the latest enhancements, including UI changes to make your Tiles integrate seamlessly with the system.
Migrate to Tiles 1.2 / ProtoLayout 1.0
As of version 1.2, most Tiles layout APIs are in the androidx.wear.protolayout
namespace. To use the latest APIs, complete the following migration steps in
your code.
Update dependencies
In your app module's build file, make the following changes:
Groovy
// Removeimplementation 'androidx.wear.tiles:tiles-material:version'// Include additional dependencies implementation "androidx.wear.protolayout:protolayout:1.2.1" implementation "androidx.wear.protolayout:protolayout-material:1.2.1" implementation "androidx.wear.protolayout:protolayout-expression:1.2.1" // Update implementation "androidx.wear.tiles:tiles:1.4.1"
Kotlin
// Removeimplementation("androidx.wear.tiles:tiles-material:version")// Include additional dependencies implementation("androidx.wear.protolayout:protolayout:1.2.1") implementation("androidx.wear.protolayout:protolayout-material:1.2.1") implementation("androidx.wear.protolayout:protolayout-expression:1.2.1") // Update implementation("androidx.wear.tiles:tiles:1.4.1")
Update namespaces
In your app's Kotlin- and Java-based code files, make the following updates. Alternatively, you can execute this namespace renaming script.
- Replace all
androidx.wear.tiles.material.*
imports withandroidx.wear.protolayout.material.*
. Complete this step for theandroidx.wear.tiles.material.layouts
library, too. Replace most other
androidx.wear.tiles.*
imports withandroidx.wear.protolayout.*
.Imports for
androidx.wear.tiles.EventBuilders
,androidx.wear.tiles.RequestBuilders
,androidx.wear.tiles.TileBuilders
, andandroidx.wear.tiles.TileService
should stay the same.Rename a few deprecated methods from TileService and TileBuilder classes:
TileBuilders
:getTimeline()
togetTileTimeline()
, andsetTimeline()
tosetTileTimeline()
TileService
:onResourcesRequest()
toonTileResourcesRequest()
RequestBuilders.TileRequest
:getDeviceParameters()
togetDeviceConfiguration()
,setDeviceParameters()
tosetDeviceConfiguration()
,getState()
togetCurrentState()
, andsetState()
tosetCurrentState()
- Note: link text is displayed when JavaScript is off
- Get started with tiles
- Create your first Tile in Wear OS
- Introduction to Compose for TV