Skip to content

WatchFace Basics

mitchctodd edited this page Feb 9, 2015 · 2 revisions

IMPORTANT: Before utilizing Clockwise to develop your watch face, it is integral that you read the development and design guidelines in the Android Wear documentation.


Create Watch Face

The WatchFace abstract class is the base class for all watch faces using Clockwise. To get started creating a watch face, extend WatchFace and override onDraw():

public class MyWatchFace extends WatchFace {
    @Override
    protected void onDraw(Canvas canvas) {
        
    }
}

You will also need to add the service to your AndroidManifest (more info on registering your watch face service can be found here:

<service
    android:name=".MyWatchFace"
    android:label="@string/mywatchface_name"
    android:allowEmbedded="true"
    android:taskAffinity=""
    android:enabled="true"
    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/mywatchface_preview_square" />
    <meta-data
        android:name="com.google.android.wearable.watchface.preview_circular"
        android:resource="@drawable/mywatchface_preview_round" />
    <intent-filter>
        <action android:name="android.service.wallpaper.WallpaperService" />
        <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
    </intent-filter>
</service>

Now you're ready to start drawing your watch face...

Draw Watch Face

onDraw() functions the same way other custom drawing works in Android. It responds to manual calls to invalidate() and provides a Canvas instance to do your custom drawing. To change the refresh rate of (i.e. the rate at which onDraw() is called) in Interactive mode, override getInteractiveModeUpdateRate() and return the desired rate in milliseconds. If you do nothing else, it will be called once/minute in all watch modes. Clockwise will handle the timer and dispatching onDraw() methods at the appropriate times in the different modes. We have found that the "sweet spot" for continuously updating watch faces (e.g. sweeping second hands) is 33ms (~30fps).

Once the onDraw() timing is setup, you can begin drawing the content for your watch face. The two most important drivers of the content of your watch face are:

  • the current time - getTime()
  • more detailed info about managing time found here
  • the current "mode" of the watch face - getCurrentWatchMode()
  • more detailed info about drawing in different watch face modes found here

You can then utilize the following methods to determine how and where to layout your content:

  • getWidth() - width, in pixels, of watch face, excluding window insets (e.g. "chin")
  • getHeight() - height, in pixels, of watch face, excluding window insets (e.g. "chin")
  • getWatchShape() - shape of watch face (e.g. round, square)

Watch Face Lifecycle

As the WatchFace class is ultimately an extension of a standard Android Service, it inherits its lifecycle. Within the Service lifecycle, the WatchFace also manages it own watch face specific lifecycle, described below:

Managing Time

WatchFaceTime

As mentioned above, Clockwise provides time via the WatchFaceTime class. In addition to the standard Time class properties, WatchFaceTime also exposes a millis field for the number of milliseconds within the current second. This functionality is useful for watch faces that desire to render animations. More info on this can be found in the Handle Seconds: Tick vs. Continuous section. As the Time class exposes an hour field that is 24 hour based [0-23], WatchFaceTime also exposes an hour12 field that is 12 hour based [0-11].

getTime()

It's important to note that calls to getTime() do not force an underlying setToNow call. It simply returns a WatchFaceTime instance that was last set to now prior to the last onTimeChanged()/onDraw() calls in the lifecycle outlined above.

onTimeChanged()

This is called prior to each onDraw() call and passes the WatchFaceTime instance for the last time onTimeChanged() was called along with an updated WatchFaceTime instance. This callback is provided to have a place to perform view/logic updates at specific times (e.g. only when the hour value changes). More info on utilizing the onTimeChanged() callback can be found in the Optimize Performance section.

Time-related Intents

Any time the user changes the date, time, or time zone on their phone, that information is synced with the watch and the respective Intent is fired on the wearable. Clockwise handles receiving these intents and informing the watch face through onTimeChanged()/onDraw() (see lifecycle above).

Phone Connectivity

To build a watch face that can communicate with a connected device, you should extend the ConnectedWatchFace class, which is an extension of WatchFace. ConnectedWatchFace manages an instance of GoogleApiClient, exposing methods to send data to connected nodes and callbacks to receive data from connected nodes. More info on utilizing the ConnectedWatchFace can be found in the Integrate Data and Integrate Configuration sections.