智能客服
你问我答,随时在线为你解决问题
智能穿戴是一种腕部可穿戴设备,提供沟通功能和与移动设备的数据交互功能,包括成人智能表和儿童智能表。智能穿戴设备具有以下显著特点:
目前, 智能穿戴设备主要有WATCH 5、WATCH Ultimate 2和超新星 X系列产品。
产品名称 | 示意图 |
|---|---|
WATCH 5 |
|
WATCH Ultimate 2 |
|
超新星 X系列 |
|
智能穿戴设备屏幕不支持旋转,屏幕旋转角度为0°,屏幕方向为竖屏。下表以WATCH 5和超新星 X1 Pro产品为例,展示产品的屏幕规格信息。
产品名称 | 屏幕规格信息(宽*高) | 示意图 |
|---|---|---|
WATCH 5 | 分辨率(vp)(向下取整):233*233 |
|
分辨率(px):466*466 | ||
超新星 X1 Pro | 分辨率(vp)(向下取整):240*204 |
|
分辨率(px):480*408 |
其他智能穿戴设备产品可通过display的getDefaultDisplaySync()方法获取设备屏幕分辨率(px),通过px2vp()方法得到分辨率的vp值。
部分智能穿戴设备(如儿童智能表超新星 X系列产品)配置前置和后置摄像头,在进行摄像头相关开发时需要关注镜头安装角度和预览流旋转角度。相关定义可参考相机镜头安装角度和预览旋转角度。镜头参数可参考下表。
屏幕旋转角度(rotation) | 0(0度) | 1(90度) | 2(180度) | 3(270度) |
|---|---|---|---|---|
前置相机示意图 |
| 不支持 | 不支持 | 不支持 |
前置相机镜头角度 | 0度 | 不支持 | 不支持 | 不支持 |
前置相机拍摄预览流旋转角度 | 0度 | 不支持 | 不支持 | 不支持 |
屏幕旋转角度(rotation) | 0(0度) | 1(90度) | 2(180度) | 3(270度) |
|---|---|---|---|---|
后置相机示意图 |
| 不支持 | 不支持 | 不支持 |
后置相机镜头角度 | 0度 | 不支持 | 不支持 | 不支持 |
后置相机拍摄预览流旋转角度 | 0度 | 不支持 | 不支持 | 不支持 |
智能穿戴的表冠(上键)支持按压与旋转两种交互方式,其旋转操作可触发实时交互响应。系统通过onDigitalCrown()回调函数处理表冠旋转事件,并已为常用组件内置了表冠交互支持。
主要特性:
- Text(this.count.toString())
- // ...
- .onDigitalCrown((event: CrownEvent) => {
- event.stopPropagation();
- this.count += event.degree;
- })
默认支持表冠交互的组件包括:
开发者可通过开放接口自定义表冠事件处理逻辑,实现更丰富的交互体验。关于智能穿戴表冠旋转事件的开发,可以参考表冠事件。
智慧手势是智能穿戴设备除屏幕交互、表冠交互和按键交互外的独特感知交互方式。在情景障碍,需要单手处理的场景,用户可以使用敲击手指和滑动指关节实现控制和切换选择诉求。
交互场景
手势类型
实现原理:系统识别手势后,会触发组件的onKeyEvent事件,KeyCode为KEYCODE_ENTER,type为KeyType.Down,应用可以在该条件触发后进行功能执行,如暂停音乐。
示例代码:
- .onKeyEvent((event: KeyEvent) => {
- if (event.keyCode === KeyCode.KEYCODE_ENTER && event.type === KeyType.Down) {
- // Trigger the pinching gesture
- this.oneButton1Color = '#ffe3ba51';
- this.oneButton1Text = 'Confirm';
- }
- })

实现原理:系统识别手势后,会分别触发失焦组件和获焦组件的onBlur和onFocus事件,应用可以在该条件触发后进行功能执行,如更改获焦组件的样式为高亮展示。
示例代码:
- .onFocus(() => {
- this.oneButton1Color = '#ff57c853';
- this.oneButton1Text = 'Hover';
- this.oneButton2Text = 'Two';
- })
- .onBlur(() => {
- this.oneButton1Color = '';
- this.oneButton1Text = 'One';
- })

