• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Enabling Quick Reply for Cross-Device Notifications
2
3<!--Kit: Notification Kit-->
4<!--Subsystem: Notification-->
5<!--Owner: @peixu-->
6<!--Designer: @dongqingran; @wulong158-->
7<!--Tester: @wanghong1997-->
8<!--Adviser: @huipeizi-->
9
10Since API version 18, quick reply is enabled for cross-device notifications.
11
12When an application on the phone subscribes to a notification reply event by specifying an event ID and publishes a notification that supports quick reply to the watch, the user can view the notification and quickly reply to it on the watch without unlocking the mobile phone.
13
14## Prerequisites
15
16 - The user has connected the watch to the phone through the Huawei Health app.
17 - The user has turned on the switch for syncing notifications from phone to watch for specified applications in **Huawei Health** > **Devices** > **Notifications** on their phones.
18
19## Implementation Principles
20
21The figure below shows the procedure for quick reply. You only need to implement step 1 and step 2. Step 6 is a user operation. Other operations are implemented by the system.
22
23![notification_introduction](figures/notification_quickreply.png)
24
25## APIs
26
27| **API** | **Description**|
28| -------- | -------- |
29| [publish](../reference/apis-notification-kit/js-apis-notificationManager.md#notificationmanagerpublish-1)(request: NotificationRequest): Promise\<void\>       | Publishes a notification. |
30| [on](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#on)(method: string, callback: CalleeCallback): void       | Registers a caller notification callback, which is invoked when the target ability registers a function. |
31
32## How to Develop
33
341. Import the related modules.
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. Enable the application to subscribe to the notification reply event.
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      // Receive the serialized data sent by the client.
71      let receivedData = new MySequenceable('', '')
72      // receivedData.inputKey is value1.
73      receivedData.inputKey = data.readString();
74      // The value of receivedData.userInput is the quick reply content specified by the user.
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          // Register sendMsgCallback on the server and subscribe to 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. Publish a notification that can be quickly replied to. This notification must contain `actionButtons` of `userInput`, and `notificationSlotType` must be set to `SOCIAL_COMMUNICATION`.
98
99    ```typescript
100    // Save the WantAgent object created. It will be used to complete the trigger operations.
101    let wantAgentObj:WantAgent;
102    // The abilityName of the wantAgentInfo must be EntryAbility.
103    let wantAgentInfo:wantAgent.WantAgentInfo = {
104      wants: [
105        {
106          deviceId: '',
107          bundleName: 'com.samples.notification', // Use the actual bundle name that sends notifications.
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    // Create a WantAgent object.
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 must be set to 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 must be carried.
143          userInput: {'inputKey': 'value1'},
144        }],
145      }
146      // Publish the notification.
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## Debugging and Verification
158
1591. Make a quick reply on the watch.
160
1612. On the phone, filter logs by **inputKey** or **userInput** to check whether the message notification callback **sendMsgCallback** exists. If the callback is found, the function is implemented properly.
162