HarmonyNext使用request.agent.download實現斷點下載

filedownlaod(API12)

📚簡介

filedownload 這是一款支持大文件斷點下載的開源插件,退出應用程序進程殺掉以后或無網絡情況下恢復網絡后,可以在上次位置繼續恢復下載等

版本更新—請查看更新日志!!! 修復已知bug,demo已經更新

📚下載安裝

ohpm install @ohos_lib/filedownload

1、添加權限在應用主模塊entry/src/main/ets/module.json5下

"requestPermissions": [{"name" : "ohos.permission.INTERNET"},{"name" : "ohos.permission.GET_NETWORK_INFO"},]

2、在應用主模塊entry入口EntryAbility onCreate生命周期里下面添加初始化數據庫操作

 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');SqliteHelper.getInstance(this.context).initRDB();
}

3、在應用主模塊entry入口Index.ts AboutToAppear()生命周期里添加如下代碼

 try {await DownloaderUtil.persistActiveDownloads();
}catch (e) {
}

4.首先確定服務器是否支持斷點下載,否則通過request.agent.create無法實現斷點下載

 curl -I -H "Range: bytes=0-100" 下載路徑
出現206 Partial Content 就代表著服務器支持斷點續傳與下載 —如下
yanruifeng@bogon video % curl -I -H "Range: bytes=0-100" https://dal-video.wenzaizhibo.com/a6dac8c6371a54477a5692f46ea9698e/6825c7da/00-x-upload/video/205971345_ae77bc38ae8b689a5a534e51b3153c8b_Kg3W8sai.mp4HTTP/1.1 206 Partial Content

filedownload相關 API

