WatchFaceService


public abstract class WatchFaceService extends WallpaperService

Known direct subclasses
ListenableWatchFaceService

This class is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

StatefulWatchFaceRuntimeService

This class is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

StatefulWatchFaceService

This class is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

WatchFaceRuntimeService

This class is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

Known indirect subclasses
ListenableStatefulWatchFaceRuntimeService

This class is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

ListenableStatefulWatchFaceService

This class is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

ListenableWatchFaceRuntimeService

This class is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.


WatchFaceService and WatchFace are a pair of classes intended to handle much of the boilerplate needed to implement a watch face without being too opinionated. The suggested structure of a WatchFaceService based watch face is:

import androidx.wear.watchface.CanvasComplicationFactory
import androidx.wear.watchface.CanvasType
import androidx.wear.watchface.ComplicationSlot
import androidx.wear.watchface.ComplicationSlotsManager
import androidx.wear.watchface.Renderer
import androidx.wear.watchface.WatchFace
import androidx.wear.watchface.WatchFaceService
import androidx.wear.watchface.WatchFaceType
import androidx.wear.watchface.WatchState
import androidx.wear.watchface.complications.ComplicationSlotBounds
import androidx.wear.watchface.complications.DefaultComplicationDataSourcePolicy
import androidx.wear.watchface.complications.SystemDataSources
import androidx.wear.watchface.complications.data.ComplicationExperimental
import androidx.wear.watchface.complications.data.ComplicationType
import androidx.wear.watchface.complications.rendering.CanvasComplicationDrawable
import androidx.wear.watchface.complications.rendering.ComplicationDrawable
import androidx.wear.watchface.style.CurrentUserStyleRepository
import androidx.wear.watchface.style.UserStyleSchema
import androidx.wear.watchface.style.UserStyleSetting
import androidx.wear.watchface.style.UserStyleSetting.ListUserStyleSetting
import androidx.wear.watchface.style.UserStyleSetting.Option
import androidx.wear.watchface.style.WatchFaceLayer

class ExampleCanvasWatchFaceService : WatchFaceService() {
    override fun createUserStyleSchema() =
        UserStyleSchema(
            listOf(
                ListUserStyleSetting.Builder(
                        UserStyleSetting.Id(COLOR_STYLE_SETTING),
                        options =
                            listOf(
                                ListUserStyleSetting.ListOption.Builder(
                                        Option.Id(RED_STYLE),
                                        resources,
                                        R.string.colors_style_red,
                                        R.string.colors_style_red_screen_reader
                                    )
                                    .build(),
                                ListUserStyleSetting.ListOption.Builder(
                                        Option.Id(GREEN_STYLE),
                                        resources,
                                        R.string.colors_style_green,
                                        R.string.colors_style_green_screen_reader
                                    )
                                    .build(),
                                ListUserStyleSetting.ListOption.Builder(
                                        Option.Id(BLUE_STYLE),
                                        resources,
                                        R.string.colors_style_blue,
                                        R.string.colors_style_blue_screen_reader
                                    )
                                    .build()
                            ),
                        listOf(
                            WatchFaceLayer.BASE,
                            WatchFaceLayer.COMPLICATIONS,
                            WatchFaceLayer.COMPLICATIONS_OVERLAY
                        ),
                        resources,
                        R.string.colors_style_setting,
                        R.string.colors_style_setting_description
                    )
                    .build(),
                ListUserStyleSetting.Builder(
                        UserStyleSetting.Id(HAND_STYLE_SETTING),
                        options =
                            listOf(
                                ListUserStyleSetting.ListOption.Builder(
                                        Option.Id(CLASSIC_STYLE),
                                        resources,
                                        R.string.hand_style_classic,
                                        R.string.hand_style_classic_screen_reader
                                    )
                                    .build(),
                                ListUserStyleSetting.ListOption.Builder(
                                        Option.Id(MODERN_STYLE),
                                        resources,
                                        R.string.hand_style_modern,
                                        R.string.hand_style_modern_screen_reader
                                    )
                                    .build(),
                                ListUserStyleSetting.ListOption.Builder(
                                        Option.Id(GOTHIC_STYLE),
                                        resources,
                                        R.string.hand_style_gothic,
                                        R.string.hand_style_gothic_screen_reader
                                    )
                                    .build()
                            ),
                        listOf(WatchFaceLayer.COMPLICATIONS_OVERLAY),
                        resources,
                        R.string.hand_style_setting,
                        R.string.hand_style_setting_description
                    )
                    .build()
            )
        )

