Develop watch faces with the secure Jetpack Watch Face library

Posted by Alex Vanyo, Developer Relations Engineer

Illustration of tan hand showing a watch

Watch faces are some of the seen ways in which folks categorical themselves on their smartwatches, they usually’re top-of-the-line methods to show your model to your customers.

Watch Face Studio from Samsung is a superb software for creating watch faces with out writing any code. For builders who need extra fine-tuned management, we have just lately launched the Jetpack Watch Face library written from the bottom up in Kotlin.

The secure launch of the Jetpack Watch Face library contains all performance from the Wearable Help Library and plenty of new options that make it simpler to help customization on the smartwatch and on the system companion app on cell, together with:

  • Watch face styling which persists throughout each the watch and telephone (without having to your personal database or companion app).
  • Help for a WYSIWYG watch face configuration UI on the telephone.
  • Smaller, separate libraries (that solely embrace what you want).
  • Battery enhancements by means of encouraging good battery utilization patterns out of the field, resembling mechanically lowering the interactive body price when battery is low.
  • New screenshot APIs so customers can see previews of their watch face modifications in actual time on each the watch and telephone.

In case you are nonetheless utilizing the Wearable Help Library, we strongly encourage migrating to the brand new Jetpack libraries to make the most of the brand new APIs and upcoming options and bug fixes.

Beneath is an instance of configuring a watch face from the telephone with no code written on or for the telephone.

GIF showing how to edit a watch face using the Galaxy Wearable mobile companion app

Enhancing a watch face utilizing the Galaxy Wearable cell companion app


If you happen to use the Jetpack Watch Face library to avoid wasting your watch face configuration choices, the values are synced with the cell companion app. That’s, all of the cross-device communication is dealt with for you.

The cell app will mechanically current these choices to the person in a easy, intuitive person interface the place they modify them to no matter works greatest for his or her fashion. It additionally contains previews that replace in actual time.

Let’s dive into the API with an summary of an important elements for making a customized watch face!

A subclass of WatchFaceService varieties the entry level of any Jetpack watch face. Implementing a WatchFaceService requires creating 3 objects: A UserStyleSchema, a ComplicationSlotsManager, and a WatchFace:

Diagram showing the 3 main parts of a WatchFaceService

Diagram displaying the three foremost elements of a WatchFaceService

These 3 objects are specified by overriding 3 summary strategies from WatchFaceService:

class CustomWatchFaceService : WatchFaceService() {

    /**
     * The specification of settings the watch face helps.
     * That is just like a database schema.
     */
    override enjoyable createUserStyleSchema(): UserStyleSchema = // ...

    /**
     * The complication slot configuration for the watchface.
     */
    override enjoyable createComplicationSlotsManager(
        currentUserStyleRepository: CurrentUserStyleRepository
    ): ComplicationSlotsManager = // ...

    /**
     * The watch face itself, which incorporates the renderer for drawing.
     */ 
    override droop enjoyable createWatchFace(
        surfaceHolder: SurfaceHolder,
        watchState: WatchState,
        complicationSlotsManager: ComplicationSlotsManager,
        currentUserStyleRepository: CurrentUserStyleRepository
    ): WatchFace = // ...

}

Let’s take a extra detailed have a look at every one in every of these in flip, and a number of the different lessons that the library creates in your behalf.

The UserStyleSchema defines the first info supply for a Jetpack watch face. The UserStyleSchema ought to comprise a listing of all customization settings out there to the person, in addition to details about what these choices do and what the default possibility is. These settings may be boolean flags, lists, ranges, and more.

By offering this schema, the library will mechanically preserve monitor of modifications to settings by the person, both by means of the cell companion app on a linked telephone or by way of modifications made on the smartwatch in a customized editor exercise.

    override enjoyable createUserStyleSchema(): UserStyleSchema =
        UserStyleSchema(
            listOf(
                // Permits person to vary the colour types of the watch face
                UserStyleSetting.ListUserStyleSetting(
                    UserStyleSetting.Id(COLOR_STYLE_SETTING),
                    // ...
                ),
                // Permits person to toggle on/off the hour pips (dashes across the outer fringe of the watch
                UserStyleSetting.BooleanUserStyleSetting(
                    UserStyleSetting.Id(DRAW_HOUR_PIPS_STYLE_SETTING),
                    // ...
                ),
                // Permits person to vary the size of the minute hand
                UserStyleSetting.DoubleRangeUserStyleSetting(
                    UserStyleSetting.Id(WATCH_HAND_LENGTH_STYLE_SETTING),
                    // ...
                )
            )
        )

The present person fashion may be noticed by way of the ​​CurrentUserStyleRepository, which is created by the library based mostly on the UserStyleSchema.

It offers you a UserStyle which is only a Map with keys based mostly on the settings outlined within the schema:

Map<UserStyleSetting, UserStyleSetting.Possibility>

