作者:FFH_PETSJ
本文基于 ArkUI request API 实现下载进度获取及显示。
在鸿蒙应用开发中,我们常用两种方式来实现文件的下载:
使用系统能力:
SystemCapability.Communication.NetStack(@ohos.http)
使用系统能力:
SystemCapability.MiscServices.Download(@ohos.request)
区别如下:前者下载过程信息不可见,后者会在手机状态栏显示下载会话,并且可被应用监听;前者请求下载后不会对文件作进一步处理,后者会直接保存到指定目录。
文档传送门:
https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-request-0000001333800457
https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/apis/js-apis-request.md/
下面,我们基于 ArkUI-ts 来实现一个下载进度条的显示,以 API 8、FA 模型为例。
API 9 接口稍有改动,若使用 API 9、Stage 模型,请参考官方文档OpenHarmony,但基本的代码思路是不变的。
https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/reference/apis/js-apis-request.md/
变动:相比于 API 8 的 FA 模型,加入了 Context 的传参;增加了uploadFile()、downloadFile() 方法,保留 upload()、donwload() 方法。
实现流程
首先配置网络权限(config.json–>module 下添加):
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
支持 http(config.json 下添加):
"deviceConfig": {
"default": {
"network": {
"cleartextTraffic": true
}
}
},
导入系统接口:
import request from '@ohos.request'
DownloadConfig
常用的字段配置:
其它的字段配置:
示例 1:例如通过图片 url 下载保存到本地的 internal://cache 的 myDownload/test.png 路径,文件名为 test.png。
let downloadConfig: request.DownloadConfig = {
url: downloadUrl,
filePath: 'myDownload/test.png',
description: 'Download Test',
}
internal://cache 是应用沙箱路径,获取方法:
import featureAbility from "@ohos.ability.featureAbility"
let cacheSandPath = featureAbility.getConext().getCacheDoir()
目前 js api 只支持在 filePath 配置在 internal://cache 下(默认)。
我们有两种方式可以访问到下载的文件:一是内部储存目录 storage 路径 file 目录;二是只允许本应用访问的沙箱路径 cache 目录。
这个知识点在后面的 Image 显示会用到。
let downloadTask
request.download(downloadConfig, (err, data) => {
if (err) {
console.info('xxx--- Failed to request the download. Cause: ' + JSON.stringify(err))
return
}
downloadTask = data
})
request.DownloadTask:
request.DownloadInfo:
想要实现下载进度的监听,从上面的方法我们可以找到对应的方法 on(“progress”)。
示例 3-1
downloadTask.on('progress', (receiveSize: number, totalSize: number) => {
this.curProgressValue = (receiveSize / totalSize) * 100
this.curTaskDownloadedSize = receiveSize
this.curTaskTotalSize = totalSize
})
经过测试发现,直接使用 on(‘progress’) 不一定能监听到实时下载大小和总大小,返回值 receivedSize 和 totalSize 可能为 0。
因此当 on(“progress”) 的返回值为 0 时,我们可以用另外一个方法 query() 来查询实时下载中的进度信息,或是在 query() 中使用 on(‘progress’)。
示例 3-2
进度的监听:
let downloadInfoFilePath:string = ''
downloadTask.query().then((downloadInfo:request.DownloadInfo) => {
downloadInfoFilePath = downloadInfo.filePath // 此处返回的路径不同于应用沙箱路径
this.downloadTask = data
this.downloadTask.on('progress', (receiveSize: number, totalSize: number) => {
this.curProgressValue = (receiveSize / totalSize) * 100 // 进度条Progress属性值
this.curTaskDownloadedSize = receiveSize // 实时下载大小
this.curTaskTotalSize = totalSize // 总大小
})
/* 或使用query返回的downloadInfo获取下载进度信息
this.curTaskDownloadedSize = downloadInfo.downloadedBytes
this.curTaskTotalSize = downloadInfo.downloadTotalBytes
this.curProgressValue = (this.curTaskDownloadedSize / this.curTaskTotalSize) * 100
*/
console.info('xxx--- downloadTask queried info:' + JSON.stringify(downloadInfo))
}).catch((err) => {
console.info('xxx--- Failed to query the downloadTask:' + JSON.stringify(err))
})
示例 3-3
complete、fail、pause 事件的监听:
downloadTask.query().then((downloadInfo:request.DownloadInfo) => {
......
var self = this
var clearListeners = function () {
self.downloadTask.off('progress')
self.downloadTask.off('fail')
self.downloadTask.off('remove')
self.downloadTask.off('complete')
}
this.downloadTask.on('fail', (err) => {
clearListeners()
this.curProgressValue = 0
})
this.downloadTask.on('remove', () => {
clearListeners()
this.curProgressValue = 0
})
this.downloadTask.on('complete', () => {
clearListeners()
this.curProgressValue = 100
// downloadInfoList:string[] 保存下载历史的路径
this.downloadInfoList.push(downloadInfoFilePath)
})
})
定义一个 Progress 组件来显示当前下载任务的进度(数字和进度条),当下载任务结束后,显示相关信息:任务成功 or 失败、保存的位置。
Progress({ value: this.curProgressValue })
.width('90%')
.color(Color.Blue)
.margin(10)
Text 显示相关下载信息:
Text('实时下载大小: ' + this.curTaskDownloadedSize + ' B').width('90%').fontSize(25).margin(10)
Text('当前任务大小: ' + this.curTaskTotalSize + ' B').width('90%').fontSize(25).margin(10)
Text('下载储存路径:').width('90%').fontSize(25).margin({ left: 10, right: 10, top: 10, bottom: 5 })
定义 Image 组件,获取保存路径显示下载的媒体(仅当图片)。
这里访问路径使用的是 downloadInfo 中的 filePath 属性,即内部储存路径。
// downloadInfoList:string[] 保存下载历史的路径
ForEach(this.downloadInfoList, item => {
Flex({ justifyContent: FlexAlign.Center }) {
Image(item)
.backgroundColor('#ccc')
.margin(5)
.width('25%')
.aspectRatio(1)
.alignSelf(ItemAlign.Start)
.objectFit(ImageFit.ScaleDown)
Text(item).fontSize(15).padding(10).width('70%')
}.width('95%')
}, item => item)
同时,可以完美地运用上我此前封装好的文件管理器组件-FilerBall,来检验我们文件下载保存的位置,以及查看更详细的文件信息。
这里设置 images、video、file 都保存在沙箱访问路径 internal://cache 的 myDownload/ 下。
Image 回显:
downloadDemo(downloadUrl: string, saveUrl?: string) {
var self = this
var clearListeners = function () {
self.downloadTask.off('progress')
self.downloadTask.off('fail')
self.downloadTask.off('remove')
self.downloadTask.off('complete')
}
let downloadConfig: request.DownloadConfig = {
url: downloadUrl,
filePath: 'myDownload/' + saveUrl,
enableMetered: true,
enableRoaming: true,
description: 'Download Test',
}
request.download(downloadConfig, (err, data) => {
if (err) {
console.info('xxx--- Failed to request the download. Cause: ' + JSON.stringify(err))
return
}
let downloadInfoFilePath
this.curProgressValue = 0
this.mes = '开始'
this.downloadTask = data
this.downloadTask.query().then((downloadInfo: request.DownloadInfo) => {
downloadInfoFilePath = downloadInfo.filePath
this.downloadTask.on('progress', (receiveSize: number, totalSize: number) => {
this.curProgressValue = (receiveSize / totalSize) * 100
this.curTaskDownloadedSize = receiveSize
this.curTaskTotalSize = totalSize
})
console.info('xxx--- Download task queried. Data:' + JSON.stringify(downloadInfo))
}).catch((err) => {
console.info('xxx--- Failed to query the download task. Cause:' + JSON.stringify(err))
})
this.downloadTask.on('fail', (err) => {
clearListeners()
this.curProgressValue = 0
this.mes = '失败'
})
this.downloadTask.on('remove', () => {
clearListeners()
this.curProgressValue = 0
this.mes = '取消'
})
this.downloadTask.on('complete', () => {
clearListeners()
this.curProgressValue = 100
this.mes = '完成'
// downloadInfoList保存下载历史的路径
this.downloadInfoList.push(downloadInfoFilePath)
})
})
}
ets 使用示例:
Button('下载视频(小)', { type: ButtonType.Capsule })
.width('90%')
.height(50)
.margin(10)
.onClick(() => {
this.curProgressValue = this.curTaskDownloadedSize = this.curTaskTotalSize = 0
this.downloadDemo('https://media.w3.org/2010/05/sintel/trailer.mp4', 'video/')
})
页面更新:2024-05-12
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号