应用间消息通信
约束与限制
- 使用该功能前,请确保对端设备侧已有对应的应用。
- 对端设备侧应用和穿戴设备应用必须同时处于已启动状态。
穿戴侧应用检测对端设备侧应用是否安装
-
参见已连接对端设备查询章节,从已连接设备列表中选定需要通信的对端设备。
-
调用getP2pClient方法,获取P2pClient对象。
-
调用isRemoteAppInstalled方法,查看对端设备是否安装指定应用。
// 将对端应用包名定义为remoteBundleNamelet remoteBundleName: string = '';// 步骤2 获取P2pClient对象let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(this.getUIContext().getHostContext());// 步骤3 查看是否安装指定的对端应用p2pClient.isRemoteAppInstalled(targetDevice.randomId, remoteBundleName).then((isInstall) => {console.info(`Succeeded in checking remote app install, result is ${isInstall}.`);}).catch((error: BusinessError) => {console.error(`Failed to check remote app install. Code is ${error.code}, message is ${error.message}.`);})
穿戴侧应用发送点对点消息或文件到对端应用
消息长度大小的限制为4096字节。针对消息长度超过限制的情况可以采用发送文件(文件大小不超过100MB)的方式或进行消息分包控制。
穿戴侧实现发送消息和文件功能后,对端应用需要实现接收消息和文件的功能。
发送点对点消息
-
为了使用工具类构造消息体,请先导入所需模块。
import { util } from '@kit.ArkTS'; -
参见已连接对端设备查询章节,从已连接设备列表中选定需要通信的对端设备。
-
构造对端应用参数P2pAppParam。
-
构造需要发送的消息P2pMessage。
-
调用getP2pClient方法,获取P2pClient对象。
-
调用sendMessage方法,从穿戴侧应用发送简短消息到对端应用。对端应用已注册监听消息接收后,即可收到穿戴侧应用发送的消息。
// 步骤2 构造对端应用参数let appInfo: wearEngine.AppInfo = {// 设置对端应用的应用信息:包名与指纹bundleName: '',fingerprint: ''}let appParam: wearEngine.P2pAppParam = {remoteApp: appInfo}// 设置需要发送的消息内容,长度限制为4096字节let messageContent: string = 'this is message';// 步骤3 构造消息结构体let textEncoder: util.TextEncoder = new util.TextEncoder;let message: wearEngine.P2pMessage = {content: textEncoder.encodeInto(messageContent)}// 步骤4 获取P2pClient对象let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(this.getUIContext().getHostContext());// 步骤5 发送消息p2pClient.sendMessage(targetDevice.randomId, appParam, message).then((p2pResult) => {console.info(`Succeeded in sending message, result is ${p2pResult.code}.`);}).catch((error: BusinessError) => {console.error(`Failed to send message. Code is ${error.code}, message is ${error.message}.`);})
发送文件
-
发送文件前需要打开文件描述符,请先导入模块。
import { fileIo } from '@kit.CoreFileKit'; -
参见已连接对端设备查询章节,从已连接设备列表中选定需要通信的对端设备。
-
构造对端应用参数P2pAppParam。
-
根据文件路径filePath,构造需要发送的文件P2pFile。
-
调用getP2pClient方法,获取P2pClient对象。
-
调用transferFile方法,从穿戴侧应用发送文件到对端应用。
// 步骤2 构造对端应用参数let appInfo: wearEngine.AppInfo = {// 设置对端应用的应用信息:包名与指纹bundleName: '',fingerprint: ''}let appParam: wearEngine.P2pAppParam = {remoteApp: appInfo}// 步骤3 构造需要发送的文件let p2pfile: wearEngine.P2pFile = {// 设置需要发送的文件路径,其中不能包含'..'file: fileIo.openSync('')}// 步骤4 获取P2pClient对象let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(this.getUIContext().getHostContext());// 步骤5 发送指定文件至对端p2pClient.transferFile(targetDevice.randomId, appParam, p2pfile, (error: BusinessError, p2pResult: wearEngine.P2pResult) => {// callback处理逻辑if (error) {console.error(`Failed to transfer file. Code is ${error.code}, message is ${error.message}.`);return;}if (p2pResult.code) {if (p2pResult.code === wearEngine.P2pResultCode.COMMUNICATION_SUCCESS) {console.info(`Succeeded in transferring file, the result is ${p2pResult.code}.`);} else {console.info(`Failed to transfer file, the error code is ${p2pResult.code}.`);return;}}if (p2pResult.progress) {console.info(`Succeeded in transfering file, the progress is ${p2pResult.progress}.`);}});fileIo.close(p2pfile.file);
订阅接收对端应用发来的消息
-
参见已连接对端设备查询章节,从已连接设备列表中选定需要通信的对端设备。
-
调用getP2pClient方法,获取P2pClient对象。
-
构造对端应用参数P2pAppParam。
-
构造接收到对端传来消息后的回调函数Callback。
-
调用registerMessageReceiver方法,订阅监听消息接收事件。
// 步骤2 获取P2pClient对象let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(this.getUIContext().getHostContext());// 步骤3 构造对端应用参数let appInfo: wearEngine.AppInfo = {bundleName: '',fingerprint: ''}// 将对端应用参数类定义为appParamlet appParam: wearEngine.P2pAppParam = {remoteApp: appInfo}// 步骤4 构造回调函数let callback = (p2pMessage: wearEngine.P2pMessage) => {console.info(`Succeeded in receiving message, the message is ${p2pMessage.content}.`);}// 步骤5 订阅监听消息接收事件p2pClient.registerMessageReceiver(targetDevice.randomId, appParam, callback).then(() => {console.info(`Succeeded in registering message receiver.`);}).catch((error: BusinessError) => {console.error(`Failed to register message receiver. Code is ${error.code}, message is ${error.message}.`);}) -
调用unregisterMessageReceiver方法,穿戴侧应用取消接收对端应用发过来的消息,需要传入订阅监听时的同一个回调函数对象。
p2pClient.unregisterMessageReceiver(targetDevice.randomId, appParam, callback).then(() => {console.info(`Succeeded in unregistering message receiver.`);}).catch((error: BusinessError) => {console.error(`Failed to unregister message receiver. Code is ${error.code}, message is ${error.message}.`);})
订阅接收对端应用发送来的文件
-
参见已连接对端设备查询章节,从已连接设备列表中选定需要通信的对端设备。
-
调用getP2pClient方法,获取P2pClient对象。
-
构造设备侧应用参数P2pAppParam。
-
构造接收到设备侧传来文件后的回调函数Callback。
-
调用registerFileReceiver方法,订阅监听文件接收事件。
// 步骤2 获取P2pClient对象let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(this.getUIContext().getHostContext());// 步骤3 构造对端应用参数let appInfo: wearEngine.AppInfo = {bundleName: '',fingerprint: ''}// 将对端应用参数类定义为appParamlet appParam: wearEngine.P2pAppParam = {remoteApp: appInfo}// 步骤4 构造回调函数let callback = (p2pMessage: wearEngine.P2pFile) => {console.info(`Succeeded in receiving file.`);}// 步骤5 订阅监听文件接收事件p2pClient.registerFileReceiver(targetDevice.randomId, appParam, callback).then(() => {console.info(`Succeeded in registering file receiver.`);}).catch((error: BusinessError) => {console.error(`Failed to register file receiver. Code is ${error.code}, message is ${error.message}.`);}) -
调用unregisterFileReceiver方法,穿戴侧应用取消接收对端应用发过来的文件,需要传入订阅监听时的同一个回调函数对象。
p2pClient.unregisterFileReceiver(targetDevice.randomId, appParam, callback).then(() => {console.info(`Succeeded in unregistering file receiver.`);}).catch((error: BusinessError) => {console.error(`Failed to unregister file receiver. Code is ${error.code}, message is ${error.message}.`);})
对端应用通过startRemoteApp方法拉起穿戴侧应用
如果对端应用通过调用startRemoteApp方法拉起穿戴侧应用时,需要在穿戴侧配置需要拉起的页面。
-
创建名为HiWearMainAbility.ets的文件,需继承UIAbility,重写onWindowStageCreate函数,配置要跳转的界面。
// 必须继承UIAbilityimport hilog from '@ohos.hilog';import UIAbility from '@ohos.app.ability.UIAbility';import window from '@ohos.window';/*** 对端应用通过startRemoteApp方法拉起穿戴侧应用的HiWearMainAbility*/export default class HiWearMainAbility extends UIAbility {onWindowStageCreate(windowStage: window.WindowStage): void {hilog.info(0x0000, 'HiWearMainAbility', '%{public}s', 'Ability onWindowStageCreate');// 配置要跳转的界面为”XXXPage”windowStage.loadContent("pages/XXXPage", (err, data) => {if (err.code) {hilog.error(0x0000, 'HiWearMainAbility', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');return;}hilog.info(0x0000, 'HiWearMainAbility', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');});}} -
在module.json5中的abilities中配置HiWearMainAbility。更多配置详情参考abilities标签。
-
配置name为HiWearMainAbility。
-
配置srcEntry为HiWearMainAbility.ets文件的路径。
-
配置startWindowIcon为标识当前UIAbility组件启动页面图标资源文件的索引。
-
配置startWindowBackground为标识当前UIAbility组件启动页面背景颜色资源文件的索引。
"module": {"name": "xxxx","type": "entry","description": "xxxx","mainElement": "xxxx","deviceTypes": [],"pages": "xxxx","abilities": [{"name": "HiWearMainAbility","srcEntry": "xxxx","startWindowIcon": "xxxx", // 标识当前UIAbility组件启动页面图标资源文件的索引"startWindowBackground": "xxxx" // 标识当前UIAbility组件启动页面背景颜色资源文件的索引}],"metadata": []}
-
-
在module.json5中的metadata中配置对端应用包名、待拉起的Ability名称,以及是否要等待穿戴侧完成订阅消息接收或者文件接收。
-
对端应用包名配置时,name为wearEngineRemoteAppNameList,value为具体的对端应用包名,如果存在多个应用包名,使用英文逗号隔开,value值最长不超过4KB;
-
Ability名称配置时,name为wearEngineUIAbilityName,value为指定要拉起的UIAbility名称,不配置默认拉起HiWearMainAbility;
-
AwaitRegisterReceiver配置时,name为wearEngineAwaitRegisterReceiver,value取值为true、false。true表示要等待穿戴侧完成订阅消息接收或者文件接收,false则反之。
"module": {"name": "xxxx","type": "entry","description": "xxxx","mainElement": "xxxx","deviceTypes": [],"pages": "xxxx","abilities": [],"metadata": [ // 配置如下信息{"name": "wearEngineRemoteAppNameList","value": "xxxx1,xxxx2,xxxx3"},{"name": "wearEngineUIAbilityName","value": "xxxx"},{"name": "wearEngineAwaitRegisterReceiver","value": "true"}]}
-