    @ComplicationExperimental
    override fun createComplicationSlotsManager(
        currentUserStyleRepository: CurrentUserStyleRepository
    ): ComplicationSlotsManager {
        val canvasComplicationFactory = CanvasComplicationFactory { watchState, listener ->
            CanvasComplicationDrawable(ComplicationDrawable(this), watchState, listener)
        }
        return ComplicationSlotsManager(
            listOf(
                ComplicationSlot.createRoundRectComplicationSlotBuilder(
                        /*id */ 0,
                        canvasComplicationFactory,
                        listOf(
                            ComplicationType.RANGED_VALUE,
                            ComplicationType.LONG_TEXT,
                            ComplicationType.SHORT_TEXT,
                            ComplicationType.MONOCHROMATIC_IMAGE,
                            ComplicationType.SMALL_IMAGE
                        ),
                        DefaultComplicationDataSourcePolicy(
                            SystemDataSources.DATA_SOURCE_DAY_OF_WEEK,
                            ComplicationType.SHORT_TEXT
                        ),
                        ComplicationSlotBounds(RectF(0.15625f, 0.1875f, 0.84375f, 0.3125f))
                    )
                    .build(),
                ComplicationSlot.createRoundRectComplicationSlotBuilder(
                        /*id */ 1,
                        canvasComplicationFactory,
                        listOf(
                            ComplicationType.RANGED_VALUE,
                            ComplicationType.LONG_TEXT,
                            ComplicationType.SHORT_TEXT,
                            ComplicationType.MONOCHROMATIC_IMAGE,
                            ComplicationType.SMALL_IMAGE
                        ),
                        DefaultComplicationDataSourcePolicy(
                            SystemDataSources.DATA_SOURCE_STEP_COUNT,
                            ComplicationType.SHORT_TEXT
                        ),
                        ComplicationSlotBounds(RectF(0.1f, 0.5625f, 0.35f, 0.8125f))
                    )
                    .build()
            ),
            currentUserStyleRepository
        )
    }

    inner class MySharedAssets : Renderer.SharedAssets {
        override fun onDestroy() {}
    }

    override suspend fun createWatchFace(
        surfaceHolder: SurfaceHolder,
        watchState: WatchState,
        complicationSlotsManager: ComplicationSlotsManager,
        currentUserStyleRepository: CurrentUserStyleRepository
    ) =
        WatchFace(
            WatchFaceType.ANALOG,
            object :
                Renderer.CanvasRenderer2<MySharedAssets>(
                    surfaceHolder,
                    currentUserStyleRepository,
                    watchState,
                    CanvasType.HARDWARE,
                    interactiveDrawModeUpdateDelayMillis = 16,
                    clearWithBackgroundTintBeforeRenderingHighlightLayer = true
                ) {
                init {
                    // Listen for user style changes.
                    CoroutineScope(Dispatchers.Main.immediate).launch {
                        currentUserStyleRepository.userStyle.collect {
                            // `userStyle` will contain two userStyle categories with options
                            // from the lists above. ..
                        }
                    }
                }

                override fun render(
                    canvas: Canvas,
                    bounds: Rect,
                    zonedDateTime: ZonedDateTime,
                    sharedAssets: MySharedAssets
                ) {
                    // ...
                }

                override fun renderHighlightLayer(
                    canvas: Canvas,
                    bounds: Rect,
                    zonedDateTime: ZonedDateTime,
                    sharedAssets: MySharedAssets
                ) {
                    canvas.drawColor(renderParameters.highlightLayer!!.backgroundTint)

                    // ...
                }

                override suspend fun createSharedAssets(): MySharedAssets {
                    // Insert resource loading here.
                    return MySharedAssets()
                }
            }
        )
}

return ExampleCanvasWatchFaceService()

Sub classes of WatchFaceService are expected to implement createWatchFace which is the factory for making WatchFaces. If the watch faces uses complications then createComplicationSlotsManager should be overridden. All ComplicationSlots are assumed to be enumerated up upfront and passed as a collection into ComplicationSlotsManager's constructor which is returned by createComplicationSlotsManager.

WatchFaceServices are required to be stateless as multiple can be created in parallel. If per instance state is required please use StatefulWatchFaceService.

Watch face styling (color and visual look of watch face elements such as numeric fonts, watch hands and ticks, etc...) and companion editing is directly supported via UserStyleSchema and UserStyleSetting. To enable support for styling override createUserStyleSchema.

WatchFaceService can expose pre-populated style presets by overriding createUserStyleFlavors or via XML (see below). Each presents represents separate style configured with UserStyle and complication slot policies configured with androidx.wear.watchface.complications.DefaultComplicationDataSourcePolicy. The system will only access flavors if metadata tag is present in manifest:

    <meta-data
android:name="androidx.wear.watchface.FLAVORS_SUPPORTED"
android:value="true" />

