鸿蒙应用开发:下载功能

news2024/11/6 1:53:56

鸿蒙系统不断发展,有与安卓、iOS 形成三足鼎立之势,且其在智能手机、智能穿戴、车载、家居等行业领域的应用越来越广泛。作为开发者,如何抓住鸿蒙生态崛起的机遇,解决开发挑战,创造更好的应用体验?欢迎您和我们一起探讨~

鸿蒙提供了多种API用于下载,今天我就拿request包来讲解下如何实现下载。

版本:

DevEco Studio 4.1 Release

SDK10

API

request API中介绍了两种下载方式:request.downloadFilerequest.agent.create。如果仅限于下载,两者区别不大,仅仅是下载路径区别。前者的config可指定所有沙箱路径,后者的config只能指定缓存目录。但是若考虑到一些细节问题,如断点续传等,推荐第二种。

主代码

下载功能主代码要求输入下载地址(url)和下载文件名(name),并且首先基于文件名检查文件是否存在,然后创建下载任务,并且在下载过程中订阅了下载进度,即时将下载信息传递给页面进行渲染。


import fs from '@ohos.file.fs';
import request from '@ohos.request';
import Prompt from '@system.prompt';
import EventBus from './EventBus';
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';

let downloadTask: request.agent.Task;
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;

export class DownLoader {

  /**
   * 下载文件
   * @param url 文件地址
   * @param name 文件名
   */
  static async downloadthisFile(url,name) {
    let filePath = context.cacheDir+'/'+name;
    try {

      // 检查文件是否存在
      const fileExists = await checkFileExists(filePath);
      if (fileExists) {
        console.log("File already exists, deleting the existing file...");
        await fs.unlink(filePath); // 删除已存在的文件
        console.log("File deleted successfully.");
      }

      // 创建下载任务
      let config: request.agent.Config = {
        action: request.agent.Action.DOWNLOAD,
        url: url,
        saveas: './'+name,
        overwrite: true,
        mode: request.agent.Mode.FOREGROUND,
        index: 0,
        begins: 0,
        ends: -1,
      };

      try {
        downloadTask = await request.agent.create(getContext(), config);
        console.info(`Succeeded in creating a download task. result: ${downloadTask.tid}`);
        downloadTask.start();
        Prompt.showToast({ message: "Download task started.", duration: 1000 });

        // 订阅下载进度
        if (downloadTask.tid) {
          let lastReceivedSize = 0;
          let lastTime = Date.now();

          // 监听下载进度
          let call = async (progress: request.agent.Progress) => {
            const Speed = calculateSpeed(progress.processed, lastTime, lastReceivedSize);
            const percent = (progress.processed / progress.sizes[0]) * 100;
            const size = (progress.sizes[0] / 1024 / 1024).toFixed(2); // MB
            console.log("进度 速度 大小", percent, Speed, size);

            // 直接更新状态
            EventBus.emit('downloadProgress', percent);
            EventBus.emit('downloadSpeed', Speed);
            EventBus.emit('downloadSize', size);
            console.log("Download task returned:", downloadTask.tid)
          };

          // 订阅下载进度
          downloadTask.on('progress', call);

          console.log("Download task returned:", downloadTask.tid);
        }
      } catch (err) {
        console.error(`Failed to create a download task, Code: ${err.code}, message: ${err.message}`);
      }

      if (!downloadTask.tid)
        throw new Error("Download task failed, no task returned.");

    } catch (err) {
      console.error(`Failed to download file. Error: ${err.message}`);
    }

  }

  /**
   * 暂停下载
   */
  static async pausedownload() {
    downloadTask.pause().then(() => {
      console.info(`Succeeded in pausing a download task. `);
    }).catch((err: BusinessError) => {
      console.error(`Failed to pause the upload task, Code: ${err.code}, message: ${err.message}`);
    });
  }

  /**
   * 恢复下载
   */
  static async resumedownload() {
    downloadTask.resume().then(() => {
      console.info(`Succeeded in resuming a download task. `);
    }).catch((err: BusinessError) => {
      console.error(`Failed to resume the download task, Code: ${err.code}, message: ${err.message}`);
    });
  }
}

/**
 * 计算下载速度
 * @param receivedSize 已接收的字节数
 * @param lastTime 上次计算速度的时间戳
 * @param lastReceivedSize 上次计算速度时已接收的字节数
 * @returns 速度,单位KB/s
 */
function calculateSpeed(receivedSize,lastTime,lastReceivedSize) {
  const currentTime = Date.now();
  const timeElapsed = (currentTime - lastTime) / 1000; // 转换为秒
  const bytesReceived = receivedSize - lastReceivedSize; // 新接收到的字节数

  // 计算速度
  const speed = timeElapsed > 0 ? (bytesReceived / timeElapsed) : 0; // 字节/秒

  // 更新历史数据
  lastTime = currentTime;
  lastReceivedSize = receivedSize;

  return Number((speed / 1024).toFixed(2)); // 转换为KB/s
};


