Ein Plugin zum Erstellen und Verwalten von Download-Aufgaben. Unterstützt iOS und Android.
Dieses Plugin verwendet WorkManager
auf Android und NSURLSessionDownloadTask
auf iOS, um Download-Aufgaben im Hintergrund auszuführen.
Die Änderungen der externen Speicher-APIs in Android 11 verursachen einige Probleme bei der aktuellen Implementierung. Ich beschließe, dieses Plugin mit einer neuen Strategie zur Verwaltung des Speicherorts der Download-Dateien neu zu gestalten. Es befindet sich in dieser PR noch in der Triage und Diskussion. Wir freuen uns sehr über den Beitrag und das Feedback des Flutter-Entwicklers, um ein besseres Design für das Plugin zu erhalten.
In früheren Versionen dieses Pakets gab es bekannte Schwachstellen im Zusammenhang mit der SQL-Injection. SQL-Injection ist eine Art Sicherheitslücke, die es böswilligen Benutzern ermöglichen kann, von einer Anwendung ausgeführte SQL-Abfragen zu manipulieren, was möglicherweise zu unbefugtem Zugriff oder Manipulation der Datenbank führt.
Es wird dringend empfohlen, ein Upgrade auf die neueste Version dieses Pakets durchzuführen, um sicherzustellen, dass Ihre Anwendung keinen SQL-Injection-Schwachstellen ausgesetzt ist. Die neueste Version enthält die notwendigen Sicherheitsverbesserungen und Patches, um solche Risiken zu mindern.
Die folgenden Schritte erfordern das Öffnen Ihres ios
Projekts in Xcode.
Hintergrundmodus aktivieren.
sqlite
Bibliothek hinzufügen.
AppDelegate
konfigurieren:
Ziel-C:
/// AppDelegate.h#import#import @interface AppDelegate : FlutterAppDelegate@end
// AppDelegate.m#include "AppDelegate.h"#include "GeneratedPluginRegistrant.h"#include "FlutterDownloaderPlugin.h"@implementation AppDelegatevoid registerPlugins(NSObject* Registry) { if (![registry hasPlugin:@"FlutterDownloaderPlugin" ]) { [FlutterDownloaderPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterDownloaderPlugin"]]; } } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; [FlutterDownloaderPlugin setPluginRegistrantCallback:registerPlugins]; // Überschreibungspunkt für die Anpassung nach dem Anwendungsstart. return [super application:application didFinishLaunchingWithOptions:launchOptions]; }@Ende
Oder Swift:
UIKit importieren Flutter importieren import flutter_downloader@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate { override func application( _Anwendung: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) FlutterDownloaderPlugin.setPluginRegistrantCallback(registerPlugins) return super.application(application, didFinishLaunchingWithOptions: launchOptions) }}private func registerPlugins(registry: FlutterPluginRegistry) { if (!registry.hasPlugin("FlutterDownloaderPlugin")) { FlutterDownloaderPlugin.register(with: register.registrar(forPlugin: "FlutterDownloaderPlugin")!) }}
HTTP-Anfrage unterstützen: Wenn Sie eine Datei mit einer HTTP-Anfrage herunterladen möchten, müssen Sie die Apple Transport Security (ATS)-Funktion deaktivieren. Es gibt zwei Möglichkeiten:
Deaktivieren Sie ATS nur für eine bestimmte Domain: (Fügen Sie den folgenden Code zu Ihrer Info.plist
Datei hinzu)
NSAppTransportSecurity NSExceptionDomains www.yourserver.com zu aktivieren NSIncludesSubdomains NSTemporaryExceptionAllowsInsecureHTTPLoads NSTemporaryExceptionMinimumTLSVersion TLSv1.1
Deaktivieren Sie ATS vollständig. Fügen Sie Ihrer Info.plist
Datei Folgendes hinzu:
NSAppTransportSecurity NSAllowsArbitraryLoads
Konfigurieren Sie die maximale Anzahl gleichzeitiger Aufgaben: Das Plugin lässt standardmäßig zu, dass drei Download-Aufgaben gleichzeitig ausgeführt werden (wenn Sie mehr als drei Aufgaben in die Warteschlange stellen, werden nur drei Aufgaben ausgeführt, andere Aufgaben werden in den Status „Ausstehend“ versetzt). Sie können diese Nummer ändern, indem Sie den folgenden Code zu Ihrer Info.plist
Datei hinzufügen.
FDMaximumConcurrentTasks 5
Benachrichtigungsmeldungen lokalisieren: Das Plugin sendet eine Benachrichtigung, um den Benutzer zu benachrichtigen, falls alle Dateien heruntergeladen werden, während Ihre Anwendung nicht im Vordergrund ausgeführt wird. Diese Nachricht ist standardmäßig auf Englisch. Sie können diese Nachricht lokalisieren, indem Sie die folgende Nachricht in der Datei Info.plist
hinzufügen und lokalisieren. (Details zur Info.plist
Lokalisierung finden Sie unter diesem Link)
FDAllFilesDownloadedMessage Alle Dateien wurden heruntergeladen
Notiz:
Dieses Plugin unterstützt nur das Speichern von Dateien in NSDocumentDirectory
Sie müssen nichts weiter tun, damit das Plugin auf Android funktioniert.
Es gibt jedoch einige optionale Einstellungen, die Sie möglicherweise konfigurieren möchten.
Damit das Tippen auf die Benachrichtigung die heruntergeladene Datei auf Android öffnet, fügen Sie den folgenden Code zu AndroidManifest.xml
hinzu:
Notizen
Sie müssen Ihre heruntergeladenen Dateien in einem externen Speicher speichern (wo die anderen Anwendungen die Berechtigung haben, Ihre Dateien zu lesen).
Die heruntergeladenen Dateien können nur geöffnet werden, wenn Ihr Gerät über mindestens eine Anwendung verfügt, die diese Dateitypen (mp3, pdf usw.) lesen kann.
Das Plugin hängt von WorkManager
-Bibliothek ab und WorkManager
hängt von der Anzahl der verfügbaren Prozessoren ab, um die maximale Anzahl gleichzeitig ausgeführter Aufgaben zu konfigurieren. Sie können eine feste Nummer für diese Konfiguration einrichten, indem Sie den folgenden Code zu Ihrer AndroidManifest.xml
hinzufügen:
Sie können Texte in Download-Fortschrittsbenachrichtigungen lokalisieren, indem Sie die folgenden Nachrichten lokalisieren.
Download gestartet Download läuft Download abgebrochen Download fehlgeschlagen Download abgeschlossen Download pausiert
Weitere Informationen zur Lokalisierung auf Android finden Sie hier.
Zum Öffnen und Installieren .apk
Dateien benötigt Ihre Anwendung die Berechtigung REQUEST_INSTALL_PACKAGES
. Fügen Sie Folgendes in Ihre AndroidManifest.xml
ein:
Siehe auch:
Behebung des Cleartext-Traffic-Fehlers auf Android 9 Pie
import 'package:flutter_downloader/flutter_downloader.dart';void main() { WidgetsFlutterBinding.ensureInitialized(); // Das Plugin muss vor der Verwendung initialisiert werden.await FlutterDownloader.initialize( debug: true, // optional: auf false setzen, um das Drucken von Protokollen auf der Konsole zu deaktivieren (Standard: true) ignoreSsl: true // Option: auf false setzen, um die Arbeit mit http-Links zu deaktivieren (Standard: false) ); runApp(/*...*/) }
final taskId = waiting FlutterDownloader.enqueue( URL: „Ihr Download-Link“, Header: {}, // optional: Header mit URL senden (Authentifizierungstoken usw.) savedDir: 'der Pfad des Verzeichnisses, in dem Sie heruntergeladene Dateien speichern möchten', showNotification: true, // Download-Fortschritt in der Statusleiste anzeigen (für Android) openFileFromNotification: true, // auf Benachrichtigung klicken, um heruntergeladene Datei zu öffnen (für Android));
Warten Sie auf FlutterDownloader.registerCallback(callback); // Callback ist eine Top-Level- oder statische Funktion
Wichtig
Die Benutzeroberfläche wird auf dem Hauptisolat gerendert, während Download-Ereignisse vom Hintergrundisolat stammen (mit anderen Worten: Code im callback
wird im Hintergrundisolat ausgeführt), sodass Sie sich um die Kommunikation zwischen zwei Isolaten kümmern müssen. Zum Beispiel:
ReceivePort _port = ReceivePort();@overridevoid initState() { super.initState(); IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port'); _port.listen((dynamic data) { String id = data[0]; DownloadTaskStatus status = DownloadTaskStatus(data[1]); int progress = data[2]; setState((){ }); }); FlutterDownloader.registerCallback(downloadCallback); }@overridevoid dispose() { IsolateNameServer.removePortNameMapping('downloader_send_port'); super.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, status, progress]); }
@pragma('vm:entry-point')
muss über der callback
-Funktion platziert werden, um Tree Shaking im Release-Modus für Android zu vermeiden.
letzte Aufgaben = Warten auf FlutterDownloader.loadTasks();
letzte Aufgaben = Warten auf FlutterDownloader.loadTasksWithRawQuery(query: query);
Um Daten erfolgreich in DownloadTask
-Objekt zu analysieren, sollten Sie Daten mit allen Feldern aus der Datenbank laden (mit anderen Worten, verwenden Sie SELECT *
). Zum Beispiel:
SELECT * FROM task WHERE status=3
Unten finden Sie das Schema der task
, in der das Plugin flutter_downloader
Informationen zu Download-Aufgaben speichert
CREATE TABLE `task` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `task_id` VARCHAR ( 256 ), `url` TEXT, `status` INTEGER DEFAULT 0, `progress` INTEGER DEFAULT 0, `file_name` TEXT, `saved_dir` TEXT , „resumable“ TINYINT DEFAULT 0, „headers“ TEXT, „show_notification“ TINYINT DEFAULT 0, „open_file_from_notification“ TINYINT DEFAULT 0, „time_created“ INTEGER DEFAULT 0);
FlutterDownloader.cancel(taskId: taskId);
FlutterDownloader.cancelAll();
FlutterDownloader.pause(taskId: taskId);
FlutterDownloader.resume(taskId: taskId);
resume()
gibt eine neue taskId
zurück, die einer neuen Hintergrundaufgabe entspricht, die erstellt wird, um den Downloadvorgang fortzusetzen. Sie sollten die alte taskId
(die den Status „ paused
hat) durch die neue taskId
ersetzen, um den Download-Fortschritt weiterhin verfolgen zu können.
FlutterDownloader.retry(taskId: taskId);
retry()
gibt eine neue taskId
zurück (genau wie resume()
).
FlutterDownloader.remove(taskId: taskId, ShouldDeleteContent:false);
FlutterDownloader.open(taskId: taskId);
Unter Android können Sie eine heruntergeladene Datei nur öffnen, wenn sie im externen Speicher abgelegt ist und es mindestens eine Anwendung auf Ihrem Gerät gibt, die diesen Dateityp lesen kann.
Wenn Sie auf Probleme stoßen oder der Meinung sind, dass dem Plugin eine Funktion fehlt, können Sie jederzeit ein Problem eröffnen.
Auch Pull-Anfragen sind herzlich willkommen!