다운로드 작업을 생성하고 관리하기 위한 플러그인입니다. iOS와 안드로이드를 지원합니다.
이 플러그인은 Android의 WorkManager
와 iOS의 NSURLSessionDownloadTask
사용하여 백그라운드에서 다운로드 작업을 실행합니다.
Android 11의 외부 저장소 API 변경으로 인해 현재 구현에 몇 가지 문제가 발생합니다. 나는 다운로드 파일 위치를 관리하기 위한 새로운 전략으로 이 플러그인을 다시 디자인하기로 결정했습니다. 이 PR에서는 아직 분류 및 논의 중입니다. 더 나은 플러그인 디자인을 얻기 위해 Flutter 개발자의 기여와 피드백을 받아주셔서 매우 감사드립니다.
이 패키지의 이전 버전에는 SQL 삽입과 관련된 알려진 취약점이 있었습니다. SQL 주입은 악의적인 사용자가 애플리케이션에서 실행되는 SQL 쿼리를 조작할 수 있도록 허용하여 잠재적으로 데이터베이스에 대한 무단 액세스 또는 조작을 초래할 수 있는 일종의 보안 취약점입니다.
애플리케이션이 SQL 주입 취약점에 노출되지 않도록 하려면 이 패키지의 최신 버전으로 업그레이드하는 것이 좋습니다. 최신 버전에는 이러한 위험을 완화하는 데 필요한 보안 개선 사항과 패치가 포함되어 있습니다.
다음 단계에서는 Xcode에서 ios
프로젝트를 열어야 합니다.
백그라운드 모드를 활성화합니다.
sqlite
라이브러리를 추가합니다.
AppDelegate
구성:
목표-C:
/// AppDelegate.h#import#import @interface AppDelegate : FlutterAppDelegate@end
// AppDelegate.m#include "AppDelegate.h"#include "GeneratedPluginRegistrant.h"#include "FlutterDownloaderPlugin.h"@implementation AppDelegatevoidregisterPlugins(NSObject* Registry) { if (![registry hasPlugin:@"FlutterDownloaderPlugin" ]) { [FlutterDownloaderPlugin RegisterWithRegistrar:[registry registrarForPlugin:@"FlutterDownloaderPlugin"]]; } } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant RegisterWithRegistry:self]; [FlutterDownloaderPlugin setPluginRegistrantCallback:registerPlugins]; // 애플리케이션 실행 후 사용자 정의를 위해 지점을 재정의합니다. return [슈퍼 애플리케이션:application didFinishLaunchingWithOptions:launchOptions]; }@끝
또는 스위프트:
UIKit 가져오기 Flutter 가져오기 import flutter_downloader@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate { func 애플리케이션 재정의( _ 애플리케이션: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 모두]? ) -> Bool { 생성된PluginRegistrant.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 요청으로 파일을 다운로드하려면 ATS(Apple Transport Security) 기능을 비활성화해야 합니다. 두 가지 옵션이 있습니다.
특정 도메인에 대해서만 ATS를 비활성화합니다. ( Info.plist
파일에 다음 코드 추가)
NSAppTransport보안 <딕셔너리>NSExceptionDomains <딕셔너리>www.yourserver.com NSIncludesSubdomains NSTemporaryExceptionAllowsInsecureHTTPLoads NSTemporaryExceptionMinimumTLSVersion TLSv1.1
ATS를 완전히 비활성화합니다. Info.plist
파일에 다음을 추가하세요)
NSAppTransport보안 <딕셔너리>NSAllowsArbitraryLoads
최대 동시 작업 수 구성: 플러그인은 기본적으로 한 번에 3개의 다운로드 작업 실행을 허용합니다(3개 이상의 작업을 대기열에 추가하면 3개의 작업만 실행되고 다른 작업은 보류 상태가 됩니다). Info.plist
파일에 다음 코드를 추가하여 이 번호를 변경할 수 있습니다.
FDMaximumConcurrentTasks 5
알림 메시지 현지화: 플러그인은 애플리케이션이 포그라운드에서 실행되지 않는 동안 모든 파일이 다운로드되는 경우 사용자에게 알리기 위해 알림 메시지를 보냅니다. 이 메시지는 기본적으로 영어입니다. Info.plist
파일에 다음 메시지를 추가하고 현지화하여 이 메시지를 현지화할 수 있습니다. (이 링크에서 Info.plist
현지화에 대한 자세한 내용을 확인할 수 있습니다)
FDAllFilesDownloadedMessage 모든 파일이 다운로드되었습니다
메모:
이 플러그인은 NSDocumentDirectory
의 저장 파일만 지원합니다.
Android에서 플러그인이 작동하도록 하기 위해 추가로 수행할 작업은 없습니다.
구성할 수 있는 몇 가지 선택적 설정이 있습니다.
알림을 탭하여 Android에서 다운로드한 파일을 열려면 AndroidManifest.xml
에 다음 코드를 추가하세요.
공급자>
메모
다운로드한 파일을 외부 저장소에 저장해야 합니다(다른 응용 프로그램이 파일을 읽을 수 있는 권한이 있는 경우).
다운로드한 파일은 장치에 이러한 파일 형식(mp3, pdf 등)을 읽을 수 있는 응용 프로그램이 하나 이상 있는 경우에만 열 수 있습니다.
플러그인은 WorkManager
라이브러리에 따라 달라지며 WorkManager
사용 가능한 프로세서 수에 따라 동시에 실행되는 최대 작업 수를 구성합니다. AndroidManifest.xml
에 다음 코드를 추가하여 이 구성에 대한 고정 숫자를 설정할 수 있습니다.
다음 메시지를 현지화하여 다운로드 진행률 알림의 텍스트를 현지화할 수 있습니다.
다운로드 시작됨 다운로드 진행 중 다운로드가 취소되었습니다 다운로드 실패 다운로드 완료 다운로드가 일시중지되었습니다
여기에서 Android의 현지화에 대해 자세히 알아볼 수 있습니다.
.apk
파일을 열고 설치하려면 애플리케이션에 REQUEST_INSTALL_PACKAGES
권한이 필요합니다. AndroidManifest.xml
에 다음을 추가합니다.
참조:
Android 9 Pie에서 일반 텍스트 트래픽 오류 수정
import 'package:flutter_downloader/flutter_downloader.dart';void main() { WidgetsFlutterBinding.ensureInitialized(); // Wait FlutterDownloader.initialize(를 사용하기 전에 플러그인을 초기화해야 합니다. debug: true, // 선택 사항: 로그를 콘솔에 인쇄하지 않으려면 false로 설정합니다(기본값: true). ignoreSsl: true // 옵션: http 링크 작업을 비활성화하려면 false로 설정합니다(기본값: false). ); 실행앱(/*...*/) }
최종 taskId = FlutterDownloader.enqueue( url: '다운로드 링크', headers: {}, // 선택사항: URL과 함께 헤더 전송(인증 토큰 등) saveDir: '다운로드한 파일을 저장하려는 디렉터리 경로', showNotification: true, // 상태 표시줄에 다운로드 진행률 표시(Android의 경우) openFileFromNotification: true, // 다운로드한 파일을 열려면 알림을 클릭하세요(Android의 경우));
FlutterDownloader.registerCallback(콜백)을 기다립니다. // 콜백은 최상위 또는 정적 함수입니다.
중요한
UI는 기본 격리에서 렌더링되는 반면 다운로드 이벤트는 백그라운드 격리에서 발생하므로(즉, callback
의 코드가 백그라운드 격리에서 실행됨) 두 격리 간의 통신을 처리해야 합니다. 예를 들어:
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'); 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
함수 위에 배치해야 합니다.
최종 작업 = FlutterDownloader.loadTasks()를 기다립니다.
최종 작업 = 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에서는 다운로드한 파일이 외부 저장소에 있고 장치에 해당 파일 형식을 읽을 수 있는 애플리케이션이 하나 이상 있는 경우에만 다운로드한 파일을 열 수 있습니다.
문제가 발생하거나 플러그인에 일부 기능이 없다고 생각되면 언제든지 문제를 열어주세요.
Pull Request도 매우 환영합니다!