HarmonyOS 穿戴服务:让你的应用和手表对话

什么是穿戴服务

你有没有想过,手机上的 App 怎么和手表上的 App 通信?比如手机上收到消息,手表上也能看到。穿戴服务(Wear Engine)就是让手机和手表之间能互相通信的工具。

穿戴服务提供了三个核心能力:

  1. 授权管理:管理手机和手表之间的权限。就像你去别人家做客,得先敲门得到允许才能进去。手机 App 想和手表 App 通信,也得先获取用户的授权
  2. 设备管理:获取已连接的手表设备信息。比如手表的名称、型号、软件版本等。你还可以查询手表支持哪些能力,比如是否支持文件传输、是否支持消息通信等
  3. 端对端通信:手机和手表之间互发消息和文件。比如手机上收到一条消息,可以立刻同步到手表上显示;或者手机上拍了一张照片,可以传到手表上当表盘背景

简单说,穿戴服务就是一个"手机-手表通信桥梁",让你的手机 App 能和手表 App 互相交流。

核心功能

穿戴服务提供以下功能:

  1. 授权管理:申请和查询用户授权。首次使用穿戴服务时,系统会弹出授权页面,让用户选择允许哪些权限。你可以查询当前已经授权了哪些权限,避免重复申请
  2. 设备管理:获取已连接设备列表、查询设备能力。比如获取当前连接的手表列表,检查手表是否支持某个功能(比如是否支持文件传输)。这些信息可以帮助你适配不同的手表型号
  3. 消息通信:手机和手表之间互发消息。消息是轻量级的数据,适合传递简单的指令或状态。比如手机 App 告诉手表 App"有新消息了",手表收到后震动提醒用户
  4. 文件传输:手机和手表之间互传文件。文件传输比消息通信更重量级,适合传递图片、音频等数据。比如把手机上的照片传到手表上当表盘背景
  5. 应用管理:检查设备侧应用是否安装、获取版本号、拉起应用。比如你可以检查手表上是否安装了你的 App,如果没有安装,可以引导用户去安装

环境搭建

硬件要求

  • 设备类型:华为手机、华为平板
  • HarmonyOS 系统:HarmonyOS NEXT Developer Beta2 及以上

软件要求

  • DevEco Studio 版本:DevEco Studio NEXT Developer Beta2 及以上
  • HarmonyOS SDK 版本:HarmonyOS NEXT Developer Beta2 SDK 及以上

搭建步骤

  1. 安装 DevEco Studio:去华为开发者官网下载安装
  2. 配置开发环境:确保网络环境正常
  3. 设备调试:使用真机进行调试
  4. 申请服务:参考官方文档申请 Wear Engine 服务

项目结构

├── entry/src/main/ets
│  ├── entryability
│  │  └── EntryAbility.ets    // 程序入口类
│  ├── pages
│  │  ├── Index.ets           // 主页面
│  │  ├── AuthPage.ets        // 授权管理页面
│  │  ├── DevicePage.ets      // 设备信息页面
│  │  └── P2pPage.ets         // 端对端应用通信页面
│  └── util
│     └── Constant.ets        // 通用常量
└── entry/src/main/resources  // 资源文件目录

项目按功能分成了几个页面,每个页面对应穿戴服务的一个功能。

穿戴服务授权流程

下面是穿戴服务的授权和设备连接流程:

导入穿戴服务模块

创建 AuthClient 实例

调用 requestAuthorization

弹出授权页面

用户是否授权?

获取已授权权限

无法使用穿戴服务

创建 DeviceClient 实例

获取已连接设备列表

查询设备能力

设备就绪

端对端通信流程

下面是手机与手表的端对端通信流程:

发送消息

发送文件

接收消息

接收文件

创建 P2pClient 实例

配置设备侧应用信息

通信类型

调用 sendMsg

调用 sendFile

注册 registerMsgReceiver

注册 registerFileReceiver

消息发送到手表

文件传输到手表

监听消息回调

监听文件回调

通信完成

第一步:导入模块

import { wearEngine } from '@kit.WearEngine';
import { BusinessError } from '@kit.BasicServicesKit';

导入手穿戴服务的核心模块。

第二步:授权管理

在使用穿戴服务之前,需要先获取用户授权。

// 获取 AuthClient 实例
@State authClient: wearEngine.AuthClient = wearEngine.getAuthClient(getContext(this));

// 创建权限请求类
@State request: wearEngine.AuthorizationRequest = {
  permissions: []
};

创建 AuthClient 实例和权限请求对象。

// 申请用户授权
this.authClient.requestAuthorization(this.request).then((result) => {
  console.info(`Succeeded in requesting authorization, authorized permissions are ${JSON.stringify(result.permissions)}.`);
}).catch((error: BusinessError) => {
  console.error(`Failed to request authorization. Code is ${error.code}, message is ${error.message}.`);
});

调用 requestAuthorization 申请用户授权。这会弹出授权页面,让用户选择允许哪些权限。

// 获取全部已授权的权限
this.authClient.getAuthorization().then((result) => {
  console.info(`Succeeded in getting authorized permissions, result is ${JSON.stringify(result.permissions)}.`);
}).catch((error: BusinessError) => {
  console.error(`Failed to get authorized permissions. Code is ${error.code}, message is ${error.message}.`);
});

调用 getAuthorization 获取已经授权的权限列表。

第三步:获取已连接设备

穿戴设备需要先和手机上的运动健康 App 连接,才能获取到设备信息。

// 获取 DeviceClient 实例
@State deviceClient: wearEngine.DeviceClient = wearEngine.getDeviceClient(getContext(this));

// 用于存储已连接设备列表的数组
@State deviceList: wearEngine.Device[] = [];

