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