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