鸿蒙开发(NEXT/API 12)【应用间消息通信】手机侧应用开发

在手机侧与穿戴设备侧构建应用到应用的通信隧道,用于收发应用自定义的报文消息以及文件。实现手机应用和穿戴设备应用间的交互,为用户提供分布式场景和体验。比如手机应用发送音频文件到穿戴设备侧应用,实现在穿戴设备侧应用上播放音乐;手机应用发送暂停指令,实现穿戴设备音乐播放暂停等。

收发点对点消息前,需要确保应用已在开发者联盟申请获取设备基础信息权限权限,否则接口将调用失败。

说明

使用该功能前,请确保穿戴设备支持应用安装能力,同时穿戴设备侧已有对应的应用。

  • 手机App和穿戴设备App必须同时处于启动状态。
  • 当手机App启动且穿戴设备App没有启动时,手机App可以通过[startRemoteApp]方法拉起穿戴设备App。

手机侧应用检测穿戴设备侧应用是否安装

注意

该接口的调用需要在开发者联盟申请设备基础信息权限。

  1. 参见[查询可用穿戴设备]章节,获取已连接设备列表。
  2. 参见[目标设备选择]章节,从已连接设备列表中选定需要通信的设备。
  1. 调用[wearEngine]中的[getP2pClient]方法,获取[P2pClient]对象。

  2. 调用[isRemoteAppInstalled]方法,查看是否安装指定的设备应用。

// 将设备侧应用包名定义为remoteBundleName
let remoteBundleName: string = '';// 步骤3 获取P2pClient对象
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));// 步骤4 查看是否安装指定的设备侧应用
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}.`);
})

手机侧应用获取穿戴设备侧应用的版本号

注意

该接口的调用需要在开发者联盟申请设备基础信息权限。

  1. 参见[查询可用穿戴设备]章节,获取已连接设备列表。
  2. 参见[目标设备选择]章节,从已连接设备列表中选定需要通信的设备。
  1. 调用[wearEngine]中的[getP2pClient]方法,获取[P2pClient]对象。

  2. 调用[getRemoteAppVersion]方法,获取指定设备对应的应用版本号。

// 将设备侧应用包名定义为remoteBundleName
let remoteBundleName: string = '';// 步骤3 获取P2pClient对象
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));// 步骤4 获取指定设备对应的应用版本号
p2pClient.getRemoteAppVersion(targetDevice.randomId, remoteBundleName).then((version) => {console.info(`Succeeded in getting remote app version, version is ${version}.`);
}).catch((error: BusinessError) => {console.error(`Failed to check get remote app version. Code is ${error.code}, message is ${error.message}.`);
})

手机侧应用拉起设备侧应用

注意

该接口的调用需要在开发者联盟申请设备基础信息权限。

在发送点对点消息前,可以用[startRemoteApp]方法拉起设备侧应用。

  1. 参见[查询可用穿戴设备]章节,获取已连接设备列表。

  2. 参见[目标设备选择]章节,从已连接设备列表中选定需要通信的设备。

  3. 调用[wearEngine]中的[getP2pClient]方法,获取[P2pClient]对象。

  4. 调用[startRemoteApp]方法,指定需要拉起设备侧应用包名。[transformLocalBundleName]默认值为false,传入为true时,wearEnigne会将本地的应用包名和指纹转换为兼容应用在云侧存储的包名和指纹。

// 将设备侧应用包名定义为remoteBundleName
let remoteBundleName: string = '';// 步骤3 获取P2pClient对象
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));// 步骤4 拉起设备侧指定应用(transformLocalBundleName不传入参数,默认为false)
p2pClient.startRemoteApp(targetDevice.randomId, remoteBundleName).then((p2pResult) => {console.info(`Succeeded in starting remote app, result is ${p2pResult.code}.`);
}).catch((error: BusinessError) => {console.error(`Failed to start remote app. Code is ${error.code}, message is ${error.message}.`);
})

手机侧应用发送点对点消息或文件到穿戴设备侧应用

注意

该接口的调用需要在开发者联盟申请设备基础信息权限。

消息长度大小的限制为4096字节。针对消息长度超过限制的情况可以采用发送文件(文件大小不超过100MB)的方式或进行消息分包控制。

手机侧实现发送消息和文件功能后,穿戴设备侧应用需要对应实现接收消息和文件的功能。

发送点对点消息

为了使用工具类构造消息体,请先导入所需模块。

import { util } from '@kit.ArkTS';
  1. 参见[查询可用穿戴设备]章节,获取已连接设备列表。
  2. 参见[目标设备选择]章节,从已连接设备列表中选定需要通信的设备。
  3. 构造设备侧应用参数[P2pAppParam]。
  4. 构造需要发送的消息[P2pMessage]。
  1. 调用[wearEngine]中的[getP2pClient]方法,获取[P2pClient]对象。

  2. 调用[sendMessage]方法,从手机上的应用发送简短消息到穿戴设备侧对应的应用。设备侧已注册监听消息接收后,即可收到手机发送的消息。

// 步骤3 构造设备侧应用参数
let appInfo: wearEngine.AppInfo = {// 设置设备侧应用的应用信息:包名与指纹bundleName: '',fingerprint: ''
}
let appParam: wearEngine.P2pAppParam = {remoteApp: appInfo// transformLocalAppInfo默认为false,不转换包名指纹
}// 设置需要发送的消息内容,长度限制为4096字节
let messageContent: string = 'this is message';// 步骤4 构造消息结构体
let textEncoder: util.TextEncoder = new util.TextEncoder;
let message: wearEngine.P2pMessage = {content: textEncoder.encodeInto(messageContent)
}// 步骤5 获取P2pClient对象
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));// 步骤6 发送消息
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';
  1. 参见[查询可用穿戴设备]章节,获取已连接设备列表。
  2. 参见[目标设备选择]章节,从已连接设备列表中选定需要通信的设备。
  3. 构造设备侧应用参数[P2pAppParam]。
  1. 根据文件路径filePath,构造需要发送的文件[P2pFile]。

  2. 调用[wearEngine]中的[getP2pClient]方法,获取[P2pClient]对象。

  3. 调用[transferFile]方法,从手机上的应用发送文件到穿戴设备侧对应的应用。

// 步骤3 构造设备侧应用参数
let appInfo: wearEngine.AppInfo = {// 设置设备侧应用的应用信息:包名与指纹bundleName: '',fingerprint: ''
}
let appParam: wearEngine.P2pAppParam = {remoteApp: appInfo// transformLocalAppInfo默认为false,不转换包名指纹
}// 步骤4 构造需要发送的文件
let p2pfile: wearEngine.P2pFile = {// 设置需要发送的文件路径,其中不能包含'..'file: fileIo.openSync('')
}// 步骤5 获取P2pClient对象
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));// 步骤6 发送指定文件至设备
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 transfering file, the result is ${p2pResult.code}.`);}console.info(`Failed to transfer file, the error code is ${p2pResult.code}.`);}if (p2pResult.progress) {console.info(`Succeeded in transfering file, the progress is ${p2pResult.progress}.`);}
});fileIo.close(p2pfile.file);