Because the person’s preferences change, a MutableStateFlow of UserStyle will emit the newest chosen choices for all the settings outlined within the UserStyleSchema.

currentUserStyleRepository.userStyle.accumulate { newUserStyle ->
    // Replace configuration based mostly on person fashion
}

Complications permit a watch face to show extra info from different apps on the watch, resembling occasions, well being knowledge, or the day.

The ComplicationSlotsManager defines what number of issues a watch face helps, and the place they’re positioned on the display. To help altering the situation or variety of issues, the ComplicationSlotsManager additionally makes use of the ​​CurrentUserStyleRepository.

    override enjoyable createComplicationSlotsManager(
        currentUserStyleRepository: CurrentUserStyleRepository
    ): ComplicationSlotsManager {
        val defaultCanvasComplicationFactory =
            CanvasComplicationFactory { watchState, listener ->
                // ...
            }
    
        val leftComplicationSlot = ComplicationSlot.createRoundRectComplicationSlotBuilder(
            id = 100,
            canvasComplicationFactory = defaultCanvasComplicationFactory,
            // ...
        )
            .setDefaultDataSourceType(ComplicationType.SHORT_TEXT)
            .construct()
    
        val rightComplicationSlot = ComplicationSlot.createRoundRectComplicationSlotBuilder(
            id = 101,
            canvasComplicationFactory = defaultCanvasComplicationFactory,
            // ...
        )
            .setDefaultDataSourceType(ComplicationType.SHORT_TEXT)
            .construct()

        return ComplicationSlotsManager(
            listOf(leftComplicationSlot, rightComplicationSlot),
            currentUserStyleRepository
        )
    }

The WatchFace describes the kind of watch face and the way to attract it.

A WatchFace may be specified as digital or analog and may optionally have a faucet listener for when the person faucets on the watch face.

Most significantly, a WatchFace specifies a Renderer, which really renders the watch face:

    override droop enjoyable createWatchFace(
        surfaceHolder: SurfaceHolder,
        watchState: WatchState,
        complicationSlotsManager: ComplicationSlotsManager,
        currentUserStyleRepository: CurrentUserStyleRepository
    ): WatchFace = WatchFace(
        watchFaceType = WatchFaceType.ANALOG,
        renderer = // ...
    )

The prettiest a part of a watch face! Each watch face will create a customized subclass of a renderer that implements every little thing wanted to really draw the watch face to a canvas.

The renderer is answerable for combining the UserStyle (the map from ​​CurrentUserStyleRepository), the complication info from ComplicationSlotsManager, the present time, and different state info to render the watch face.

class CustomCanvasRenderer(
    personal val context: Context,
    surfaceHolder: SurfaceHolder,
    watchState: WatchState,
    personal val complicationSlotsManager: ComplicationSlotsManager,
    currentUserStyleRepository: CurrentUserStyleRepository,
    canvasType: Int
) : Renderer.CanvasRenderer(
    surfaceHolder = surfaceHolder,
    currentUserStyleRepository = currentUserStyleRepository,
    watchState = watchState,
    canvasType = canvasType,
    interactiveDrawModeUpdateDelayMillis = 16L
) {
    override enjoyable render(canvas: Canvas, bounds: Rect, zonedDateTime: ZonedDateTime) {
        // Draw into the canvas!
    }

    override enjoyable renderHighlightLayer(canvas: Canvas, bounds: Rect, zonedDateTime: ZonedDateTime) {
        // Draw into the canvas!
    }
}

Along with the system WYSIWYG editor on the telephone, we strongly encourage supporting configuration on the smartwatch to permit the person to customise their watch face with out requiring a companion gadget.

To help this, a watch face can present a configuration Exercise and permit the person to vary settings utilizing an EditorSession returned from EditorSession.createOnWatchEditorSession. Because the person makes modifications, calling EditorSession.renderWatchFaceToBitmap supplies a dwell preview of the watch face within the editor Exercise.

To see how the entire puzzle suits collectively to inform the time, try the watchface sample on GitHub. To be taught extra about growing for Put on OS, try the developer website.

Recent Articles

We requested, you advised us: Shopping for smartphones with money remains to be king

There are many methods to purchase a brand new smartphone whether or not it’s by money, a contract, or a trade-in scheme. However how...

The App Advertising and marketing Snack with Clark Stacey, CEO of WildWorks ⎮ Episode 1 – Apptamin

The App Advertising and marketing Snack is bringing you the most recent ASO suggestions from app professionals. Our first episode’s visitor is Clark Stacey,...

vifa Copenhagen 2.0 vibrant Nordic speaker has a beautiful, handheld transportable design

Carry your music round with you and play it on the vifa Copenhagen 2.0 vibrant Nordic speaker. It is available in six enjoyable hues:...

Related Stories

Stay on op - Ge the daily news in your inbox