智慧手势交互的前提是组件获焦。首先使用activate激活当前界面的焦点激活态。
- this.getUIContext().getFocusController().activate(true, false);
激活焦点激活态后,可调用requestFocus()方法使目标组件获得焦点,随后手势操作方可生效。示例代码如下,页面渲染后默认使得id为"btn1"的按钮获焦:
- // register a button to get focus by default.
- this.getUIContext().getFocusController().requestFocus('btn1');
退出页面时,设置当前界面的焦点激活态为false,退出焦点激活态。
- aboutToDisappear(): void {
- this.getUIContext().getFocusController().activate(false);
- }
为提升智能穿戴设备续航能力并给用户带来更持久、更流畅的使用体验,可以采取以下措施:

若应用涉及导航、视频等需要保持应用常亮的场景,可以根据如下步骤实现:
- onWindowStageCreate(windowStage: window.WindowStage): void {
- let windowClass: window.Window | undefined = undefined;
- window.getLastWindow(this.context, (err: BusinessError, data: window.Window) => {
- const errCode: number = err.code;
- if (errCode) {
- hilog.error(0x0000, TAG, 'Failed to obtain the top window. Cause: ' + JSON.stringify(err));
- return;
- }
- windowClass = data;
- hilog.info(0x0000, TAG, 'Succeeded in obtaining the top window. Data: ' + JSON.stringify(data));
- AppStorage.setOrCreate('windowClass', windowClass);
- });
- // ...
- }
- // Window object obtained from EntryAbility, which is used to ensure that the screen is steady on during navigation.
- @StorageLink('windowClass') windowClass: window.Window | undefined = undefined;
- // ...
-
- aboutToAppear(): void {
- // ...
- if (this.windowClass) {
- this.windowClass.setWindowKeepScreenOn(true, (err: BusinessError) => {
- const errCode: number = err.code;
- if (errCode) {
- hilog.error(0x0000, TAG,
- `Failed to set the screen to be always on. Cause code: ${err.code}, message: ${err.message}`);
- return;
- }
- hilog.info(0x0000, TAG, 'Succeeded in setting the screen to be always on.');
- });
- }
- }
手机与智能穿戴设备的互联通信是智能穿戴设备的核心开发场景,开发者可通过WearEngine提供的标准化接口实现跨设备交互,具体开发流程如下:
- export class ConnectUtil {
- // Peer communication device entity class object
- device?: wearEngine.Device;
- // Unique ID of the peer communication device.
- deviceRandomId?: string;
- // Used to obtain linked devices
- deviceClient?: wearEngine.DeviceClient;
- // ...
-
- constructor(context: Context) {
- if (canIUse('SystemCapability.Health.WearEngine')) {
- this.deviceClient = wearEngine.getDeviceClient(context);
- // ...
- }
- }
- // ...
- }
- // Obtains the information about the peer device connected to the peer device
- // and listens on the communication between the peer device and the peer device.
- async getConnectedDevices(): Promise<void> {
- try {
- if (canIUse('SystemCapability.Health.WearEngine')) {
- let devices: wearEngine.Device[] = await this.deviceClient?.getConnectedDevices() as wearEngine.Device[];
- this.device = devices[0];
- this.deviceRandomId = devices[0].randomId;
- }
- await this.registerMessageReceiver();
- } catch (err) {
- hilog.error(0x0000, TAG, 'getConnectedDevices is err' + JSON.stringify(err));
- }
- }
- export class ConnectUtil {
- // ...
- // Used to p2p
- p2pClient?: wearEngine.P2pClient;
- // ...
-
- constructor(context: Context) {
- if (canIUse('SystemCapability.Health.WearEngine')) {
- // ...
- this.p2pClient = wearEngine.getP2pClient(context);
- }
- }
- // ...
- }
- // Callback Method for Listening to Peer Communication.
- private onMsgCallback: Callback<wearEngine.P2pMessage> = (data: wearEngine.P2pMessage): void => {
- // Decodes the intercepted content into a character string.
- let decoder: util.TextDecoder = util.TextDecoder.create();
- if (canIUse('SystemCapability.Health.WearEngine')) {
- let str: string = decoder.decodeToString(data.content);
- promptAction.openToast({
- message: 'message: ' + str,
- duration: 2000
- });
- }
- }
-
- // Listening to the communication between the peer end.
- async registerMessageReceiver(): Promise<void> {
- try {
- if (canIUse('SystemCapability.Health.WearEngine')) {
- await this.p2pClient?.registerMessageReceiver(this.deviceRandomId, appParam, this.onMsgCallback);
- hilog.info(0x0000, TAG, 'registerMessageReceiver is ok');
- }
- } catch (err) {
- hilog.error(0x0000, TAG, 'registerMessageReceiver is err ', JSON.stringify(err));
- }
- }
-
- // Disabling the Interception of Peer Communication。
- async unregisterMessageReceiver(): Promise<void> {
- try {
- if (canIUse('SystemCapability.Health.WearEngine')) {
- await this.p2pClient?.unregisterMessageReceiver(this.deviceRandomId, appParam, this.onMsgCallback);
- hilog.info(0x0000, TAG, 'unregisterMessageReceiver is ok');
- }
- } catch (err) {
- hilog.error(0x0000, TAG, 'unregisterMessageReceiver is err ', JSON.stringify(err));
- }
- }
- // Method of sending messages to the peer end
- async sendMessage(message: string): Promise<void> {
- try {
- let p2pMessage: wearEngine.P2pMessage = this.getP2pMessage(message);
- if (canIUse('SystemCapability.Health.WearEngine')) {
- let value = await this.p2pClient?.sendMessage(this.deviceRandomId, appParam, p2pMessage);
- hilog.info(0x0000, TAG, 'sendMessage value is' + JSON.stringify(value))
- }
- } catch (err) {
- hilog.error(0x0000, TAG, 'sys sendMessage is err ' + JSON.stringify(err));
- }
- }
智能穿戴设备的消息通知来源包括:
手机应用通知
在华为运动健康APP中,进入消息通知设置界面,为指定手机应用开启通知权限,即可将该应用的消息实时同步至已配对的华为智能穿戴设备。
手机主动推送
手机应用可以通过WearEngine的notify()实现手机向智能穿戴设备主动推送消息通知,开发步骤如下:
- // Used to notify message
- notifyClient: wearEngine.NotifyClient | undefined;
使用当前组件所在Ability的Context,获取Notify模块的客户端。
- try {
- this.connectUtils.notifyClient = wearEngine.getNotifyClient(this.getUIContext().getHostContext());
- } catch (err) {
- hilog.error(0x0000, TAG,
- `Failed to get notify client. Cause code: ${err.code}, message: ${err.message}`);
- }
- /*
- * Method of notifying a message to watch.
- */
- notifyMessage() {
- // Configure the notification content.
- // Including the package name of the notification source, notification title, and notification content.
- let type1Notification: wearEngine.Notification = {
- type: wearEngine.NotificationType.NOTIFICATION_WITHOUT_BUTTONS,
- bundleName: 'com.example.smartwatchmapnavigation',
- title: 'smartwatchmapnavigation',
- text: 'walk navigation start',
- }
- let options: wearEngine.NotificationOptions = {
- notification: type1Notification,
- onAction: (feedback: wearEngine.NotificationFeedback) => {
- hilog.info(0x000, TAG,
- `one button notify get feedback is ${feedback.action ? feedback.action : feedback.errorCode}`);
- }
- }
-
- // Sends a notification to the watch based on notifyClient.
- // This method can be invoked only by apps on mobile phones.
- this.notifyClient!.notify(this.deviceRandomId, options).then(result => {
- hilog.info(0x000, TAG, `Succeeded in sending notification.`);
- }).catch((error: BusinessError) => {
- hilog.error(0x000, TAG, `Failed to send notification. Code is ${error.code}, message is ${error.message}`);
- })
- }
使用WearEngine的NotifyClient.notify()需要获取WearEngine权限,具体可以参考申请接入Wear Engine服务。
智能穿戴设备本地通知
智能穿戴设备应用可以通过NotificationManager模块实现自主发送通知。
可通过requestEnableNotification的错误码判断用户是否授权。若返回的错误码为1600004,即为拒绝授权。
- aboutToAppear() {
- let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
- notificationManager.isNotificationEnabled().then((data: boolean) => {
- hilog.info(DOMAIN_NUMBER, TAG, "isNotificationEnabled success, data: " + JSON.stringify(data));
- if (!data) {
- notificationManager.requestEnableNotification(context).then(() => {
- hilog.info(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification success`);
- }).catch((err: BusinessError) => {
- if (1600004 == err.code) {
- hilog.error(DOMAIN_NUMBER, TAG,
- `[ANS] requestEnableNotification refused, code is ${err.code}, message is ${err.message}`);
- } else {
- hilog.error(DOMAIN_NUMBER, TAG,
- `[ANS] requestEnableNotification failed, code is ${err.code}, message is ${err.message}`);
- }
- });
- }
- }).catch((err: BusinessError) => {
- hilog.error(DOMAIN_NUMBER, TAG, `isNotificationEnabled fail, code is ${err.code}, message is ${err.message}`);
- });
- }
- Button('发送通知')
- .onClick(()=>{
- let notificationRequest: notificationManager.NotificationRequest = {
- id: 1,
- content: {
- // General text type notification.
- notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
- normal: {
- title: 'test_title',
- text: 'test_text',
- additionalText: 'test_additionalText',
- }
- }
- };
- notificationManager.publish(notificationRequest, (err: BusinessError) => {
- if (err) {
- hilog.error(DOMAIN_NUMBER, TAG, `Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
- return;
- }
- hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in publishing notification.');
- });
- })
智能穿戴设备中的儿童智能表应用面向儿童用户,启蒙教育、内容展示、社交互动、音视频、游戏等应用应重点评估未成年人保护要求。应用如需跟随系统未成年人模式调整内容展示、功能入口或使用时长,应适配未成年人模式能力。
未成年人模式相关能力可参考Account Kit(华为账号服务)中的minorsProtection能力。开发者应根据应用场景判断是否需要获取未成年人模式开启状态、年龄段信息,或引导用户开启未成年人模式。
智能穿戴设备上如何进行工程调试
问题描述:拿到智能穿戴设备后,不知如何将应用部署到智能穿戴设备上调试应用功能。
解决方案:智能穿戴使用WIFI无线调试(支持自动签名),调试规范如下:
智能穿戴设备上如何进行工程配置
问题描述:不知道智能穿戴设备需要完成哪些工程配置,成人智能表和儿童智能表的工程配置有哪些不同。
解决方案:开发在智能穿戴设备上的应用,需要在module.json5配置文件的module字段中,为deviceTypes字段设置wearable类型。更多详情可参考deviceTypes标签。若当前已有适配轻量级智能表的工程,需要迁移适配成人智能表设备,可以参考FA工程迁移。
成人智能表应用完成以上配置即可,儿童智能表应用需要额外添加儿童智能表分发策略配置,DevEco Studio需更新至6.1.0 Release及以上,具体步骤如下:
- {
- "distributionFilter": {
- "screenShape": {
- "policy": "include",
- "value": [
- "rect"
- ]
- },
- "screenWindow": {
- "policy": "include",
- "value": [
- "480*408"
- ]
- }
- }
- }
- {
- "module": {
- "deviceTypes": [
- "wearable"
- ],
- "metadata": [
- {
- "name": "string",
- "value": "string",
- "resource": "$profile:distributionFilter_config"
- }
- ],
- "requiredDeviceFeatures": {
- "wearable": [
- "child"
- ]
- }
- }
- }
- {
- "targetSdkVersion": "6.1.0(23)",
- "compatibleSdkVersion": "6.1.0(23)"
- }
采用“一次开发,多端部署”分层架构开发的应用工程,如何管理智能穿戴设备与其他设备上的应用HAP包
问题描述:应用采用“一次开发,多端部署”将手机端、智能穿戴端的应用在一个工程中管理,不知该如何管理HAP包。
解决方案:由于应用在智能穿戴设备上的页面设计、功能形态会与其他设备有明显差异,因此推荐独立HAP精准适配的HAP包的管理策略:
更多详情可参见分层架构设计的产品定制层相关内容。
手表应用发布注意事项
问题描述:手表应用在涉及到智能穿戴设备与轻量级智能穿戴设备时,应用发布的常见问题以及注意事项。

解决方案:

儿童智能表除上述流程外,还存在额外审核和材料要求,请参考儿童智能表发布注意事项。
应用在某智能穿戴设备上能够正常使用,安装到另一款设备产品上后应用崩溃闪退/功能无响应
问题描述:应用在某款智能穿戴设备上能够正常使用功能,在另一款智能穿戴设备上使用时应用崩溃闪退/功能无响应。
可能原因:不同智能穿戴设备的硬件配置与系统能力支持度存在差异。应用未针对这些设备差异进行充分的兼容性适配。
解决方案:
迁移FA项目后,同步/异步接口无法正常调用或功能异常
问题描述:迁移项目后,原项目中的同步/异步接口无法正常调用或功能异常。
解决方案:需要改写接口调用方式,以huks.generateKeyItem()接口为例,原项目中:
- huks.generateKeyItem(alias, options, callback);
迁移项目后,改写为:
- try {
- const data = await huks.generateKeyItem(alias, options);
- // Result of successful processing.
- } catch (error) {
- // Capture and handle exceptions.
- }
迁移FA工程后,无法与手机侧通信
问题描述:完成项目迁移后,原项目有与手机侧通信交互的功能,但是新项目该功能无法使用。
可能原因:应用使用指纹信息来验证进行应用间的通信,迁移后应查询新应用的APP ID并在配置文件中更改值。
解决方案:通过"hdc shell bm dump –n YourBundleName | grep appIdentifier"获取穿戴侧应用的APP ID,在两侧应用的配置文件中更改fingerprint。
儿童智能表应用在发布时存在额外审核和材料要求。
应用发布的通用配置和流程可参考发布HarmonyOS应用。儿童智能表除遵循智能穿戴应用发布要求外,还需满足以下差异化要求:
具体操作说明如下:
儿童智能表开发前,发送邮件【华为儿童智能手表应用上架申请】到邮箱developer@huawei.com,邮件内提供如下信息,已与华为接口人取得联系的开发者,可将相关信息提交给接口人,由接口人配置应用白名单,接口人包括商业拓展(BD)和解决方案(SA)负责人:
APP名称 | xxx |
包名 | xxx.xxx.xxx |
APP版本号 | xxx |
APP ID | xxx(APP ID的创建,可参考为HarmonyOS应用创建APP ID) |
分发的表侧 | 仅儿童智能表;成人智能表+儿童智能表 |
APP名称是否与成人智能表相同 | 是/否(如果APP名称相同,则包名不能相同,包名需要核准,可参考HarmonyOS应用核准(备案)) |
APP名称是否与手机、平板、电脑等其他品类相同 | 是/否(如果APP名称相同,则包名不能相同,包名需要核准,可参考HarmonyOS应用核准(备案)) |
开发者名称 | xxx |
其他说明(重要) | 含应用介绍、免费内容占比、应用功能说明(形式不限)等 |
申请结果会在十个工作日内反馈。
准许通过后,请开发者参照《华为儿童智能表三方应用守则》评估开发,并在开发完成后提供《华为儿童智能表三方应用守则》的自检回执到邮箱developer@huawei.com或对应的华为接口人。
儿童智能表应用开发完成后,提交应用时选择智能手表选项,儿童智能表应用在智能手表选项下。发布应用的通用配置和流程可参考发布HarmonyOS应用。在提交时,忽略以下弹窗,点击确认或关闭按钮以继续下一步操作:

应用分类:根据应用特性选择相关分类(如音乐、休闲娱乐、儿童等),“应用/儿童”为非必选项。

应用标签:至少选择一个标签作为应用主标签,同时可以再选择一个或多个其它标签作为补充(非必须)。根据应用特性选择标签,“儿童”为非必选项。

智能穿戴设备兼容FA模型,本章节提供了如何将使用JS构建的轻量级智能穿戴项目迁移到智能穿戴设备上继续使用,实现功能的延续与适配。
以轻量级智能穿戴应用开发为例,按照如下步骤,可以将使用JS构建的项目迁移到智能穿戴设备上:


工程名目录右键选择“New”->“Module”创建模块。

选择“Empty Ability”,点击“Next”进入下一步。

默认配置无需修改,点击“Next”进入下一步。

为了兼容智能穿戴,需要修改Ability name为“HiWearMainAbility”。点击“Finish”完成智能穿戴兼容模块创建。

删除工程默认创建的entry模块,此时实现轻量级智能穿戴项目迁移的基础框架创建完成。


迁移的文件后需要修改config.json。修改资源文件的引用;pages目录下如果有新页面文件需添加至config.json;修改页面设计基线宽度为466。

config.json文件中补充所需的权限。如果原项目中使用了震动功能,需添加震动权限。

- huks.generateKeyItem(alias, options, callback);
在轻量级智能穿戴设备上,回调将同步执行。但在智能穿戴设备上是异步的,因此需要更改书写样式增加await,保证代码同轻量级智能穿戴设备一样同步执行。
- try {
- const data = await huks.generateKeyItem(alias, options);
- // Result of successful processing.
- } catch (error) {
- // Capture and handle exceptions.
- }