flutter_omni_downloader 0.1.0 copy "flutter_omni_downloader: ^0.1.0" to clipboard
flutter_omni_downloader: ^0.1.0 copied to clipboard

Request-aware Flutter downloader with resumable transfers and background support.

flutter_omni_downloader #

Request-aware Flutter downloader with resumable transfers, progress streams, and background-capable native implementations for Android and iOS.

Overview #

flutter_omni_downloader is built for downloads that start from more than a plain file URL. It uses the published flutter_universal_downloader_* federated packages under the hood while exposing a new app-facing package name.

Supported platforms #

  • Android: background downloads, foreground notifications, pause and resume
  • iOS: background downloads with URLSession

Features #

  • direct file downloads and API-triggered downloads
  • GET, POST, and PUT
  • custom headers, params, and request bodies
  • resumable transfers for large files
  • streamed progress updates with bytes and speed
  • Android WorkManager integration with foreground service notifications
  • iOS background session support

Installation #

dependencies:
  flutter_omni_downloader: ^0.1.0

Then run:

flutter pub get

Android setup #

Add the permissions your host app needs in android/app/src/main/AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

If you save to legacy external storage on older Android versions, request the appropriate storage permission in the host app as well.

Quick start #

import 'package:flutter_omni_downloader/flutter_omni_downloader.dart';

final taskId = await UniversalDownloader.start(
  DownloadRequest(
    url: 'https://api.example.com/reports/export',
    method: HttpMethod.post,
    headers: <String, String>{
      'Authorization': 'Bearer <token>',
      'Content-Type': 'application/json',
    },
    params: <String, dynamic>{'format': 'pdf'},
    body: <String, dynamic>{'range': 'last_30_days'},
    fileName: 'report.pdf',
    enableResume: true,
    enableBackground: true,
    showNotification: true,
  ),
);

UniversalDownloader.progressStream.listen((progress) {
  print(
    '[${progress.taskId}] ${progress.status.name} '
    '${progress.progress}% '
    '${progress.speed.toStringAsFixed(2)} MB/s',
  );
});

Pause, resume, and cancel #

await UniversalDownloader.pause(taskId);
await UniversalDownloader.resume(taskId);
await UniversalDownloader.cancel(taskId);

DownloadRequest #

const request = DownloadRequest(
  url: 'https://example.com/archive.zip',
  method: HttpMethod.get,
  headers: <String, String>{'Accept': '*/*'},
  params: <String, dynamic>{'source': 'mobile'},
  body: null,
  fileName: 'archive.zip',
  saveDir: null,
  enableResume: true,
  enableBackground: true,
  showNotification: true,
);

Progress stream payload #

Each DownloadProgress event contains:

  • taskId
  • progress
  • downloadedBytes
  • totalBytes
  • speed
  • status

Available statuses:

  • queued
  • downloading
  • paused
  • completed
  • failed

API reference #

  • UniversalDownloader.start(DownloadRequest request) returns the task id
  • UniversalDownloader.pause(String taskId) pauses an active task
  • UniversalDownloader.resume(String taskId) resumes a paused task
  • UniversalDownloader.cancel(String taskId) cancels and removes task state
  • UniversalDownloader.progressStream emits DownloadProgress updates

Example #

See example/lib/main.dart for a runnable sample with:

  • URL input
  • optional bearer token support
  • live progress UI
  • pause, resume, and cancel controls

Troubleshooting #

Download does not start on Android #

  • confirm the host app has internet and foreground-service permissions
  • request notification permission on Android 13+ if you expect visible notifications

Progress does not update #

  • make sure you keep a live subscription to UniversalDownloader.progressStream
  • verify the native side is receiving the request and not failing immediately

Resume does not work with a specific server #

  • some servers do not support range requests consistently
  • in those cases the native implementation may restart from byte 0

Repository #

This package is part of the federated workspace in this repository. The root README documents the workspace structure and implementation split.