WatchFaces are initially constructed on a background thread before being used exclusively on the ui thread afterwards. There is a memory barrier between construction and rendering so no special threading primitives are required.

To aid debugging watch face animations, WatchFaceService allows you to speed up or slow down time, and to loop between two instants. This is controlled by MOCK_TIME_INTENT intents with a float extra called "androidx.wear.watchface.extra.MOCK_TIME_SPEED_MULTIPLIE" and to long extras called "androidx.wear.watchface.extra.MOCK_TIME_WRAPPING_MIN_TIME" and "androidx.wear.watchface.extra.MOCK_TIME_WRAPPING_MAX_TIME" (which are UTC time in milliseconds). If minTime is omitted or set to -1 then the current time is sampled as minTime.

E.g., to make time go twice as fast: adb shell am broadcast -a androidx.wear.watchface.MockTime
--ef androidx.wear.watchface.extra.MOCK_TIME_SPEED_MULTIPLIER 2.0

To use the sample on watch face editor UI, import the wear:wear-watchface-editor-samples library and add the following into your watch face's AndroidManifest.xml:

<activity
android:name="androidx.wear.watchface.editor.sample.WatchFaceConfigActivity"
android:exported="true"
android:label="Config"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="androidx.wear.watchface.editor.action.WATCH_FACE_EDITOR" />
<category android:name=
"com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

To register a WatchFaceService with the system add a tag to the in your watch face's AndroidManifest.xml:

<service
android:name=".MyWatchFaceServiceClass"
android:exported="true"
android:label="@string/watch_face_name"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
</intent-filter>
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/my_watch_preview" />
<meta-data
android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="@drawable/my_watch_circular_preview" />
<meta-data
android:name="com.google.android.wearable.watchface.wearableConfigurationAction"
android:value="androidx.wear.watchface.editor.action.WATCH_FACE_EDITOR"/>
<meta-data
android:name="android.service.wallpaper"
android:resource="@xml/watch_face" />
<meta-data
android:name=
"com.google.android.wearable.watchface.companionBuiltinConfigurationEnabled"
android:value="true" />
</
service>

Multiple watch faces can be defined in the same package, requiring multiple tags.

By default the system will only allow the user to create a single instance of the watch face. You can choose to allow the user to create multiple instances (each with their own styling and a distinct WatchState.watchFaceInstanceId) by adding this meta-data to your watch face's manifest:

    <meta-data
android:name="androidx.wear.watchface.MULTIPLE_INSTANCES_ALLOWED"
android:value="true" />

A watch face can declare the UserStyleSchema, ComplicationSlots and UserStyleFlavors in XML. The main advantage is simplicity for the developer, however meta data queries (see androidx.wear.watchface.client.WatchFaceMetadataClient) are faster because they can be performed without having to bind to the WatchFaceService.

To use xml inflation, add an androidx.wear.watchface.XmlSchemaAndComplicationSlotsDefinition meta date tag to your service:

    <meta-data
android:name="androidx.wear.watchface.XmlSchemaAndComplicationSlotsDefinition"
android:resource="@xml/my_watchface_definition" />

And the linked xml/my_watchface_definition resource must contain a XmlWatchFace node. E.g.:

     <XmlWatchFace xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<UserStyleSchema>
<ListUserStyleSetting
android:icon="@drawable/time_style_icon"
app:affectedWatchFaceLayers="BASE|COMPLICATIONS|COMPLICATIONS_OVERLAY"
app:defaultOptionIndex="1"
app:description="@string/time_style_description"
app:displayName="@string/time_style_name"
app:id="TimeStyle">
<ListOption
android:icon="@drawable/time_style_minimal_icon"
app:displayName="@string/time_style_minimal_name"
app:id="minimal" />
<ListOption
android:icon="@drawable/time_style_seconds_icon"
app:displayName="@string/time_style_seconds_name"
app:id="seconds" />
</ListUserStyleSetting>
</UserStyleSchema>
</ComplicationSlot>
app:slotId="1"
app:boundsType="ROUND_RECT"
app:supportedTypes="SHORT_TEXT|RANGED_VALUE|SMALL_IMAGE"
app:defaultDataSourceType="RANGED_VALUE"
app:systemDataSourceFallback="DATA_SOURCE_WATCH_BATTERY">
<ComplicationSlotBounds
app:left="0.3" app:top="0.7" app:right="0.7" app:bottom="0.9"/>
</ComplicationSlot>
<UserStyleFlavors>
<UserStyleFlavor app:id="flavor1">
<StyleOption app:id="TimeStyle" app:value="minimal"/>
<ComplicationPolicy
app:slotId="1"
app:primaryDataSource="com.package/com.app"
app:primaryDataSourceDefaultType="SHORT_TEXT"
app:systemDataSourceFallback="DATA_SOURCE_DAY_AND_DATE"
app:systemDataSourceFallbackDefaultType="SHORT_TEXT"/>
</UserStyleFlavor>
</UserStyleFlavors>
</XmlWatchFace>

