鸿蒙应用开发:下载功能

简介: 鸿蒙应用开发:下载功能

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

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

版本:

DevEco Studio 4.1 Release

SDK10

API
request API中介绍了两种下载方式:request.downloadFile和request.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 文件是否存在
    */
    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%')

}
}

下载过程

相关文章
|
7月前
|
存储 移动开发 Android开发
HarmonyOS应用开发者高级认证(88分答案)
HarmonyOS应用开发者高级认证(88分答案)
2722 0
|
7月前
|
JavaScript 前端开发 开发者
深入理解ArkTS:Harmony OS 应用开发语言 TypeScript 的基础语法和关键特性
深入理解ArkTS:Harmony OS 应用开发语言 TypeScript 的基础语法和关键特性
663 0
|
1天前
|
开发框架 人工智能 安全
鸿蒙HarmonyOS应用开发 | 「鸿蒙技术分享」HarmonyOS NEXT元服务卡片实战体验
HarmonyOS NEXT的发布对华为及整个行业都产生了深远的影响。它不仅展示了华为的技术实力,还敏锐地把握了市场需求。同时,吸引了更多的开发者和合作伙伴加入鸿蒙生态体系,共同推动鸿蒙生态的繁荣发展。
148 15
鸿蒙HarmonyOS应用开发 | 「鸿蒙技术分享」HarmonyOS NEXT元服务卡片实战体验
|
1天前
|
物联网 调度 vr&ar
鸿蒙HarmonyOS应用开发 |鸿蒙技术分享HarmonyOS Next 深度解析:分布式能力与跨设备协作实战
鸿蒙技术分享:HarmonyOS Next 深度解析 随着万物互联时代的到来,华为发布的 HarmonyOS Next 在技术架构和生态体验上实现了重大升级。本文从技术架构、生态优势和开发实践三方面深入探讨其特点,并通过跨设备笔记应用实战案例,展示其强大的分布式能力和多设备协作功能。核心亮点包括新一代微内核架构、统一开发语言 ArkTS 和多模态交互支持。开发者可借助 DevEco Studio 4.0 快速上手,体验高效、灵活的开发过程。 239个字符
130 13
鸿蒙HarmonyOS应用开发 |鸿蒙技术分享HarmonyOS Next 深度解析:分布式能力与跨设备协作实战
|
1天前
|
监控 安全 开发工具
鸿蒙HarmonyOS应用开发 | HarmonyOS Next-从应用开发到上架全流程解析
HarmonyOS Next是华为推出的最新版本鸿蒙操作系统,强调多设备协同和分布式技术,提供丰富的开发工具和API接口。本文详细解析了从应用开发到上架的全流程,包括环境搭建、应用设计与开发、多设备适配、测试调试、应用上架及推广等环节,并介绍了鸿蒙原生应用开发者激励计划,帮助开发者更好地融入鸿蒙生态。通过DevEco Studio集成开发环境和华为提供的多种支持工具,开发者可以轻松创建并发布高质量的鸿蒙应用,享受技术和市场推广的双重支持。
111 11
|
21小时前
|
数据管理 API 调度
鸿蒙HarmonyOS应用开发 | 探索 HarmonyOS Next-从开发到实战掌握 HarmonyOS Next 的分布式能力
HarmonyOS Next 是华为新一代操作系统,专注于分布式技术的深度应用与生态融合。本文通过技术特点、应用场景及实战案例,全面解析其核心技术架构与开发流程。重点介绍分布式软总线2.0、数据管理、任务调度等升级特性,并提供基于 ArkTS 的原生开发支持。通过开发跨设备协同音乐播放应用,展示分布式能力的实际应用,涵盖项目配置、主界面设计、分布式服务实现及部署调试步骤。此外,深入分析分布式数据同步原理、任务调度优化及常见问题解决方案,帮助开发者掌握 HarmonyOS Next 的核心技术和实战技巧。
89 63
鸿蒙HarmonyOS应用开发 | 探索 HarmonyOS Next-从开发到实战掌握 HarmonyOS Next 的分布式能力
|
26天前
「Mac畅玩鸿蒙与硬件26」UI互动应用篇3 - 倒计时和提醒功能实现
本篇将带领你实现一个倒计时和提醒功能的应用,用户可以设置倒计时时间并开始计时。当倒计时结束时,应用会显示提醒。该项目涉及时间控制、状态管理和用户交互,是学习鸿蒙应用开发的绝佳实践项目。
69 2
「Mac畅玩鸿蒙与硬件26」UI互动应用篇3 - 倒计时和提醒功能实现
|
12天前
|
存储 JSON 开发工具
三、HarmonyOS NEXT应用开发:ArkTS工程目录结构(Stage模型)
本文介绍了HarmonyOS NEXT应用开发中ArkTS工程的目录结构(Stage模型),包括AppScope、entry、hvigor、oh_modules等主要目录及其作用。重点解析了entry目录下的src > main > resources目录结构,详细说明了base、限定符目录和rawfile的作用,以及如何引用资源文件。
49 1
|
12天前
|
IDE JavaScript 开发工具
一、鸿蒙应用开发快速体验
本文介绍了鸿蒙应用开发的快速体验流程,涵盖从开发环境的准备到项目的实际运行。首先,需安装并配置华为DevEco Studio IDE,该IDE基于IntelliJ IDEA Community构建,旨在为鸿蒙应用开发提供一站式解决方案。接着,通过创建新项目、选择合适的模板及配置项目信息,可以迅速搭建起应用的基本框架。最后,本文还详细描述了如何利用Preview预览、模拟器运行以及真机调试三种方式来测试和优化应用,确保其在不同场景下的兼容性和性能表现。整个过程旨在帮助开发者快速入门鸿蒙应用开发,提升开发效率。
38 0
一、鸿蒙应用开发快速体验
|
2月前
|
存储 开发工具 开发者
紧跟科技潮流,揭秘鸿蒙应用开发新世界:打造全场景智慧生活,你准备好迎接这场技术革命了吗?
【10月更文挑战第20天】随着华为鸿蒙系统的发布,一个全新的操作系统生态正在形成。本文将探讨基于鸿蒙系统的应用软件开发,介绍其跨设备特性、开发工具链及框架,并通过示例代码展示开发流程,帮助开发者更好地理解和利用这一平台。
46 4
下一篇
DataWorks