取消发送文件

  1. 参见[查询可用穿戴设备]章节,获取已连接设备列表。
  2. 参见[目标设备选择]章节,从已连接设备列表中选定需要通信的设备。
  3. 构造设备侧应用参数[P2pAppParam]。
  1. 根据文件路径filePath,构造需要取消发送的文件[P2pFile])。

  2. 调用[wearEngine]中的[getP2pClient]方法,获取[P2pClient]对象。

  3. 调用[cancelFileTransfer]方法,取消从手机上的应用到穿戴设备侧对应的应用的文件发送。

// 步骤3 构造设备侧应用参数
let appInfo: wearEngine.AppInfo = {// 设置设备侧应用的应用信息:包名与指纹bundleName: '',fingerprint: ''
}
let appParam: wearEngine.P2pAppParam = {remoteApp: appInfo// transformLocalAppInfo默认为false,不转换包名指纹
}// 步骤4 构造需要发送的文件
let p2pfile: wearEngine.P2pFile = {// 设置需要发送的文件路径,其中不能包含'..'file: fileIo.openSync('')
}// 步骤5 获取P2pClient对象
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));// 发送指定文件至设备
p2pClient.transferFile(targetDevice.randomId, appParam, p2pfile, () => {// 回调函数执行逻辑
})// 步骤6 取消发送文件
p2pClient.cancelFileTransfer(targetDevice.randomId, appParam, p2pfile).then((p2pResult) => {if (p2pResult.code === wearEngine.P2pResultCode.COMMUNICATION_SUCCESS) {console.info(`Succeeded in cancelling transfer file, the result is ${p2pResult.code}.`);}
}).catch((error: BusinessError) => {console.error(`Failed to cancel transfer file. Code is ${error.code}, message is ${error.message}.`);
})fileIo.close(p2pfile.file);

订阅接收穿戴设备侧应用发过来的消息

注意