If you use resources references to specify identifiers, they should be locale independent (i.e. translatable="false").

If you use XmlSchemaAndComplicationSlotsDefinition then you shouldn't override createUserStyleSchema or createComplicationSlotsManager. However if tags are defined then you must override getComplicationSlotInflationFactory in order to provide the CanvasComplicationFactory and where necessary edge complication ComplicationTapFilters.

Note the tag does not support configExtras because in general a Bundle can not be inflated from XML.

Note it is an error to define a XmlSchemaAndComplicationSlotsDefinition and not use it.

As of Wear OS 4, complications can provide data using dynamic values, that the platform evaluates continuously and sends the evaluated results to the watch face. Privileged watch faces that can utilize the unevaluated dynamic values, can include the privileged permission com.google.wear.permission.GET_COMPLICATION_DYNAMIC_VALUE in their manifest, which will tell the system to avoid pruning them from the ComplicationData, where they will show up in the relevant fields next to the evaluated values.

use Watch Face Format instead

Summary

Constants

static final int

This field is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

Public constructors

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

Public methods

final @NonNull Handler

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull Handler

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

void

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull WallpaperService.Engine

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

Protected methods

@NonNull ComplicationSlotsManager

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull UserStyleFlavors
@WorkerThread
createUserStyleFlavors(
    @NonNull CurrentUserStyleRepository currentUserStyleRepository,
    @NonNull ComplicationSlotsManager complicationSlotsManager
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull UserStyleSchema

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

abstract @NonNull WatchFace
@WorkerThread
createWatchFace(
    @NonNull SurfaceHolder surfaceHolder,
    @NonNull WatchState watchState,
    @NonNull ComplicationSlotsManager complicationSlotsManager,
    @NonNull CurrentUserStyleRepository currentUserStyleRepository
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

void
@UiThread
dump(
    @NonNull FileDescriptor fd,
    @NonNull PrintWriter writer,
    @NonNull String[] args
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

ComplicationSlotInflationFactory

This method is deprecated. Use the version with currentUserStyleRepository argument instead

@NonNull ComplicationSlotInflationFactory

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

Inherited methods

From android.content.Context
boolean

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final int
getColor(int p0)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull ColorStateList

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @Nullable Drawable
getDrawable(int p0)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull String
getString(int p0)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull String
getString(int p0, @NonNull Object p1)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull T
<T extends Object> getSystemService(@NonNull Class<@NonNull T> p0)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull CharSequence
getText(int p0)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull TypedArray

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull TypedArray

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull TypedArray
obtainStyledAttributes(int p0, @NonNull int[] p1)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

final @NonNull TypedArray
obtainStyledAttributes(
    @Nullable AttributeSet p0,
    @NonNull int[] p1,
    int p2,
    int p3
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

void

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

void
sendBroadcastWithMultiplePermissions(
    @NonNull Intent p0,
    @NonNull String[] p1
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

From android.content.ContextWrapper
boolean
bindIsolatedService(
    @NonNull Intent p0,
    int p1,
    @NonNull String p2,
    @NonNull Executor p3,
    @NonNull ServiceConnection p4
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

boolean

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

boolean

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

boolean

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

boolean
bindService(
    @NonNull Intent p0,
    int p1,
    @NonNull Executor p2,
    @NonNull ServiceConnection p3
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

boolean

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

boolean
bindServiceAsUser(
    @NonNull Intent p0,
    @NonNull ServiceConnection p1,
    int p2,
    @NonNull UserHandle p3
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull int[]

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull int[]

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int
checkContentUriPermissionFull(@NonNull Uri p0, int p1, int p2, int p3)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int
checkPermission(@NonNull String p0, int p1, int p2)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int
checkUriPermission(@NonNull Uri p0, int p1, int p2, int p3)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

int
checkUriPermission(
    @Nullable Uri p0,
    @Nullable String p1,
    @Nullable String p2,
    int p3,
    int p4,
    int p5
)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull int[]
checkUriPermissions(@NonNull List<@NonNull Uri> p0, int p1, int p2, int p3)

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

void

This method is deprecated. Deprecated in Java

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull Context

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

@NonNull String[]

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

boolean

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.

boolean

This method is deprecated. AndroidX watchface libraries are deprecated, use Watch Face Format instead.