基于ArkUI request API实现下载进度获取及显示

本文基于 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-0000001333800457https://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.featureabilitylet 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,来检验我们文件下载保存的位置,以及查看更详细的文件信息。
演示图:
借助 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/')})  页面代码放在附件资源,请点击阅读原文查看。  


鸿蒙2.0系统下载 鸿蒙系统官方下载地址
iphone8什么时候上市最新消息:苹果iphone8、iphone7s如期发布,富士康已经开始量产,售价1000美元起
存储器分类,存储器的分级结构
MSO5/6B系列示波器在智能汽车电源环路响应测试
ADI电源产品推陈出新 突破性能“老三篇
基于ArkUI request API实现下载进度获取及显示
苹果发布2019财年第四财季业绩,iPhone 11的定价策略很成功
RDAW263 高线性2.5-2.7 GHz WiMAX宽带
单片机跟plc哪个的区别是什么
关于开源Linux操作系统的veLinux深度解读
钳位二极管和稳压管的区别是什么
全屏指纹 双卡双待或将在iPhone8发布时上线?
地平线机器人数字输入编程
元宇宙的发展是大势所趋吗
FW工程师是干什么的
2016工业机器人亮点频现 3C与汽车成主战场
均联智行获颁TUV南德ISO/SAE 21434 汽车网络安全流程认证证书
中微公司Primo D-RIE®作为首台设备顺利搬入客户生产线
HRA系列DC-DC隔离电源模块接线注意事项
如何检测恶劣环境下的金属缺陷,视觉检测系统来助力