构建表盘服务

表盘是一项打包在 Wear OS 应用中的服务。当用户选择可用的表盘时,系统会显示相应表盘并调用服务回调方法。

用户安装包含表盘的 Wear OS 应用时,可通过表盘选择器进行选择,从而在手表上显示表盘。或者,用户也可以通过配对手机上的配套应用选择表盘。

本页介绍了如何配置 Wear OS 项目以包含表盘以及如何实现表盘服务。

创建表盘项目

要在 Android Studio 中为您的表盘创建一个项目,请执行以下操作:

  1. 依次点击 File > New > New project
  2. Create Android Project 窗口中,接受默认值,然后点击 Next
  3. Target Android Devices 窗口中,仅选择 Wear 选项,然后在 SDK 版本列表中选择最新的可用版本。点击 Next
  4. Add an Activity to Wear 窗口中,选择 Watch Face,然后点击 Next
  5. Configure Activity 窗口中,接受默认值,然后点击 Finish

Android Studio 会为您的表盘服务创建一个包含 app 模块的项目。如需详细了解 Android Studio 中的项目,请参阅创建项目

依赖关系

穿戴式设备支持库提供了一些必要的类,您可以扩展这些类来创建表盘实现。 要使用 Wearable Data Layer API 在配套设备与穿戴式设备之间同步数据项,需要 Google Play 服务客户端库(play-servicesplay-services-wearable)。

按照上述说明创建项目时,Android Studio 会在您的 build.gradle 文件中自动添加所需的条目。

穿戴式设备支持库 API 参考

参考文档详细介绍了您用来实现表盘的类。请浏览穿戴式设备支持库的 API 参考文档

注意:我们建议您使用 Android Studio 进行 Wear OS 开发,因为使用它可以方便地设置项目、导入库和打包应用。

声明权限

表盘需要 WAKE_LOCK 权限。请将以下权限添加到 Wear OS 应用(穿戴式设备应用)和移动(手机)应用的清单文件的 manifest 元素下:

    <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>
    

注意:手持式设备应用必须包括在穿戴式设备应用中声明的所有权限。

实现服务和回调方法

Wear OS 中的表盘以服务的形式实现。如果表盘处于活动状态,那么当时间发生变化或发生重要事件(如切换到微光模式或接收新通知)时,系统会调用其服务中的方法。服务实现随后会使用更新后的时间和其他任何相关数据在屏幕上绘制表盘。

要实现表盘,您需要扩展 CanvasWatchFaceServiceCanvasWatchFaceService.Engine 类,然后替换 CanvasWatchFaceService.Engine 类中的回调方法。这些类包含在穿戴式设备支持库中。

以下代码段大体说明了您需要实现的主要方法:

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 */
            }
        }
    }
    

CanvasWatchFaceService 类提供了一种类似于 View.invalidate() 方法的废弃机制。当您希望系统重新绘制表盘时,可以在整个实现过程中调用 invalidate() 方法。您只能在主界面线程中使用 invalidate() 方法。要从其他线程废弃画布,请调用 postInvalidate() 方法。

如需详细了解如何实现 CanvasWatchFaceService.Engine 类中的方法,请参阅绘制表盘

注册表盘服务

实现表盘服务后,您可以在穿戴式设备应用的清单文件中注册实现。当用户安装此应用时,系统会使用服务的相关信息让表盘显示在 Wear OS 配套应用和穿戴式设备上的表盘选择器中。

以下代码段展示了如何在 application 元素下注册表盘实现:

    <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>
    

在向用户显示设备上安装的所有表盘时,Wear OS 配套应用和穿戴式设备上的表盘选择器将使用 com.google.android.wearable.watchface.preview 元数据条目定义的预览图片。要获取这一可绘制对象,请在 Wear OS 设备上或模拟器实例中运行表盘并截取屏幕截图。在屏幕的像素密度为 hdpi 的 Wear OS 设备上,预览图片的大小一般为 320x320 像素。

在圆形设备上看起来截然不同的表盘可同时提供圆形和方形预览图片。要指定圆形预览图片,请使用 com.google.android.wearable.watchface.preview_circular 元数据条目。如果表盘同时包含两种预览图片,配套应用和穿戴式设备上的表盘选择器将根据手表的形状显示合适的图片。如果不包含圆形预览图片,则对方形和圆形设备都使用方形预览图片。对于圆形设备,将使用圆形剪裁方形预览图片。

android.service.wallpaper 元数据条目可指定 watch_face.xml 资源文件,该文件包含一个 wallpaper 元素:

    <?xml version="1.0" encoding="UTF-8"?>
    <wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />
    

您的穿戴式设备应用可以包含多个表盘。您必须在穿戴式设备应用的清单文件中为每个表盘实现添加一个服务条目。