该接口的调用需要在开发者联盟申请设备基础信息权限。

  1. 参见[查询可用穿戴设备]章节,获取已连接设备列表。

  2. 参见[目标设备选择]章节,从已连接设备列表中选定需要通信的设备。

  3. 调用[wearEngine]中的[getP2pClient]方法,获取[P2pClient]对象。

  4. 构造设备侧应用参数[P2pAppParam]。

  5. 构造接收到设备侧传来消息后的回调函数[callback]。

  6. 调用[registerMessageReceiver]方法,订阅监听消息接收事件。

// 步骤3 获取P2pClient对象
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));// 步骤4 构造设备侧应用参数
let appInfo: wearEngine.AppInfo = {bundleName: '',fingerprint: ''
}
// 将设备侧应用参数类定义为appParam
let appParam: wearEngine.P2pAppParam = {remoteApp: appInfo// transformLocalAppInfo默认为false,不转换包名指纹
}// 步骤5 构造回调函数
let callback = (p2pMessage: wearEngine.P2pMessage) => {console.info(`Succeeded in receiving message, the message is ${p2pMessage.content}.`);
}// 步骤6 订阅监听消息接收事件
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}.`);
})
  1. 调用[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}.`);
})

订阅接收穿戴设备侧发送过来的文件

  1. 参见[查询可用穿戴设备]章节,获取已连接设备列表。

  2. 参见[目标设备选择]章节,从已连接设备列表中选定需要通信的设备。

  3. 调用[wearEngine]中的[getP2pClient]方法,获取[P2pClient]对象。

  4. 构造设备侧应用参数[P2pAppParam]。

  5. 构造接收到设备侧传来文件后的回调函数[callback]

  6. 调用[registerFileReceiver] 方法,订阅监听文件接收事件。

// 步骤3 获取P2pClient对象
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(getContext(this));// 步骤4 构造设备侧应用参数
let appInfo: wearEngine.AppInfo = {bundleName: '',fingerprint: ''
}
// 将设备侧应用参数类定义为appParam
let appParam: wearEngine.P2pAppParam = {remoteApp: appInfo// transformLocalAppInfo默认为false,不转换包名指纹
}// 步骤5 构造回调函数
let callback = (p2pMessage: wearEngine.P2pFile) => {console.info(`Succeeded in receiving file.`);
}// 步骤6 订阅监听文件接收事件
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}.`);
})
  1. 调用[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}.`);
})

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿
1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/880700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php函数安全漏洞的挖掘与修复技巧

PHP 函数安全漏洞的挖掘与修复技巧 简介 PHP 函数中经常存在安全漏洞,例如 SQL 注入和跨站脚本攻击 (XSS)。了解如何挖掘和修复这些漏洞对于确保 Web 应用程序的安全性至关重要。 漏洞挖掘 以下是挖掘 PHP 函数安全漏洞的一些技巧: 参数检查&#xf…

BUG——IMX6ULL编译正点原子Linux内核报错

最初编译的是正点原子改过的Linux内核,可能是版本问题,一直报错,无法成功编译。然后换成NXP官方Linux内核6.6版本,初始编译虽然也报各种错,但都是缺少库或相关工具,全部安装后就可以成功编译出镜像了&#…

Leetcode 740. 删除并获得点数

原题链接:. - 力扣(LeetCode) 给你一个整数数组 nums ,你可以对它进行一些操作。 每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和…

cscode搭建vue项目

创建前安装环境 ctrlj弹出终端 window需要管理员运行并且授权 node -v # 显示版本号,说明 node 已经装好 npm -v # 显示版本号,说明 npm 可以使用 # 安装cnpm npm install -g cnpm --registryhttps://registry.npm.taobao.org cnpm -v # 显示版本号&a…

Spring中如何为静态变量注入值

在 Spring 中,如果使用 Value 注解注入值,不能将其应用于 static 字段。Spring 只能为实例变量注入值,不能直接对静态变量进行注入。 使用 PostConstruct 初始化: 如果确实需要在静态上下文中使用该值,可以使用 Post…

机器学习(1)——线性回归、线性分类与梯度下降

文章目录 线性回归线性分类线性可分数据线性不可分数据逻辑回归支持向量机 梯度下降批量梯度下降随机梯度下降批量随机梯度下降 线性回归 概述: 在一元线性回归中,我们假设目标变量y与特征变量x存在线性关系,模型表达式为: y …

【hot100-java】【合并两个有序链表】