/**
 * 检查文件是否存在
 * @param filePath 文件路径
 * @returns Promise<boolean> 文件是否存在
 */
async function checkFileExists(filePath) {
  try {
    console.log("Checking file existence for:", filePath);
    await fs.stat(filePath);
    return true; // 文件存在
  } catch (err) {
    if (err.code === 'ENOENT') {
      return false; // 文件不存在
    } else {
      console.error(`Error checking file existence: ${err.message}`);
      return false; // 处理其他错误
    }
  }
}

页面

页面主体是两个输入框,输入下载地址(url)和下载文件名(name),执行下载的按钮、暂停(继续)按钮以及一个圆形进度条。

import { DownLoader } from '../common/Download';
import EventBus from '../common/EventBus';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State download: boolean = true;
  @State url: string = '';
  @State fileName: string = '';
  @State percent: number = 0;


  aboutToAppear(): void {
    // 订阅下载进度更新
    EventBus.on('downloadProgress', async (percent) => {
      this.percent = percent;
      console.log("Updated download progress:", this.percent);
    });
  }
  build() {
    Column() {
      TextInput({ text: this.url, placeholder: 'input your download url' }).margin({ top: 20 })
        .onSubmit((EnterKeyType) => {
          console.info(EnterKeyType + '输入法回车键的类型值')
        })
      TextInput({ text: this.fileName, placeholder: 'input your download file name' }).margin({ top: 20 })
        .onSubmit((EnterKeyType) => {
          console.info(EnterKeyType + '输入法回车键的类型值')
        })
      Button('Download')
        .width(150)
        .margin({ top: 20 })
        .onClick(async ()=>{
          await DownLoader.downloadthisFile(this.url,this.fileName);
        })
      Button(this.download ? 'Pause' : 'Resume')
        .width(150)
        .margin({ top: 20 })
        .onClick(async ()=>{
          this.download = !this.download;
          this.download ? DownLoader.resumedownload() : DownLoader.pausedownload();
        })

      Progress({ value: this.percent, total: 100, type: ProgressType.ScaleRing }).width(100).height(100)
        .margin({top: 50})
        .visibility(this.percent >= 0 && this.percent <= 100 ? Visibility.Visible : Visibility.Hidden)
        .backgroundColor(Color.Black)
        .style({ strokeWidth: 15, scaleCount: 20, scaleWidth: 5 })	// 设置环形有刻度进度条宽度15,总刻度数为20,刻度宽度为5vp
    }
    .padding(20)
    .width('100%')
  }
}

 

下载过程

tips:执行下载的代码很简单,接下来完善一下断点续传等功能。欢迎感兴趣的看官老爷指点交流~

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

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

相关文章

小白直接冲!BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测

小白直接冲&#xff01;BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测 目录 小白直接冲&#xff01;BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测效果一览基本介绍程序设计参考资料 效果一…

如何绘制产业链图谱?

绘制产业链图谱是一个系统性的工作&#xff0c;涉及到对产业的深入理解和分析。对于一般产业绘制产业图谱的步骤&#xff0c;我们可以参照以下流程&#xff1a; 1.明确目标产业链&#xff1a;确定要分析的产业链&#xff0c;比如新材料、新能源、智能制造等&#xff0c;这通常…

Pycharm,2024最新专业版下载安装配置详细教程!

先来一段官方介绍&#xff0c;PyCharm是一种PythonIDE&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外&#xff0c;该IDE提供了一些高级功能…

鸿蒙开发——进程模型与进程通信

1、进程模型 ❓ 什么是进程&#xff1f; 进程是一个正在执行的程序的实例。当我们启动一个程序时&#xff0c;操作系统会创建一个进程&#xff0c;分配给它所需的资源&#xff0c;如内存和CPU时间。每个进程至少有一个线程&#xff0c;即执行线程&#xff0c;负责执行程序的指…

SQL server 中 CROSS APPLY的使用

CROSS APPLY 是 SQL Server 中的一个操作符&#xff0c;用于将一个表表达式&#xff08;如子查询、函数等&#xff09;与外部表进行连接。CROSS APPLY 类似于 INNER JOIN&#xff0c;但它允许你在一个查询中多次引用外部表的行&#xff0c;并且可以动态地生成结果集。 基本语法…

xlwings,让excel飞起来!

excel已经成为必不可少的数据处理软件&#xff0c;几乎天天在用。python有很多支持操作excel的第三方库&#xff0c;xlwings是其中一个。 关于xlwings xlwings开源免费&#xff0c;能够非常方便的读写Excel文件中的数据&#xff0c;并且能够进行单元格格式的修改。 xlwings还…

