• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 为跨设备协同通知添加快捷回复
2
3<!--Kit: Notification Kit-->
4<!--Subsystem: Notification-->
5<!--Owner: @peixu-->
6<!--Designer: @dongqingran; @wulong158-->
7<!--Tester: @wanghong1997-->
8<!--Adviser: @huipeizi-->
9
10从API version 18开始,支持为跨设备协同通知添加快捷回复。
11
12当手机应用通过指定事件ID订阅通知回复事件、并发布支持快捷回复的通知到手表时,用户无需解锁手机,即可在手表上查看通知消息并快捷回复。
13
14## 前提条件
15
16 - 用户已通过手机中运动健康App连接手表。
17 - 用户已在手机的“运动健康App > 设备 > 消息通知”中,开启“同步手机消息通知至手表”开关与“支持的应用”通知开关。
18
19## 实现原理
20
21快捷回复的实现原理如下。其中,开发者仅需要实现步骤1和步骤2,步骤6为用户操作,其他均由系统实现。
22
23![notification_introduction](figures/notification_quickreply.png)
24
25## 接口说明
26
27| **接口名**  | **描述** |
28| -------- | -------- |
29| [publish](../reference/apis-notification-kit/js-apis-notificationManager.md#notificationmanagerpublish-1)(request: NotificationRequest): Promise\<void\>       | 发布通知。  |
30| [on](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#on)(method: string, callback: CalleeCallback): void       | 通用组件服务端注册消息通知callback。  |
31
32## 开发步骤
33
341. 导入模块。
35
36    ```typescript
37    import { notificationManager } from '@kit.NotificationKit';
38    import { AbilityConstant, UIAbility, Want, wantAgent, WantAgent } from '@kit.AbilityKit';
39    import { window } from '@kit.ArkUI';
40    import { rpc } from '@kit.IPCKit';
41    import { BusinessError } from '@kit.BasicServicesKit';
42    ```
43
442. 手机中应用订阅通知回复事件。
45
46    ```typescript
47    class MySequenceable implements rpc.Parcelable {
48      inputKey: string = ''
49      userInput: string = ''
50
51      constructor(inputKey: string, userInput: string) {
52        this.inputKey = inputKey
53        this.userInput = userInput
54      }
55
56      marshalling(messageParcel: rpc.MessageSequence) {
57        messageParcel.writeString(this.inputKey)
58        messageParcel.writeString(this.userInput)
59        return true
60      }
61
62      unmarshalling(messageParcel: rpc.MessageSequence) {
63        this.inputKey = messageParcel.readString()
64        this.userInput = messageParcel.readString()
65        return true
66      }
67    }
68
69    function sendMsgCallback(data: rpc.MessageSequence) {
70      // 获取客户端发送的序列化数据
71      let receivedData = new MySequenceable('', '')
72      // receivedData.inputKey为value1.
73      receivedData.inputKey = data.readString();
74      // receivedData.userInput为用户指定的快捷回复内容。
75      receivedData.userInput = data.readString();
76      console.info(`inputKey : ${JSON.stringify(receivedData.inputKey)}`);
77      console.info(`userInput : ${JSON.stringify(receivedData.userInput)}`);
78
79      return new MySequenceable('', '')
80    }
81
82    export default class EntryAbility extends UIAbility {
83      onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
84        console.info('Ability onCreate');
85        console.info(`onCreate ${JSON.stringify(want)}`);
86        try {
87          // 服务端注册消息通知回调sendMsgCallback,且必须订阅com.ohos.notification_service.sendReply
88          this.callee.on('com.ohos.notification_service.sendReply', sendMsgCallback)
89        } catch (error) {
90          console.error(`Failed to register. Code is ${error.code}, message is ${error.message}`);
91        }
92        console.info('register successfully');
93      }
94    }
95    ```
96
973. 发布可快捷回复的通知消息。该通知必须携带有`userInput`的`actionButtons`,且`notificationSlotType`必须为`SOCIAL_COMMUNICATION`。
98
99    ```typescript
100    // 用于保存创建成功的wantAgent对象,后续使用其完成触发的动作。
101    let wantAgentObj:WantAgent;
102    // 该wantAgentInfo的abilityName必须为步骤二的EntryAbility。
103    let wantAgentInfo:wantAgent.WantAgentInfo = {
104      wants: [
105        {
106          deviceId: '',
107          bundleName: 'com.samples.notification', // 使用时修改为发送通知的应用包名
108          abilityName: 'EntryAbility',
109          action: '',
110          entities: [],
111          uri: '',
112          parameters: {}
113        }
114      ],
115      actionType: wantAgent.OperationType.START_ABILITY,
116      requestCode: 0,
117      actionFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]
118    };
119    // 创建WantAgent
120    wantAgent.getWantAgent(wantAgentInfo, (err: BusinessError, data:WantAgent) => {
121      if (err) {
122         console.error(`Failed to get want agent. Code is ${err.code}, message is ${err.message}`);
123         return;
124      }
125      console.info('Succeeded in getting want agent.');
126      wantAgentObj = data;
127      let notificationRequest: notificationManager.NotificationRequest = {
128        id: 1,
129        // notificationSlotType必须为SOCIAL_COMMUNICATION
130        notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION,
131        content: {
132          notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
133          normal: {
134            title: 'Test_Title',
135            text: 'Test_Text',
136            additionalText: 'Test_AdditionalText',
137          },
138        },
139        actionButtons: [{
140          title: 'button1',
141          wantAgent: wantAgentObj,
142          // 必须携带userInput
143          userInput: {'inputKey': 'value1'},
144        }],
145      }
146      // 发布通知
147      notificationManager.publish(notificationRequest, (err: BusinessError) => {
148        if (err) {
149          console.error(`Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
150          return;
151        }
152        console.info('Succeeded in publishing notification.');
153      });
154    });
155   ```
156
157## 调试验证
158
1591. 手表上进行快捷回复。
160
1612. 在手机侧通过过滤日志"inputKey"或"userInput"等方式查看是否有消息通知回调sendMsgCallback。如果有,表明功能实现正常。
162