记忆中,两个指针合并即可。 建立哨兵节点dum /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { t…

Docker更换阿里容器镜像源

以Mac为例, 一、获取阿里容器镜像加速器地址 访问阿里云官网https://cn.aliyun.com/ 登录阿里云,没有账号就注册一个 登录完成后在搜索框搜索,容器镜像服务,并打开 点击管理控制台,进入管理控制台 左侧点击镜像加速…

【Python入门】20个Python自动化脚本,解放双手、事半功倍

如果你正在学习Python,那么你需要的话可以,点击这里👉Python重磅福利:入门&进阶全套学习资料、电子书、软件包、项目源码等等免费分享! 在当今的快节奏工作环境中,自动化不再是一种奢侈,而是…

下一代性能怪兽RTX 5090最新规格更新与Blackwell架构解析

据悉,目前各家AIC厂商已经陆续收到NVIDIA的相关资料,RTX 5090、RTX 5080已经正式进入开案阶段,也就是厂商们开始设计各自的产品方案了。不出意外,年初的CES 2025上会看到RTX 5090/5080的发布。 作为NVIDIA的新一代GPU&#xff0c…

【车联网安全】车端知识调研

一、CAN总线: 1、定义: CAN 总线相当于汽车的神经网络,连接车内各控制系统,其通信采用广播机制,各连接部件均可收发控制消息,通信效率高,可确保通信实时性。当前市场上的汽车至少拥有一个CAN网络&#xff0…

Leetcode 3302. Find the Lexicographically Smallest Valid Sequence

Leetcode 3302. Find the Lexicographically Smallest Valid Sequence 1. 解题思路2. 代码实现 题目链接:3302. Find the Lexicographically Smallest Valid Sequence 1. 解题思路 这一题的话由于至多只能够修改一个字符,因此,我们就是要考…

如何进行“服务器内部错误”的诊断 | OceanBase诊断案例

本文作者:任仲禹,爱可生数据库高级工程师,擅长故障分析和性能优化。 的OMS迁移工具具备丰富的功能。但在实际运维场景中,我们可能会遇到各种问题,其中“服务器内部错误”便是一个较为棘手的问题,因为界面上…

PHP 递归遍历目录

本篇文章主要内容为PHP 两种循环递归遍历目录的示例。 目录 while循环 foreach循环 调用及结果 总结 while循环 应用while循环和opendir、readdir函数处理读取路径下所有文件和目录。 具体代码如下: function getDir($path, $space ) {$dir opendir($path)…

【易上手快捷开发新框架技术】nicegui标签组件lable用法庖丁解牛深度解读和示例源代码IDE运行和调试通过截图为证

传奇开心果微博文系列 序言一、标签组件lable最基本用法示例1.在网页上显示出 Hello World 的标签示例2. 使用 style 参数改变标签样式示例 二、标签组件lable更多用法示例1. 添加按钮动态修改标签文字2. 点击按钮动态改变标签内容、颜色、大小和粗细示例代码3. 添加开关组件动…

PHP“===”的意义

在PHP中, 运算符被称为“恒等比较运算符”(Identical Comparison Operator),它用于比较两个变量的值和类型是否完全相同。这个运算符与双等号 (等值比较运算符)不同,后者在比较时会对两边的值进…

美图AI短片创作工具MOKI全面开放 支持生成配乐、细节修改

人工智能 - Ai工具集 - 集合全球ai人工智能软件的工具箱网站 美图公司近日宣布,其研发的AI短片创作工具MOKI已正式向所有用户开放。这款专注于AI短片创作的工具,提供了包括动画短片、网文短剧等多种类型视频内容的生成能力,致力于为用户带来…

uni-app之旅-day02-分类页面

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言创建cate分支4.1 渲染分类页面的基本结构4.2 获取分类数据4.3 动态渲染左侧的一级分类列表4.4 动态渲染右侧的二级分类列表4.5 动态渲染右侧的三级分类列表4.6 …

linux上,进程管理

命令 ps aux 是一个在 Unix 和类 Unix 系统中非常常用的命令,用于显示当前系统中的运行中的进程信息。这个命令可以提供关于各个进程的详细信息,包括进程ID、CPU 和内存使用率、进程状态、启动时间等。让我们来详细解释一下 ps aux 命令的各个部分&#…

linux-CMake

linux-CMake 1.安装CMake工具2.单个源文件3.多个源文件4.生成库文件5.将源文件组织到不同的目录下6.可执行文件和库文件放置到单独的目录下7.常见的命令 CMake使用。 1.安装CMake工具 sudo apt-get install cmake2.单个源文件 1.先在文件夹里创建两个文件:main.c&…