鸿蒙系统开发【应用接续】基本功能

应用接续

介绍

基于ArkTS扩展的声明式开发范式编程语言编写的一个分布式视频播放器,主要包括一个直播视频播放界面,实现视频播放时可以从一台设备迁移到另一台设备继续运行,来选择更合适的设备继续执行播放功能以及PAD视频播放时协同调用手机编辑发送弹幕功能。

效果预览

1

使用说明

  1. 准备手机端与平板端两台设备,并且登录同一华为账号,双端设备打开WI-FI和蓝牙,建议双端设备接入同一个局域网,可提升数据传输的速度
  2. 双端设备均安装此应用
  3. 滑动浏览手机端视频,打开平板端应用
  4. 点击平板端手机输入按钮,调起手机端输入内容,提交后平板端查看

具体实现

  1. 在实现协同接口前,应用需要申请协同所需的访问控制权ohos.permission.DISTRIBUTED_DATASYNC。 在requestPermissions字段中增加权限声明ohos.permission.DISTRIBUTED_DATASYNC
  2. 同时需要在应用首次启动时弹窗向用户申请授权,在用户手动允许授权后,应用才会真正获取相应权限,从而成功访问操作目标对象。 在EntryAbility类中实现以下函数,从而在调用时动态弹窗向用户申请权限。
