ダウンロードタスクを作成および管理するためのプラグイン。 iOSとAndroidをサポートします。
このプラグインは、Android ではWorkManager
使用し、iOS ではNSURLSessionDownloadTask
使用して、バックグラウンドでダウンロード タスクを実行します。
Android 11 での外部ストレージ API の変更により、現在の実装にいくつかの問題が発生します。ダウンロード ファイルの場所を管理するための新しい戦略を使用してこのプラグインを再設計することにしました。この PR ではまだトリアージと議論が行われています。プラグインの設計を改善するために、Flutter 開発者からの貢献とフィードバックをいただければ幸いです。
このパッケージの以前のバージョンには、SQL インジェクションに関連する既知の脆弱性がありました。 SQL インジェクションはセキュリティ上の脆弱性の一種で、悪意のあるユーザーがアプリケーションによって実行される SQL クエリを操作できるようになり、データベースへの不正なアクセスや操作につながる可能性があります。
アプリケーションが SQL インジェクションの脆弱性にさらされないようにするために、このパッケージの最新バージョンにアップグレードすることを強くお勧めします。最新バージョンには、そのようなリスクを軽減するために必要なセキュリティの改善とパッチが含まれています。
次の手順では、Xcode でios
プロジェクトを開く必要があります。
バックグラウンドモードを有効にします。
sqlite
ライブラリを追加します。
AppDelegate
を構成します。
目標-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:[レジストリ registrarForPlugin:@"FlutterDownloaderPlugin"]]; } } - (BOOL)application:(UIApplication *)application DidFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; [FlutterDownloaderPlugin setPluginRegistrantCallback:registerPlugins]; // アプリケーションの起動後にカスタマイズするポイントをオーバーライドします。 return [スーパーアプリケーション:アプリケーションdFinishLaunchingWithOptions:launchOptions]; }@終わり
またはスウィフト:
UIKitをインポートする フラッターをインポートする import flutter_downloader@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate { override func application( _ アプリケーション: 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 リクエストのサポート: HTTP リクエストでファイルをダウンロードする場合は、Apple Transport Security (ATS) 機能を無効にする必要があります。オプションは 2 つあります。
特定のドメインに対してのみ ATS を無効にします: (次のコードをInfo.plist
ファイルに追加します)
<key>NSAppTransportSecurity</key> <辞書> <key>NSExceptionDomains</key> <辞書> <key>www.yourserver.com</key> <dict> <!-- このキーを追加して、sub.yourserver.com などのサブドメインを有効にします --> <key>NS サブドメインを含む</key> <true/> <!-- このキーを追加して標準の HTTP リクエストを許可し、ATS を無効にします --> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> <!-- このキーを追加して、受け入れる最小 TLS バージョンを指定します --> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> </dict> </dict> </dict>
ATSを完全に無効にします。以下をInfo.plist
ファイルに追加します)
<key>NSAppTransportSecurity</key> <辞書> <key>NSAllowsArbitraryLoads</key><true/> </dict>
同時タスクの最大数を構成します。プラグインでは、デフォルトで一度に 3 つのダウンロード タスクを実行できます (3 つを超えるタスクをキューに入れると、実行中のタスクは 3 つだけになり、他のタスクは保留状態になります)。この番号を変更するには、次のコードをInfo.plist
ファイルに追加します。
<!-- この数値を変更して同時タスクの最大数を構成します --><key>FDMinimumConcurrentTasks</key> <整数>5</整数>
通知メッセージのローカライズ:アプリケーションがフォアグラウンドで実行されていないときにすべてのファイルがダウンロードされた場合、プラグインは通知メッセージを送信してユーザーに通知します。このメッセージはデフォルトでは英語です。 Info.plist
ファイルに次のメッセージを追加してローカライズすることで、このメッセージをローカライズできます。 ( Info.plist
ローカリゼーションの詳細については、このリンクを参照してください)
<key>FDAllFilesDownloadedMessage</key> <string>すべてのファイルがダウンロードされました</string>
注記:
このプラグインはNSDocumentDirectory
内のファイルの保存のみをサポートします
プラグインを Android で動作させるために特別なことをする必要はありません。
ただし、構成する必要があるオプションの設定がいくつかあります。
通知をタップして Android 上でダウンロードしたファイルを開くようにするには、次のコードをAndroidManifest.xml
に追加します。
<プロバイダー android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider" android:authorities="${applicationId}.flutter_downloader.provider" android:exported="false" android:grantUriPermissions="true"> <メタデータ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> </プロバイダ>
注意事項
ダウンロードしたファイルは外部ストレージ (他のアプリケーションがファイルを読み取る権限を持っている場所) に保存する必要があります。
ダウンロードしたファイルは、デバイスにこれらのファイル タイプ (mp3、pdf など) を読み取ることができるアプリケーションが少なくとも 1 つある場合にのみ開くことができます。
プラグインはWorkManager
ライブラリに依存し、 WorkManager
利用可能なプロセッサの数に応じて、同時に実行されるタスクの最大数を構成します。次のコードをAndroidManifest.xml
に追加することで、この構成に固定数を設定できます。
<!-- FlutterDownloader のカスタマイズを開始します --><!-- デフォルトのイニシャライザを無効にします --><provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported ="false" ツール:node="merge"> <メタデータ android:name="androidx.work.WorkManagerInitializer" android:value="androidx.startup" tools:node="remove" /> </provider><!-- カスタマイズされたイニシャライザを宣言します --><provider android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer" android:authorities="${applicationId}.flutter-downloader-init" android:exported=" false"> <!-- この数値を変更して、同時タスクの最大数を構成します --> <メタデータ android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS" android:value="5" /> </provider><!-- FlutterDownloader のカスタマイズを終了します -->
次のメッセージをローカライズすることで、ダウンロード進行状況通知のテキストをローカライズできます。
<string name="flutter_downloader_notification_started">ダウンロードが開始されました</string> <string name="flutter_downloader_notification_in_progress">ダウンロードが進行中</string> <string name="flutter_downloader_notification_canceled">ダウンロードがキャンセルされました</string> <string name="flutter_downloader_notification_failed">ダウンロードに失敗しました</string> <string name="flutter_downloader_notification_complete">ダウンロードが完了しました</string> <string name="flutter_downloader_notification_paused">ダウンロードが一時停止されました</string>
Android でのローカリゼーションについて詳しくは、こちらをご覧ください。
.apk
ファイルを開いてインストールするには、アプリケーションにREQUEST_INSTALL_PACKAGES
権限が必要です。 AndroidManifest.xml
に以下を追加します。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
以下も参照してください。
Android 9 Pieのクリアテキストトラフィックエラーを修正
import 'package:flutter_downloader/flutter_downloader.dart';void main() { WidgetsFlutterBinding.ensureInitialized(); // await FlutterDownloader.initialize( を使用する前にプラグインを初期化する必要があります debug: true, // オプション: コンソールへのログの出力を無効にするには false に設定します (デフォルト: true) ignoreSsl: true // オプション: http リンクの操作を無効にするには false に設定します (デフォルト: false) ); runApp(/*...*/) }
Final taskId = await FlutterDownloader.enqueue( URL: 'ダウンロードリンク', headers: {}, // オプション: URL (認証トークンなど) とともに送信されるヘッダー SavedDir: 'ダウンロードしたファイルを保存するディレクトリのパス', showNotification: true, // ダウンロードの進行状況をステータスバーに表示します (Android の場合) openFileFromNotification: true, // 通知をクリックしてダウンロードしたファイルを開きます (Android の場合);
FlutterDownloader.registerCallback(callback); を待ちます。 // コールバックはトップレベル関数または静的関数です
重要
UI はメイン アイソレートでレンダリングされますが、ダウンロード イベントはバックグラウンド アイソレートから取得される (つまり、 callback
のコードはバックグラウンド アイソレートで実行される) ため、2 つのアイソレート間の通信を処理する必要があります。例えば:
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 destroy() { 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, ステータス, 進行状況]); }
Android のリリース モードでのツリーの揺れを避けるために、 @pragma('vm:entry-point')
callback
関数の上に配置する必要があります。
最終タスク = await FlutterDownloader.loadTasks();
最終タスク = await FlutterDownloader.loadTasksWithRawQuery(query: query);
データをDownloadTask
オブジェクトに正常に解析するには、すべてのフィールドを含むデータをデータベースからロードする必要があります (つまり、 SELECT *
を使用します)。例えば:
SELECT * FROM タスク WHERE ステータス=3
以下は、 flutter_downloader
プラグインがダウンロード タスクに関する情報を保存するtask
テーブルのスキーマです。
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 、「再開可能」 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()
ダウンロード プロセスを続行するために作成された新しいバックグラウンド タスクに対応する新しいtaskId
を返します。ダウンロードの進行状況を追跡し続けるには、古いtaskId
( paused
ステータスになっている) を新しいtaskId
に置き換える必要があります。
FlutterDownloader.retry(taskId: taskId);
retry()
新しいtaskId
返します ( resume()
と同様)
FlutterDownloader.remove(taskId: taskId, shouldDeleteContent:false);
FlutterDownloader.open(taskId: taskId);
Android では、ダウンロードしたファイルが外部ストレージに保存されており、デバイス上にそのファイル タイプを読み取ることができるアプリケーションが少なくとも 1 つある場合にのみ、そのファイルを開くことができます。
問題が発生した場合、またはプラグインに機能が欠けていると思われる場合は、お気軽に問題を開いてください。
プルリクエストも大歓迎です!