方法介紹
persistActiveDownloads()斷點下載的主要方法「內置更改數據庫狀態,把斷點前后字節數統一合并成一個文件」
static async pause(taskId: string):Promise下載暫停方法「內置更改數據庫狀態」
static async resume(downloadInfo: IFileDownloader):Promise下載恢復方法 「內置更改數據庫狀態」
static async delete(userId: string, downloadId: string):Promise刪除「取消下載」方法「刪除數據庫表記錄,刪除文件系統下載文件、」
static async downloadFile(data: T, isBatchInsertQueue?: boolean)通用下載方法
GTNetworkUtil網絡相關工具類 「監聽有網、無網狀態」
FileUtil文件操作相關工具類 「沙盒文件存儲、刪除等操作」
SqliteHelper數據庫操作類、「增刪改查」
static addListener(eventName:string,callback:(download:IFileDownloader)=>void)下載統一監聽回調類「進度監聽、失敗、恢復、成功、暫停」
基本用法
import { IFileDownloader } from '@ohos_lib/filedownload/src/main/ets/interface/IFileDownloader';
import {DownloaderUtil,DownloadManager, NetworkCallback, SqliteHelper,GTNetworkUtil} from '@ohos_lib/filedownload'
import { DownloadStatus } from '@ohos_lib/filedownload/src/main/ets/constants/DownloadStatus';
import { relationalStore } from '@kit.ArkData';
import { promptAction, router } from '@kit.ArkUI';
import { IResponseData } from '../interfaces/IResponseData';@Entry
@ComponentV2
struct SingleFileDownload {@Local userId:string ='722134343434343434';//登錄用戶信息id 這里寫四Mockprivate networkCallback:NetworkCallback={netAvailableCallback: (netHandle: ESObject) => {promptAction.showToast({message:'網絡可用~'})},netLostCallback: (_: ESObject) => {promptAction.showToast({message:'網絡連接已斷開,請檢查~'})//無網絡情況下,恢復網絡后繼續保持在上次位置下載 --只需要調用如下一行代碼即可// 本質邏輯內部還是發送了一個監聽,統一在DownloadManager.addListener監聽處理DownloaderUtil.persistActiveDownloads()}}@Local data: IResponseData[] = [];async aboutToAppear() {this.loadData();getContext().eventHub.on('reQuery',()=>{this.loadData();})DownloadManager.addListener(DownloadManager.eventName,(downloadInfo:IFileDownloader)=>{console.log('更新回調',downloadInfo.downloadSize)//進度監聽更新回調let newData =  this.data?.map((item)=>{if(item.downloadId===downloadInfo.downloadId){item.taskId = downloadInfo.taskId;item.filePath = downloadInfo.filePath;item.fileName =downloadInfo.fileName;item.downloadSize = downloadInfo.downloadSize;item.fileSize = downloadInfo.fileSize;item.isBackgroundPause =downloadInfo.isBackgroundPause;item.exitFrequency = downloadInfo.exitFrequency;item.status = downloadInfo.status;item.begins = downloadInfo.begins;return item;}return item;})this.data =newData;})//完善在無網絡情況下,下載任務暫停,并且恢復網絡后繼續下載GTNetworkUtil.register(this.networkCallback)}//TODO tips: 下載失敗,首先檢查url是否可以正常訪問,或者瀏覽器是否可以正常在線下載async loadData(){// TODO 假設從網絡獲取數據數據結構為: response=[{classNumber:'76432121445578293',className:'第一章 第一講:At the Airport在機場'}]//轉換數據結構response時接口類型必須要繼承 extends IFileDownloader IFileDownloader接口類型初始化至少包含三個字段userId ,downloadId,url userId登錄用戶的userId//因此extends IFileDownloader過的IResponseData接口類型 對應轉換后的數據如下所示let result:IResponseData[] =[{classNumber:'76432121445578293',downloadId:'76432121445578293',className:'第一章 第一講:At the Airport在機場',"url": "http://dal-video.wenzaizhibo.com/13c7d34a1181dddad67cfbe387977842/6836c525/00-x-upload/video/209245033_3aaf16a38aff214594fffec92839d37e_n8kGbGC8.mp4",       userId:this.userId}]//從數據庫讀取獲取上次的下載進度let predicates =new relationalStore.RdbPredicates(SqliteHelper.tableName);predicates.equalTo('userId',this.userId);let queryList = await SqliteHelper.getInstance(getContext()).queryData(predicates);if(queryList.length>0){let newData = result.map((item:IResponseData)=>{let obj =queryList.find(el=>el.downloadId===item.downloadId);if(obj) {item.taskId = obj.taskId;item.filePath = obj.filePath;item.fileName =obj.fileName;item.downloadSize = obj.downloadSize;item.fileSize = obj.fileSize;item.isBackgroundPause =obj.isBackgroundPause;item.exitFrequency = obj.exitFrequency;item.status = obj.status;item.begins = obj.begins;return item;}return item;})this.data= newData;}else{this.data = result;}}aboutToDisappear(): void {GTNetworkUtil.unregister();DownloadManager.removeListener(DownloadManager.eventName)getContext().eventHub.off('reQuery');}getStatus(status:number|undefined){switch (status){case DownloadStatus.COMPLETED:return '下載完成'case DownloadStatus.PAUSE:return '暫停'case DownloadStatus.FAILED:return '下載失敗'case DownloadStatus.RUNNING:return '下載中'default :return '下載'}}@Builder imageAnimator(item:IResponseData){ImageAnimator().images([{src: $r('app.media.ic_downloading_1')},{src: $r('app.media.ic_downloading_2')},{src: $r('app.media.ic_downloading_3')},{src: $r('app.media.ic_downloading_4')},{src: $r('app.media.ic_downloading_5')}]).duration(1000).state(item.status===DownloadStatus.RUNNING?AnimationStatus.Running:AnimationStatus.Initial).reverse(false).fillMode(FillMode.None).iterations(-1).width(24).height(24).onStart(() => {console.info('Start')}).onPause(() => {console.info('Pause')}).onRepeat(() => {console.info('Repeat')}).onCancel(() => {console.info('Cancel')}).onFinish(() => {console.info('Finish')})}build() {Column() {Stack({alignContent:Alignment.TopStart}){ForEach(this.data,(item:IResponseData)=>{Flex({direction:FlexDirection.Row,alignItems:ItemAlign.Center,justifyContent:FlexAlign.SpaceBetween}) {Row(){Text(item?.className).fontSize(16).fontWeight(FontWeight.Bold)}.layoutWeight(1)if(item.status===DownloadStatus.COMPLETED){Image($r('app.media.ic_download_completed')).width(24).height(24)}else if(item.status===DownloadStatus.RUNNING) {this.imageAnimator(item);}else if(item.status===DownloadStatus.FAILED){Image($r('app.media.ic_download_fail')).width(24).height(24)}else if(item.status===DownloadStatus.PAUSE){Image($r('app.media.ic_download_start')).width(24).height(24)}}.width('100%').height(44).onClick(async ()=>{if (item?.status === DownloadStatus.RUNNING) { //下載中---->點擊觸發取消下載【刪除下載】let number =  await DownloaderUtil.delete(item.userId,item.downloadId);if(number>0){this.loadData();}} else if (item?.status === DownloadStatus.FAILED) { //下載失敗----> 重新下載DownloaderUtil.downloadFile(item);} else if (item?.status === DownloadStatus.PAUSE) { //下載暫停----->代表要恢復下載await DownloaderUtil.resume(item);} else if(item.status===DownloadStatus.COMPLETED) { //下載完成 ---->去播放router.pushUrl({url: 'pages/VideoPlayerPage',params:{url:'file:///'+item.filePath+'/'+item.fileName,}})}else{ //未下載 -->去下載promptAction.showToast({message:'開始下載',})DownloaderUtil.downloadFile(item);}}).padding({left: 16,right: 16}).margin({top: 32})})}.layoutWeight(1)Button('查看下載').type(ButtonType.Capsule).onClick(()=>{router.pushUrl({url:'pages/DownloadManagerPage',params:{data:this.data,userId:this.userId}})}).backgroundColor(Color.Red)}.height('100%').width('100%')}
}
運行Demo演示效果
  • demo 運行 git clone https://github.com/yrjwcharm/ohos_library.git
  • 切換分支 git checkout feature/ohos/fileDownload
下載觀看Demo演示效果–退出應用程序殺掉進程后恢復下載

點擊下載視頻

下載觀看Demo演示效果–無網絡情況下恢復網絡后繼續保持下載

點擊下載視頻

鴻蒙技術交流QQ群:783867484
開源不易,希望您可以動一動小手點點小??
👴希望大家如有好的需求踴躍提交,如有問題請前往github提交issue,空閑時間會擴充與修復優化

🌏開源協議

本項目基于 Apache License 2.0 ,在拷貝和借鑒代碼時,請大家務必注明出處。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/907560.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907560.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907560.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nginx: [emerg] bind() to 0.0.0.0:80 failed (10013: 80端口被占用

Nginx啟動報錯:nginx: [emerg] bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions) 這個報錯代表80端口被占用 先查看占用80的端口 netstat -aon | findstr :80 把它殺掉,強…

embbeding 視頻截圖

Embedding是什么?有什么作用?是怎么得到的?_嗶哩嗶哩_bilibili

服務器tty2終端如何關機

在服務器的 tty2 或其他虛擬終端上,要安全地進行關機操作,可以使用以下命令之一: 1.1 使用 shutdown 命令: shutdown 命令可以計劃系統關機。默認需要超級用戶權限。 sudo shutdown -h now-h 選項表示關機(halt&…

時序數據庫IoTDB啟動方式及集群遷移指南

IoTDB啟動方式 IoTDB在配置啟動時有兩種推薦方式: ?主機名啟動?: ?推薦理由?:主機名啟動方式更為靈活,便于在不同網絡環境中部署相同的IoTDB實例。?工作原理?:IoTDB啟動后會維護一張節點編號與網絡地址的映射表…

如何在Qt中繪制一個帶有動畫的弧形進度條?

如何在Qt中繪制一個弧形的進度條 在圖形用戶界面開發中,進度指示控件(Progress Widget)是非常常見且實用的組件。CCArcProgressWidget 是一個繼承自 QWidget 的自定義控件,用于繪制圓弧形進度條。當然,筆者看了眼公開…

在 Mac 下 VSCode 中的終端使用 option + b 或 f 的快捷鍵變成輸入特殊字符的解決方案

前言 在終端里,我們可以使用 option b 和 option f 來在我們輸入的命令中進行快速的前后調整光標,但是,在未設置的情況下,在 MacOS 中,會變成輸入特殊字符。 普通鍵盤上是 alt b 和 alt f ,只是叫法不…

Android bindservice綁定服務,并同步返回service對象的兩個方法

先上一段代碼: private IDeviceService deviceService null; private ServiceConnection connnull; private synchronized void bindyourservice() { Intent intent new Intent();intent.setPackage("servicepackagename");intent.setAction("…

Go語言之空接口與類型斷言

Go 語言中,接口是一種強大的抽象機制。其中,空接口(interface{})和類型斷言為我們提供了處理任意類型與類型檢查的能力。 一、空接口(interface{}) 空接口是 Go 中最特殊的接口:不包含任何方法…

三、OrcaSlicer預設顯示

一、界面類 主框架使用的是wxWidgets庫;3D模型的渲染區的控件,使用的是imgui庫。 1、Plater 此類在OrcaSlicer\src\slic3r\GUI\Plater.hpp文件中定義 1.1 Plater::priv 此結構體是Plater的數據類,各種數據的對象和指針保存在此結構體中。如…

00 QEMU源碼中文注釋與架構講解

QEMU源碼中文注釋與架構講解 先占坑:等后續完善后再更新此文章 注釋作者將狼才鯨創建日期2025-05-30更新日期NULL CSDN閱讀地址:00 QEMU源碼中文注釋與架構講解Gitee源碼倉庫地址:才鯨嵌入式/qemu 一、前言 參考網址 QEMU 源碼目錄簡介qe…

一、Sqoop歷史發展及原理

作者:IvanCodes 日期:2025年5月30日 專欄:Sqoop教程 在大數據時代,數據往往分散存儲在各種不同類型的系統中。其中,傳統的關系型數據庫 (RDBMS) 如 MySQL, Oracle, PostgreSQL 等,仍然承載著大量的關鍵業務…

【Halcon】圖像分割中的 regiongrowing 與dyn_threshold 動態閾值 算法詳解對比

圖像分割中的 regiongrowing 與動態閾值算法詳解對比 在使用 HALCON 進行圖像處理時,圖像分割是最常見也最關鍵的操作之一。本文將深入講解 regiongrowing 算子的原理與使用方法,并與另一常見方法——動態閾值 (dyn_threshold) 進行詳細對比&#xff0c…

Docker部署項目無法訪問,登錄超時完整排查攻略

項目背景:遷移前后端應用,prod環境要求保留443端口,開發環境37800端口,后端容器端口為8000,前端為80,fastAPI對外端口為41000 生產環境部署在VM01,開發環境部署在VM03,在VM01配置nginx轉發 [r…

充電便捷,新能源汽車移動充電服務如何預約充電

隨著新能源汽車的普及,充電便捷性成為影響用戶體驗的關鍵因素之一。傳統的固定充電樁受限于地理位置和數量,難以完全滿足用戶需求,而移動充電服務的出現,為車主提供了更加靈活的補能方式。通過手機APP、小程序或在線平臺&#xff…

探索C++標準模板庫(STL):從容器到底層奧秘-全面解析String類高效技巧(上篇)

前引:在現代軟件開發中,字符串處理是幾乎所有程序的核心需求之一。無論是文本解析、網絡通信,還是用戶交互,高效且安全的字符串操作能力直接決定了代碼的質量與可維護性。而C標準模板庫(Standard Template Library, ST…

Python爬蟲實戰:抓取百度15天天氣預報數據

🌐 編程基礎第一期《9-30》–使用python中的第三方模塊requests,和三個內置模塊(re、json、pprint),實現百度地圖的近15天天氣信息抓取 記得安裝 pip install requests📑 項目介紹 網絡爬蟲是Python最受歡迎的應用場景之一&…

HTML常見事件詳解:從入門到實戰應用

前言 在Web開發中,事件是用戶與網頁交互的核心機制。HTML事件讓我們能夠響應用戶的各種操作,如點擊、鼠標移動、鍵盤輸入等。掌握HTML事件是前端開發的基礎技能之一,本文將深入探討HTML中的常見事件類型及其實際應用。 HTML事件概覽總結 H…

模具制造業數字化轉型:精密模塑,以數字之力鑄就制造基石

模具被譽為 “工業之母”,是制造業的重要基石,其精度直接決定了工業產品的質量與性能。在工業制造向高精度、智能化發展的當下,《模具制造業數字化轉型:精密模塑,以數字之力鑄就制造基石》這一主題,精準點明…

深度解讀漏洞掃描:原理、類型與應用實踐

在網絡安全領域,漏洞就像隱藏在系統中的定時炸彈,隨時可能被攻擊者利用,導致數據泄露、服務癱瘓等嚴重后果。而漏洞掃描作為發現這些潛在威脅的 “偵察兵”,是保障網絡安全的重要防線。本文將全面介紹漏洞掃描的相關知識&#xff…

[HNCTF 2022 Week1]silly_zip

下載附件 解壓發現需要密碼 用010打開看看,發現是偽加密 改成00點擊保存 解壓后得到圖片 感覺圖片看著怪怪的,修改一下高度看看有沒有其他線索 把47改成78 最后得到flag