用於建立和管理下載任務的插件。支援 iOS 和 Android。
該外掛程式在 Android 上使用WorkManager
,在 iOS 上使用NSURLSessionDownloadTask
在背景執行下載任務。
Android 11 中外部儲存 API 的變更導致目前實作出現一些問題。我決定使用新策略重新設計這個外掛程式來管理下載檔案位置。本 PR 中仍在分類和討論中。非常感謝 Flutter 開發人員的貢獻和回饋,以獲得更好的插件設計。
在此軟體包的早期版本中,存在與 SQL 注入相關的已知漏洞。 SQL 注入是一種安全漏洞,可讓惡意使用者操縱應用程式執行的 SQL 查詢,從而可能導致未經授權的存取或操縱資料庫。
強烈建議升級到該軟體包的最新版本,以確保您的應用程式不會受到 SQL 注入漏洞的影響。最新版本包含必要的安全性改進和修補程式來減輕此類風險。
以下步驟需要在 Xcode 中開啟您的ios
專案。
啟用後台模式。
新增sqlite
庫。
配置AppDelegate
:
Objective-C:
/// AppDelegate.h#import#import @interface AppDelegate : FlutterAppDelegate@end
// AppDelegate.m#include "AppDelegate.h"#include "GeneratePluginRegistrant.h"#include "FlutterDownloaderPlugin.h"@implementation AppDelegatevoid registerPlugins(NSd]) { [FlutterDownloaderPlugin registerWithRegistrar:[註冊表registrarForPlugin:@"FlutterDownloaderPlugin"]]; } } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratePluginRegistrant registerWithRegistry:self]; [FlutterDownloaderPlugin setPluginRegistrantCallback:registerPlugins]; // 應用程式啟動後覆蓋自訂點。 返回[超級應用程式:應用程式didFinishLaunchingWithOptions:launchOptions]; }@結尾
或者斯威夫特:
導入 UIKit 導入顫振 導入 flutter_downloader@UIApplicationMain@objc 類別 AppDelegate: FlutterAppDelegate { 覆寫 func application( _ 應用程式:UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplication.LaunchOptionsKey:任何]? ) -> Bool { generatedPluginRegistrant.register(with: self) FlutterDownloaderPlugin.setPluginRegistrantCallback(registerPlugins) return super.application(application, didFinishLaunchingWithOptions: launchunchOpti. if (!registry.hasPlugin("FlutterDownloaderPlugin")) { FlutterDownloaderPlugin.register(with:registry.registrar(forPlugin: "FlutterDownloaderPlugin")!) }}
支援 HTTP 請求:如果要使用 HTTP 請求下載文件,則需要停用 Apple Transport Security (ATS) 功能。有兩個選擇:
僅針對特定網域停用 ATS:(將以下程式碼新增至您的Info.plist
檔案中)
NSAppTransportSecurity <字典>NSExceptionDomains <字典>www.yourserver.com NSincludesSubdomains NSTemporaryExceptionAllowsInsecureHTTPLoads NSTemporaryExceptionMinimumTLSVersion <字串>TLSv1.1字串> 字典> 字典> 字典>
完全禁用 ATS。將以下內容新增至您的Info.plist
檔案中)
NSAppTransportSecurity <字典>NSAllowsArbitraryLoads 字典>
配置最大並發任務數:外掛程式預設允許同時執行 3 個下載任務(如果入隊的任務超過 3 個,則只有 3 個任務在運行,其他任務處於掛起狀態)。您可以將以下程式碼新增至Info.plist
檔案來變更此數字。
FDMaximumConcurrentTasks <整數>5整數>
本地化通知訊息:如果應用程式未在前台運行時所有檔案都已下載,則外掛程式將發送通知訊息來通知使用者。該訊息預設為英文。您可以透過在Info.plist
檔案中新增和本地化以下訊息來本地化此訊息。 (您可以在此連結中找到Info.plist
本地化的詳細資訊)
FDAllFilesDownloadedMessage 所有檔案已下載
筆記:
該外掛僅支援將文件保存在NSDocumentDirectory
中
您無需執行任何額外操作即可使該插件在 Android 上運行。
您可能需要配置一些可選設定。
若要讓點擊通知在 Android 上開啟下載的文件,請將以下程式碼新增至AndroidManifest.xml
:
<元資料 android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> 提供者>
筆記
您必須將下載的檔案保存在外部儲存中(其他應用程式有權讀取您的檔案)
只有當您的裝置至少有一個可以讀取這些文件類型(mp3、pdf 等)的應用程式時,才能開啟下載的文件
該插件依賴WorkManager
庫,而WorkManager
依賴可用處理器的數量來配置同時運行的最大任務數。您可以將以下程式碼新增至AndroidManifest.xml
來為此配置設定固定數量:
<元資料 android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS" android:value="5" />
您可以透過本地化以下訊息來本地化下載進度通知中的文字。
下載已開始 正在下載 下載已取消 下載失敗 下載完成 下載已暫停
您可以在此處了解有關 Android 本地化的更多資訊。
要開啟並安裝.apk
文件,您的應用程式需要REQUEST_INSTALL_PACKAGES
權限。在AndroidManifest.xml
中加入以下內容:
參見:
修正 Android 9 Pie 上的明文流量錯誤
導入 'package:flutter_downloader/flutter_downloader.dart';void main() { WidgetsFlutterBinding.ensureInitialized(); // 使用之前必須初始化外掛程式await FlutterDownloader.initialize( debug: true, // 可選:設定為 false 以停用將日誌印到控制台(預設值:true) ignoreSsl: true // 選項:設定為 false 以停用 http 連結(預設值: false) ); 運行應用程式(/*...*/) }
最終任務Id =等待FlutterDownloader.enqueue( url: '您的下載連結', headers: {}, // 可選:使用 url(驗證令牌等)傳送標頭 saveDir: '要儲存下載檔案的目錄路徑', showNotification: true, // 在狀態列中顯示下載進度(適用於 Android) openFileFromNotification: true, // 點選通知開啟下載的檔案(適用於 Android);
等待 FlutterDownloader.registerCallback(回呼); // 回呼是頂層函數或靜態函數
重要的
UI在主isolate上渲染,而下載事件來自後台isolate(換句話說, callback
中的程式碼在後台isolate中運行),因此您必須處理兩個isolate之間的通訊。例如:
ReceivePort _port = ReceivePort();@overridevoid initState() { super.initState(); IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port'); _port.listen((動態資料) { String id = data[0]; DownloadTaskStatus status = DownloadTaskStatus(data[1]); int Progress = data[2]; setState((){ }); }); FlutterDownloader.registerCallback(downloadCallback); }@overridevoid dispose() { IsolateNameServer.removePortNameMapping('downloader_send_port'); 超級.dispose(); }@pragma('vm:entry-point')static void downloadCallback(String id, int status, int Progress) { Final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port'); send.send([id, 狀態, 進度]); }
@pragma('vm:entry-point')
必須放置在callback
函數上方,以避免 Android 發布模式下的樹抖動。
最終任務=等待FlutterDownloader.loadTasks();
最終任務=等待FlutterDownloader.loadTasksWithRawQuery(query: query);
為了成功將資料解析為DownloadTask
對象,您應該從資料庫中載入包含所有欄位的資料(換句話說,使用SELECT *
)。例如:
SELECT * FROM 任務 WHERE status=3
下面是task
表的架構, flutter_downloader
程式儲存有關下載任務的信息
建立表格 `task` ( `id` INTEGER PRIMARY KEY AUTOINCRMENT, `task_id` VARCHAR ( 256 ), `url` TEXT, `status` INTEGER DEFAULT 0, `progress` INTEGER DEFAULT 0`XT, nameUL 、`可恢復` TINYINT 預設值0、`headers` 文字、`show_notification` TINYINT 預設值0、`open_file_from_notification` TINYINT 預設值0、`time_created` INTEGER 預設值0);
FlutterDownloader.cancel(taskId: taskId);
FlutterDownloader.cancelAll();
FlutterDownloader.pause(taskId:taskId);
FlutterDownloader.resume(taskId: taskId);
resume()
將傳回新的taskId
該任務 ID 對應於為繼續下載程序而建立的新背景任務。您應該用新的taskId
替換舊的taskId
(已paused
狀態)以繼續追蹤下載進度。
FlutterDownloader.retry(taskId: taskId);
retry()
將會傳回一個新的taskId
(就像resume()
一樣)
FlutterDownloader.remove(taskId: taskId, shouldDeleteContent:false);
FlutterDownloader.open(taskId: taskId);
在 Android 上,您只能打開位於外部儲存中的下載文件,而且裝置上至少有一個應用程式可以讀取該文件類型。
如果您遇到任何問題或認為該插件缺少某些功能,請隨時提出問題。
也非常歡迎請求請求!