创建 DeviceClient 实例,用来获取设备信息。

// 获取已连接设备列表
this.deviceClient.getConnectedDevices().then(devices => {
  this.deviceList = devices;
  console.info(`Succeeded in getting devices, devices number is ${devices.length}`);
}).catch((error: BusinessError) => {
  console.error(`Failed to get devices. Code is ${error.code}, message is ${error.message}`);
});

调用 getConnectedDevices 获取已连接的设备列表。返回的设备对象包含设备名称、型号、软件版本等信息。

第四步:查询设备能力

获取到设备后,可以查询设备支持哪些能力。

// 查询设备的 Device 能力集支持情况
this.changeItem.isDeviceCapabilitySupported(this.deviceCapabilityId).then(value => {
  console.info(`Succeeded in checking device capability: ${this.deviceCapabilityId}, result is ${value}`);
}).catch((error: BusinessError) => {
  console.error(`Failed to check device capability. Code is ${error.code}, message is ${error.message}`);
});

// 查询设备的 WearEngine 能力集支持情况
this.changeItem.isWearEngineCapabilitySupported(this.wearengineCapabilityId).then(value => {
  console.info(`Succeeded in checking wear engine capability: ${this.wearengineCapabilityId}, result is ${value}`);
}).catch((error: BusinessError) => {
  console.error(`Failed to check wear engine capability. Code is ${error.code}, message is ${error.message}`);
});

调用 isDeviceCapabilitySupportedisWearEngineCapabilitySupported 查询设备是否支持某个能力。

第五步:端对端通信

端对端通信(P2P)让你的手机 App 和手表 App 之间可以互发消息和文件。

// 获取 P2pClient 实例
@State p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));

// 设备侧应用信息
private appInfo: wearEngine.AppInfo = {
  bundleName: this.watchBundleName,
  fingerprint: 'a'
};

// P2P 通信参数
private appParam: wearEngine.P2pAppParam = {
  remoteApp: this.appInfo
};

创建 P2pClient 实例,配置设备侧应用信息。

发送消息

// 发送消息到手表
this.p2pClient.sendMsg(this.changeItem, this.appParam, messageData).then(() => {
  console.info('Succeeded in sending message.');
}).catch((error: BusinessError) => {
  console.error(`Failed to send message. Code is ${error.code}, message is ${error.message}`);
});

调用 sendMsg 发送消息到手表。手表侧的应用需要先订阅消息接收事件。

接收消息

// 订阅消息接收事件
private msgCallback = (msg: wearEngine.P2pMessage) => {
  let decoder: util.TextDecoder = util.TextDecoder.create();
  let str: string = decoder.decodeWithStream(msg.content);
  console.info(`receive message: ${str}`);
};

// 注册消息接收回调
this.p2pClient.registerMsgReceiver(this.changeItem, this.appParam, this.msgCallback).then(() => {
  console.info('Succeeded in registering message receiver.');
}).catch((error: BusinessError) => {
  console.error(`Failed to register message receiver. Code is ${error.code}, message is ${error.message}`);
});

调用 registerMsgReceiver 注册消息接收回调。当手表发来消息时,会调用这个回调函数。

接收文件

// 订阅文件接收事件
private fileCallback = (file: wearEngine.P2pFile) => {
  console.info(`receive file: ${file.file.name}`);
};

// 注册文件接收回调
this.p2pClient.registerFileReceiver(this.changeItem, this.appParam, this.fileCallback).then(() => {
  console.info('Succeeded in registering file receiver.');
}).catch((error: BusinessError) => {
  console.error(`Failed to register file receiver. Code is ${error.code}, message is ${error.message}`);
});

调用 registerFileReceiver 注册文件接收回调。当手表发来文件时,会调用这个回调函数。

实际应用场景

穿戴服务在实际开发中有很多用途:

消息同步

// 手机收到消息后,同步到手表
async function syncMessageToWatch(message: string) {
  let p2pClient = wearEngine.getP2pClient(context);
  let deviceClient = wearEngine.getDeviceClient(context);
  let devices = await deviceClient.getConnectedDevices();
  
  if (devices.length > 0) {
    let appParam: wearEngine.P2pAppParam = {
      remoteApp: { bundleName: 'com.example.watchapp', fingerprint: 'xxx' }
    };
    await p2pClient.sendMsg(devices[0], appParam, messageData);
  }
}

远程控制

// 用手表控制手机拍照
async function remoteControl() {
  p2pClient.registerMsgReceiver(device, appParam, (msg) => {
    let command = decoder.decodeWithStream(msg.content);
    if (command === 'take_photo') {
      takePhoto();
    }
  });
}

健康数据同步

// 手表的健康数据同步到手机
async function syncHealthData() {
  p2pClient.registerFileReceiver(device, appParam, (file) => {
    // 处理接收到的健康数据文件
    processHealthData(file.file);
  });
}

适用场景

穿戴服务适合以下场景:

  • 消息应用:消息同步到手表
  • 健康应用:健康数据同步
  • 运动应用:运动数据实时显示
  • 远程控制:用手表控制手机
  • 支付应用:手表端支付确认

注意事项

  1. 设备连接:手表需要先和手机运动健康 App 连接
  2. 权限申请:需要申请 Wear Engine 服务并获取用户授权
  3. 包名配置:需要正确配置设备侧应用的包名和指纹
  4. 能力检查:使用前要检查设备是否支持对应能力
  5. 订阅管理:不需要时要及时取消订阅

总结

穿戴服务让你的手机 App 和手表 App 互相通信,核心流程:

  1. 申请用户授权
  2. 获取已连接设备
  3. 查询设备能力
  4. 使用端对端通信发送消息/文件

掌握了这些,你就能开发出手表和手机联动的应用,提升用户体验。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