A watch face is a service packaged in a Wear OS app. When a user selects an available watch face, the watch face is displayed and the service callback methods are invoked.
When a user installs a Wear OS app that has watch faces, the watch faces are available on the watch using the watch face selector. Alternatively, the user can select a watch face from a companion app on the paired phone.
This page describes how to configure a Wear OS project to include watch faces and how to implement a watch face service.
Create a watch face project
Follow the following steps to create a project in Android Studio for your watch face:
- Click File > New > New project.
- In the Select a project template window, select the Wear tab, select Watch Face from the list of options, and click Next.
- In the Configure your project window, accept the default values and click Finish.
Android Studio creates a project with an app
module for your watch face service.
Dependencies
The
Wearable support library provides the necessary classes that you extend to create watch
face implementations. The Google Play services client libraries (play-services
and
play-services-wearable
) are required to sync data items between the companion device
and the wearable with the Wearable
data layer API.
Android Studio automatically adds the required entries in your build.gradle
files.
The new AndroidX watch face library is currently available in alpha. See the code sample on GitHub to try it out. However, for production apps, you should use the current Wearable support library version until the AndroidX watch face library has a beta.
Wearable support library API reference
The reference documentation provides detailed information about the classes you use to implement watch faces. Browse the API reference documentation for the Wearable support library.
Note: We recommend using Android Studio for Wear OS development, as it provides project setup, library inclusion, and packaging conveniences.
Declare permissions
A watch face requires the WAKE_LOCK
permission.
Add the following permission to the manifest files of both the Wear OS app
and the mobile phone app under the manifest
element:
<manifest ...> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- Required for complications to receive complication data and open the provider chooser. --> <uses-permission android:name="com.google.android.wearable.permission.RECEIVE_COMPLICATION_DATA"/> ... </manifest>
Support rectangular devices
By default, watch faces on rectangular devices are run in a square emulation mode to support
watch faces built for circular and square devices. If you want to fully support rectangular devices,
override this behavior by creating a meta-data
tag in the watch face
service
of your manifest
and setting the
android.service.wallpaper.square_mode
to false
as shown in the following
code sample:
<manifest ...> <application ...> <service android:name=".MyWatchFace" android:label="My Watch Face" android:permission="android.permission.BIND_WALLPAPER"> ... <meta-data android:name="android.service.wallpaper.square_mode" android:value="false" /> ... </service> ... </application> ... </manifest>
Implement the service and callback methods
Watch faces in Wear OS are implemented as services. If a watch face is active, the system invokes the methods in its service when the time changes or when an important event occurs (like switching to ambient mode or receiving a new notification). The service implementation then draws the watch face on the screen using the updated time and any other relevant data.
To implement a watch face, extend the
CanvasWatchFaceService
and
CanvasWatchFaceService.Engine
classes. Then override the callback methods in the
CanvasWatchFaceService.Engine
class. These classes are included in the
Wearable support library.
The following sample outlines the key methods you need to implement:
Kotlin
class AnalogWatchFaceService : CanvasWatchFaceService() { override fun onCreateEngine(): Engine { /* provide your watch face implementation */ return Engine() } /* implement service callback methods */ inner class Engine : CanvasWatchFaceService.Engine() { override fun onCreate(holder: SurfaceHolder) { super.onCreate(holder) /* initialize your watch face */ } override fun onPropertiesChanged(properties: Bundle?) { super.onPropertiesChanged(properties) /* get device features (burn-in, low-bit ambient) */ } override fun onTimeTick() { super.onTimeTick() /* the time changed */ } override fun onAmbientModeChanged(inAmbientMode: Boolean) { super.onAmbientModeChanged(inAmbientMode) /* the wearable switched between modes */ } override fun onDraw(canvas: Canvas, bounds: Rect) { /* draw your watch face */ } override fun onVisibilityChanged(visible: Boolean) { super.onVisibilityChanged(visible) /* the watch face became visible or invisible */ } } }
Java
public class AnalogWatchFaceService extends CanvasWatchFaceService { @Override public Engine onCreateEngine() { /* provide your watch face implementation */ return new Engine(); } /* implement service callback methods */ private class Engine extends CanvasWatchFaceService.Engine { @Override public void onCreate(SurfaceHolder holder) { super.onCreate(holder); /* initialize your watch face */ } @Override public void onPropertiesChanged(Bundle properties) { super.onPropertiesChanged(properties); /* get device features (burn-in, low-bit ambient) */ } @Override public void onTimeTick() { super.onTimeTick(); /* the time changed */ } @Override public void onAmbientModeChanged(boolean inAmbientMode) { super.onAmbientModeChanged(inAmbientMode); /* the wearable switched between modes */ } @Override public void onDraw(Canvas canvas, Rect bounds) { /* draw your watch face */ } @Override public void onVisibilityChanged(boolean visible) { super.onVisibilityChanged(visible); /* the watch face became visible or invisible */ } } }
The
CanvasWatchFaceService
class provides an invalidate mechanism similar to the
View.invalidate()
method.
Call the
invalidate()
method throughout your implementation when you want the system to
redraw the watch face. You can only use the invalidate()
method in the main UI thread.
To invalidate the canvas from another thread, call the
postInvalidate()
method.
For more information about implementing the methods in the
CanvasWatchFaceService.Engine
class, see
Draw watch faces.
Register the watch face service
After you implement the watch face service, register the implementation in the manifest file of the wearable app. When users install this app, the system uses the information about the service to make the watch face available in the Wear OS by Google companion app and in the watch face picker on the wearable device.
The following sample shows how to register a watch face implementation
under the
application
element:
<service android:name=".AnalogWatchFaceService" android:label="@string/analog_name" android:permission="android.permission.BIND_WALLPAPER" > <meta-data android:name="android.service.wallpaper" android:resource="@xml/watch_face" /> <meta-data android:name="com.google.android.wearable.watchface.preview" android:resource="@drawable/preview_analog" /> <meta-data android:name="com.google.android.wearable.watchface.preview_circular" android:resource="@drawable/preview_analog_circular" /> <intent-filter> <action android:name="android.service.wallpaper.WallpaperService" /> <category android:name= "com.google.android.wearable.watchface.category.WATCH_FACE" /> </intent-filter> </service>
The
Wear OS by Google companion app and the watch face picker on the wearable device use the preview
image defined by the com.google.android.wearable.watchface.preview
metadata entry when
presenting users with all the watch faces installed on the device. To obtain this drawable,
run the watch face on your Wear OS device or in an emulator instance and
take a screenshot. On Wear
devices with hdpi screens, the preview image is typically 320x320 pixels in size.
Watch faces that look substantially different on round devices can provide both round and
square preview images. To specify a round preview image, use the
com.google.android.wearable.watchface.preview_circular
metadata entry. If a watch
face includes both preview images, the companion app and the watch face picker on the wearable
show the appropriate one, depending on the shape of the watch. If a round preview image isn't
included, the square preview image is used for both square and round devices. For round devices,
a square preview image is cropped using a circular shape.
The android.service.wallpaper
metadata entry specifies the
watch_face.xml
resource file, which contains a wallpaper
element, as shown in the following sample:
<?xml version="1.0" encoding="UTF-8"?> <wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />
Your wearable app can contain more than one watch face. You must add a service entry to the manifest file of the wearable app for each of your watch face implementations.
Related resources
Refer to the following related resources: