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 <Flutter/Flutter.h>#import <UIKit/UIKit.h>@interface AppDelegate : FlutterAppDelegate@end
// AppDelegate.m#include "AppDelegate.h"#include "GeneratedPluginRegistrant.h"#include "FlutterDownloaderPlugin.h"@implementation AppDelegatevoid registerPlugins(NSObject<FlutterPluginRegistry>* 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];
}@EndeOder 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: Registry.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 Domäne: (Fügen Sie den folgenden Code zu Ihrer Info.plist Datei hinzu)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>www.yourserver.com</key>
<dict> <!-- Fügen Sie diesen Schlüssel hinzu, um Subdomains wie sub.yourserver.com --> zu aktivieren
<key>NSIncludesSubdomains</key>
<true/> <!-- Fügen Sie diesen Schlüssel hinzu, um Standard-HTTP-Anfragen zuzulassen und so den ATS zu negieren -->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/> <!-- Fügen Sie diesen Schlüssel hinzu, um die minimal zu akzeptierende TLS-Version anzugeben -->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict> Deaktivieren Sie ATS vollständig. Fügen Sie Ihrer Info.plist Datei Folgendes hinzu:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict> 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.
<!-- ändert diese Zahl, um die maximale Anzahl gleichzeitiger Aufgaben zu konfigurieren --><key>FDMaximumConcurrentTasks</key> <integer>5</integer>
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)
<key>FDAllFilesDownloadedMessage</key> <string>Alle Dateien wurden heruntergeladen</string>
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:
<provider android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider" android:authorities="${applicationId}.flutter_downloader.provider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/>
</provider>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:
<!-- FlutterDownloader-Anpassung beginnen --><!-- Standardinitialisierer deaktivieren --><provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported ="false" tools:node="merge">
<meta-data android:name="androidx.work.WorkManagerInitializer" android:value="androidx.startup" tools:node="remove" />
</provider><!-- benutzerdefinierten Initialisierer deklarieren --><provider android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer" android:authorities="${applicationId}.flutter-downloader-init" android:exported=" false"> <!-- ändert diese Zahl, um die maximale Anzahl gleichzeitiger Aufgaben zu konfigurieren -->
<meta-data android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS" android:value="5" />
</provider><!-- FlutterDownloader-Anpassung beenden -->Sie können Texte in Download-Fortschrittsbenachrichtigungen lokalisieren, indem Sie die folgenden Nachrichten lokalisieren.
<string name="flutter_downloader_notification_started">Download gestartet</string> <string name="flutter_downloader_notification_in_progress">Download läuft</string> <string name="flutter_downloader_notification_canceled">Download abgebrochen</string> <string name="flutter_downloader_notification_failed">Download fehlgeschlagen</string> <string name="flutter_downloader_notification_complete">Download abgeschlossen</string> <string name="flutter_downloader_notification_paused">Download pausiert</string>
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:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
Siehe auch:
Beheben Sie den Cleartext-Traffic-Fehler 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 flutter_downloader Plugin 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 , „fortsetzbar“ 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!