[大模型]Diffusion扩散式生成模型

一、概述 扩散式生成模型相较于GAN网络的对抗式生成模型&#xff0c;有更高的精度&#xff0c;也更符合人类的视觉和审美罗技&#xff0c;且风格化能力更强。现行的所有Diffusion模型都是基于2020年的论文DDPM来实现的。 GAN网络通过使生成器(Generator)生成的模型尽可能的逼近…

十四届蓝桥杯STEMA考试Python真题试卷第二套第五题

来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第五题 本题属于迷宫类问题,适合用DFS算法解决,解析中给出了Python中 map() 和列表推导式的应用技巧。最后介绍了DFS算法的两种常见实现方式——递归实现、栈实现,应用场景——迷宫类问题、图的连通性、树的遍历、拓朴排…

keil5的Debug调试时,卡在 LDR R0, =SystemInit,无法往后进行

解决办法&#xff1a;使用STM32Cube生成的工程文件时&#xff0c;勾选Use MicroLIB即可

OpenEuler 使用ffmpeg x11grab捕获屏幕流,rtsp推流,并用vlc播放

环境准备 安装x11grab(用于捕获屏幕流)和libx264(用于编码) # 基础开发环境&x11grab sudo dnf install -y \autoconf \automake \bzip2 \bzip2-devel \cmake \freetype-devel \gcc \gcc-c \git \libtool \make \mercurial \pkgconfig \zlib-devel \libX11-devel \libXext…

ai常见实验

参考链接https://arxiv.org/pdf/2410.19894 对比实验&#xff08;sota 表格&#xff09; -辅助信息可以体现 P F 等 可视化结果 &#xff08;图片形式&#xff09; 消融实验 超参数实验 &#xff08;有时候表示 有时候单独表格 看哪个参数好&#xff09; 部分消融和超参数…

【万字详文介绍】:迭代扩张卷积神经网络(IDCNN)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Oracle OCP认证考试考点详解082系列12

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 56. 第56题&#xff1a; 题目 解析及答案&#xff1a; 关于企业管理器&#xff08;EM&#xff09;Express&#xff0c;以下哪两个陈述是…

任务:拟合曲面

3d 要拟合粗的蓝色曲面&#xff0c;剩下三条线是在3个平面的投影 1 2 3 4d

Python世界:自动化办公Word之批量替换文本生成副本

Python世界&#xff1a;自动化办公Word之批量替换文本生成副本 任务背景编码思路代码实现相关参考 任务背景 为提高办公效率&#xff0c;用python试手了一个word任务&#xff0c;要求如下&#xff1a; 给你一个基础word文档A&#xff0c;格式为docx&#xff0c;名字为&#xf…

如何检查雷池社区版 WAF 是否安装成功?

容器运行状态检查&#xff1a; 使用命令行检查&#xff1a;打开终端&#xff0c;连接到安装雷池的服务器。运行 docker ps 命令&#xff0c;查看是否有与雷池相关的容器正在运行。 如果能看到类似 safeline-mgt、safeline-tengine 等相关容器&#xff0c;并且状态为 Up&#x…

青少年编程能力等级测评CPA Python编程(一级)

青少年编程能力等级测评CPA Python编程(一级) &#xff08;考试时间90分钟&#xff0c;满分100分&#xff09; 一、单项选择题&#xff08;共20题&#xff0c;每题3.5分&#xff0c;共70分&#xff09; 下列语句的输出结果是&#xff08; &#xff09;。 print(35*2) A&a…

java学习2

一、什么是方法 方法&#xff08;method&#xff09;是程序中最小的执行单元 重复的代码、具有独立功能的代码可以抽取到方法中&#xff1b;提高代码的复用性和可维护性。 二、方法的格式 1.方法的格式定义&#xff1a; 最简单的方法定义 调用&#xff1a;playGame(); 带…

蓝牙资讯|苹果AirPods Pro 2推出听力测试、助听器和听力保护等功能

苹果推送iOS 18.1 系统版本更新&#xff0c;AirPods Pro 2 用户也在 iOS 18.1 中获得了强大的新功能。 运行固件 7B19 的 AirPods Pro 2 用户&#xff0c;搭配 iOS 18.1 系统的 iPhone&#xff0c;将获得三项强大的听力健康功能&#xff1a;听力测试、助听器和听力保护。 听力…

【学习日记】Anaconda的安装与使用-小白大学生

目录 日记说明 解压安装&#xff1a; 配置 使用 日记说明 作者是个大学生 这个专栏主要收集课时常用的软件 以及女朋友上课用的软件的教程 所有安装包可以私聊我获取 免费 提前清除已有python环境 windows11 Anaconda-2024.02 垃圾话&#xff1a; Anaconda 是全球领先的数…