/** Copyright (c) 2024 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import { abilityAccessCtrl, AbilityConstant, bundleManager, Permissions, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { WindowUtil } from '../utils/WindowUtil';
import Logger from '../utils/Logger';export default class EntryAbility extends UIAbility {contentStorage?: LocalStorage;onContinue(wantParam: Record<string, Object>) {Logger.info(wantParam.version.toString(), wantParam.targetDevice.toString());// Preparing to Migrate Datalet activeLive: number = AppStorage.get<number>('activeLive') as number;// Save the data to be migrated in the 'data' field of wantParam.wantParam['activeLive'] = activeLive;// Setting the Source End Not to ExitwantParam["ohos.extra.param.key.supportContinueSourceExit"] = false;Logger.info(activeLive.toString());return AbilityConstant.OnContinueResult.AGREE}onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {Logger.info('Ability onCreate');this.checkPermissions();// If the invoking reason is migration, set the status to migratable to cope with cold start (ensuring migration continuity)if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {Logger.info(JSON.stringify(result));});}// Cold start of the application: Restore the saved migration dataif (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {// Restore migrated data from wantlet activeLive = want?.parameters?.activeLive;AppStorage.setOrCreate<number>('activeLive', activeLive as number);Logger.info(activeLive as string);// Explicit invocation of page restorethis.contentStorage = new LocalStorage();Logger.info('Ability onCreate restoreWindowStage');this.context.restoreWindowStage(this.contentStorage);}}onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) {Logger.info('Ability onCreate');// If the invoking reason is migration, set the status to migratable to cope with hot start (ensuring migration continuity)if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {Logger.info(JSON.stringify(result));});}//During the warm start of an application: Restore the saved migration dataif (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {// Restore migrated data from wantlet activeLive = want?.parameters?.activeLive;AppStorage.setOrCreate<number>('activeLive', activeLive as number);Logger.info(activeLive as string);// Explicit invocation of page restorethis.contentStorage = new LocalStorage();Logger.info('Ability onNewWant restoreWindowStage');this.context.restoreWindowStage(this.contentStorage);}}// Check permission granting and dynamically apply for permissionsasync checkPermissions(): Promise<void> {const permissions: Array<Permissions> = ['ohos.permission.DISTRIBUTED_DATASYNC'];let grantStatus: abilityAccessCtrl.GrantStatus = await this.checkAccessToken(permissions[0]);// Verifying Permission Grantingif (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {// GrantedLogger.info('Permission already granted.');} else {// Not granted. Dynamically apply for authorization in the dialog box displayed to the userlet atManager = abilityAccessCtrl.createAtManager();try {atManager.requestPermissionsFromUser(this.context, ['ohos.permission.DISTRIBUTED_DATASYNC'], (err, data) => {Logger.info(JSON.stringify(data));});} catch (err) {Logger.error(JSON.stringify(err));return;}}}// Get the grant status of the current app's permissionsasync checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {let atManager = abilityAccessCtrl.createAtManager();let grantStatus: abilityAccessCtrl.GrantStatus = -1;// Obtains the token IDlet tokenId: number = 0;try {let bundleInfo: bundleManager.BundleInfo =await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;tokenId = appInfo.accessTokenId;} catch (err) {Logger.error(JSON.stringify(err));}try {grantStatus = await atManager.checkAccessToken(tokenId, permission);} catch (err) {Logger.error(JSON.stringify(err));}return grantStatus;}onDestroy(): void {Logger.info('Ability onDestroy');}onWindowStageCreate(windowStage: window.WindowStage): void {// Main window is created, set main page for this abilityLogger.info('Ability onWindowStageCreate');WindowUtil.requestFullScreen(windowStage, this.context);WindowUtil.updateStatusBarColor(this.context, true);windowStage.loadContent('pages/LivePage', (err) => {if (err.code) {Logger.error(JSON.stringify(err) ?? '');return;}Logger.info('Succeeded in loading the content.');});}onWindowStageDestroy(): void {// Main window is destroyed, release UI related resourcesLogger.info('Ability onWindowStageDestroy');}onWindowStageRestore(windowStage: window.WindowStage): void {WindowUtil.requestFullScreen(windowStage, this.context);}onForeground(): void {// Ability has brought to foregroundLogger.info('Ability onForeground');}onBackground(): void {// Ability has back to backgroundLogger.info('Ability onBackground');}
}
  1. 获取目标设备的设备ID。
  2. 在发起端设置目标组件参数,调用startAbilityForResult()接口启动目标端UIAbility,异步回调中的data用于接收目标端UIAbility停止自身后返回给调用方UIAbility的信息。
  3. 在目标端UIAbility任务完成后,调用terminateSelfWithResult()方法,将数据返回给发起端的UIAbility。
  4. 发起端UIAbility接收到目标端UIAbility返回的信息,对其进行处理。

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

在这里插入图片描述

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!

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

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

相关文章

《LeetCode热题100》---<5.②普通数组篇五道>

本篇博客讲解LeetCode热题100道普通数组篇中的六道题 第三道&#xff1a;轮转数组&#xff08;中等&#xff09; 第四道&#xff1a;除自身以外数组的乘积&#xff08;中等&#xff09; 第三道&#xff1a;轮转数组&#xff08;中等&#xff09; 方法一&#xff1a;使用额外的数…

vscode+cmake+msys2工具链配置

1、msys2下载编译器和cmake工具 pacman -S mingw-w64-x86_64-toolchain pacman -S mingw-w64-x86_64-cmaketoolchain包中包含很多不必要的工具包&#xff0c;应该可以指定具体的工具g&#xff0c;gcc&#xff0c;mingw32-make的下载&#xff0c;详细命令请自行搜索。 2、将 m…

QT 应用程序输出中文乱码

一 &#xff0c;选择文本编码 1. 点击编辑再点击Select Encoding选择编码 2 .在弹出的窗口&#xff0c;选择UTF-8再点击按编码保存即可 3. 重新编译&#xff0c;可以发现中文乱码问题解决

思维+dfs,CF 269C - Flawed Flow

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 269C - Flawed Flow 二、解题报告 1、思路分析 考虑源点相连的边的方向是确定的&#xff0c;因为流量是从源点往外流的 我们设cap[u] 为 和u相连边的容量和&#xff0c;显然入边容量要和出边容量相等&…

jvm调优参数

JVM调优是指调整JVM的参数&#xff0c;以优化Java程序的性能。以下是一些常用的JVM调优方法&#xff1a; 1.堆内存大小&#xff1a;通过-Xms和-Xmx参数设置JVM的初始堆内存和最大堆内存。堆内存太小会导致频繁GC&#xff0c;太大则可能导致内存利用率不高。 2.新生代与老年…

OS_操作系统的运行环境

2024.06.11:操作系统的运行环境学习笔记 第3节 操作系统的运行环境 3.1 操作系统引导3.2 操作系统内核3.2.1 内核资源管理3.2.2 内核基本功能 3.3 CPU的双重工作模式3.3.1 CPU处于用户态&#xff08;目态&#xff09;3.3.2 CPU处于内核态&#xff08;管态&#xff09; 3.4 特权…

鸿蒙Scroll布局,横向与纵向

注意&#xff0c;当横向scroll时&#xff0c;直接子元素的宽&#xff0c;不能100%&#xff0c; 当纵向scroll时&#xff0c;直接子元素的高&#xff0c;不能100%​​​​​​​ 1、纵向代码&#xff1a; 方法1&#xff1a;用数值计算&#xff0c;来设置中间的高度&#xff1a; …

nginx负载均衡、java、tomcat装包

一、nginx 七层负载均衡 1、七层负载均衡基础配置 2、负载均衡状态 [rootserver]# vim /usr/local/nginx/conf/nginx.confworker_processes 1;event {worker_connections 1024&#xff1b;}http { # 七层负载均衡支持http、ftp协议include mime.types;default_type app…

【云原生】数据库忘记密码怎么办?

相信很多人都会遇到在虚拟机中忘记数据库密码的情况&#xff0c;想必大家都很苦恼&#xff0c;所以今天给大家来讲讲数据库忘记密码了如何修改密码再登录数据库&#xff01;&#xff01;&#xff01; 1、关闭数据库服务 systemctl stop mariadb 2、执行MySQL 服务器在启动时跳…

ModuleNotFoundError: No module named ‘tqdm‘

报错信息&#xff1a; tqdm是一个快速、可扩展的Python进度条库&#xff0c;用于展示迭代器的长循环执行进度。 解决&#xff1a;通过以下命令安装 使用conda命令安装 conda install tqdm使用pip安装&#xff1a; pip install tqdm

【JVM】垃圾回收机制、算法和垃圾回收器

什么是垃圾回收机制 为了让程序员更加专注于代码的实现&#xff0c;而不用过多的考虑内存释放的问题&#xff0c;所以在Java语言中&#xff0c;有了自动的垃圾回收机制&#xff0c;也是我们常常提及的GC(Garbage Collection) 有了这个垃圾回收机制之后&#xff0c;程序员只需…

Spring学习笔记1

今天内容:配置maven 搭建了springboot项目 约定大于配置&#xff08;它默认的框架优先级比配置的要高&#xff0c;基本全都用它所默认的框架只有特殊需求的时候才会修改一小部分。&#xff09; IOC Spring IOC 管理项目中java bean的生命周期 在项目运行阶段&#xff0c;…

操作系统与进程简单介绍

操作系统与进程 操作系统进程 操作系统 上一篇博客中介绍了操作系统到底层硬件它们之间的一个关系&#xff0c;那么还是这张图 操作系统到用户它们之间的关系又是如何的呢&#xff1f; 又回到了最根本的问题上&#xff1a;为什么要有操作系统呢&#xff1f; 1、向下管理好软…

敦煌文化主题页面 HTML,CSS,Javascript 源码分享

使用技术&#xff1a;HTML&#xff0c;CSS&#xff0c;JavaScript 项目亮点&#xff1a;加入了大量的CSS动画效果&#xff0c;以及JS交互效果&#xff0c;水平适合初学者以及大学生&#xff0c;包含登录注册页 需要的可以dd&#xff0c; 绿泡泡&#xff1a;ColdDayOne

为面试准备的一些内容

开发中使用了什么技术&#xff1f; mvvm、compose、livedata、单例模式、工厂模式、弱引用、线程池、Handler。 对于项目一开始我们打算使用aosp原生的管控方式&#xff0c;如UsageStatManager获取每个app的使用时长&#xff0c;和使用PackageManager的setPackagesSuspended方…

一文弄清Java的四大引用及其两大传递

开场白 Hello大家好呀&#xff0c;我是CodeCodeBond✊最近在复习很多很多的基础知识&#xff0c;有了很多新的感悟~ 话不多说&#xff0c;直接发车✈ 四大引用 问题切入点 在学习 Thread线程利用ThreadLocalMap实现线程的本地内存&#xff08;变量副本&#xff09;的时候&…

mac配置git的sshkey

在MAC中配置Git的SSH Key&#xff1a; 1.打开终端 2.生成SSH密钥&#xff0c;输入以下命令&#xff1a; ssh-keygen -t rsa -b 4096 -C “你自己的账号电子邮件地址” 按回车键后&#xff0c;系统会提示你输入文件保存路径&#xff0c;默认为~/.ssh/id_rsa直接按回车键使用默…

Mybatis实战:#{} 和 ${}的使用区别和数据库连接池

一.#{} 和 ${} #{} 和 ${} 在MyBatis框架中都是用于SQL语句中参数替换的标记&#xff0c;但它们在使用方式和处理参数值上存在一些显著的区别。 #{}的作用&#xff1a; #{} 是MyBatis中用于预编译SQL语句的参数占位符。它会将参数值放入一个预编译的PreparedStatement中&am…

Java语言程序设计——篇十一(2)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…

MySQL(8.0)数据库安装和初始化以及管理

1.MySQL下载安装和初始化 1.下载安装包 下载地址&#xff1a;https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 2.解压…