universal_downloader 1.0.2
universal_downloader: ^1.0.2 copied to clipboard
A Flutter package for downloading files on all platforms (Android, iOS, Web, Windows, macOS, Linux) with progress tracking and comprehensive error handling.
Universal Downloader #
A Flutter package for downloading files on all platforms: Android, iOS, Web, Windows, macOS, and Linux.
Supports ALL file types - PDFs, music, videos, documents, archives, images, and any other format without restrictions.
Features #
✅ Universal Compatibility: Works on all Flutter platforms
✅ All File Types Supported: PDFs, music, videos, documents, archives, images, and any format
✅ Progress Tracking: Real-time download progress callbacks
✅ Platform-Optimized Storage: Uses appropriate directories for each platform
✅ Automatic Permissions: Handles storage permissions for mobile platforms
✅ Error Handling: Comprehensive error reporting and recovery
✅ Simple API: Easy-to-use interface with intuitive callbacks
✅ Web Support: Browser-based downloads with enhanced CORS handling
✅ SSL Support: Bypass self-signed certificates on native platforms
✅ Type Safety: Full Dart type safety with comprehensive models
Platform-Specific Behavior #
| Platform | Storage Location | Progress Tracking | Notes |
|---|---|---|---|
| Android | Downloads/Documents directory | ✅ | Uses path_provider |
| iOS | Documents directory | ✅ | Uses path_provider |
| Web | Browser downloads | ✅ | Enhanced download with multiple strategies |
| Windows | Downloads folder | ✅ | Uses system Downloads directory |
| macOS | Downloads folder | ✅ | Uses system Downloads directory |
| Linux | Downloads folder | ✅ | Uses system Downloads directory |
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
universal_downloader: ^1.0.0
Then run:
flutter pub get
Usage #
Basic Usage #
import 'package:universal_downloader/universal_downloader.dart';
// Simple download
await UniversalDownloader.downloadFile(
url: "https://example.com/file.pdf",
fileName: "myfile.pdf",
);
Advanced Usage with Callbacks #
import 'package:universal_downloader/universal_downloader.dart';
final result = await UniversalDownloader.downloadFile(
url: "https://example.com/largefile.zip",
fileName: "largefile.zip",
onProgress: (progress) {
print("Progress: ${progress.percentage.toStringAsFixed(1)}%");
print("Downloaded: ${progress.downloadedBytes}/${progress.totalBytes} bytes");
},
onComplete: (filePath) {
print("File saved at: $filePath");
},
onError: (error) {
print("Download failed: $error");
},
saveToDocuments: false, // Use Downloads folder (mobile only)
);
if (result.isSuccess) {
print("Download completed: ${result.filePath}");
} else {
print("Download failed: ${result.errorMessage}");
}
Download from Stream #
import 'package:universal_downloader/universal_downloader.dart';
// Download from a byte stream
await UniversalDownloader.downloadStream(
stream: myByteStream,
filename: "streamed_file.pdf",
);
Download Binary Data #
import 'package:universal_downloader/universal_downloader.dart';
import 'dart:typed_data';
// Download from binary data
Uint8List imageData = /* your image data */;
await UniversalDownloader.downloadData(
data: imageData,
filename: "image.png",
);
Stream-based URL Download #
import 'package:universal_downloader/universal_downloader.dart';
// More memory-efficient for large files
final result = await UniversalDownloader.downloadFromUrlStream(
url: "https://example.com/largefile.zip",
filename: "largefile.zip",
onProgress: (progress) {
print("Progress: ${progress.percentage.toStringAsFixed(1)}%");
},
);
Enhanced Web Download (Recommended for PDFs/Music) #
import 'package:universal_downloader/universal_downloader.dart';
// Better handling for PDFs, music files, and media content
final result = await UniversalDownloader.downloadWebFile(
url: "https://example.com/song.mp3",
filename: "song.mp3",
onComplete: (filePath) {
print("Music file downloaded: $filePath");
},
onError: (error) {
print("Download failed: $error");
},
);
Simple URL Download #
import 'package:universal_downloader/universal_downloader.dart';
// Simple download without progress tracking
await UniversalDownloader.downloadUrl(
url: "https://example.com/file.pdf",
filename: "document.pdf", // Optional
);
Platform Detection #
// Check current platform
print("Current platform: ${UniversalDownloader.platformName}");
// Check platform capabilities
if (UniversalDownloader.supportsDirectorySelection) {
print("This platform supports directory selection");
}
if (UniversalDownloader.supportsProgressTracking) {
print("This platform supports progress tracking");
}
Mobile Permissions #
Automatic Permission Handling #
The Universal Downloader automatically handles storage permissions for mobile platforms:
// Permission is automatically requested before download starts
final result = await UniversalDownloader.downloadFile(
url: "https://example.com/file.pdf",
fileName: "document.pdf",
);
// If permission is denied, you'll get a PermissionDownloadException
Manual Permission Management #
You can also manually check and request permissions:
import 'package:universal_downloader/universal_downloader.dart';
// Check if permission is granted
bool hasPermission = await PermissionUtils.requestStoragePermission();
if (!hasPermission) {
// Show error message to user
String errorMessage = PermissionUtils.getPermissionErrorMessage();
showDialog(/* show error dialog */);
}
Required Android Permissions #
Add these permissions to your android/app/src/main/AndroidManifest.xml:
<!-- Internet permission for downloading files -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Storage permissions for Android 12 and below -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<!-- For Android 13+ (API 33+) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
API Reference #
UniversalDownloader.downloadFile() #
Downloads a file from a URL and saves it locally.
Parameters:
url(String, required): The URL to download fromfileName(String, required): The filename to save asonProgress(ProgressCallback?, optional): Progress update callbackonComplete(CompleteCallback?, optional): Success callbackonError(ErrorCallback?, optional): Error callbacksaveToDocuments(bool, optional): Save to Documents instead of Downloads (mobile only)allowSelfSignedCertificate(bool, optional): Allow self-signed SSL certificates (native platforms only)
Returns: Future<DownloadResult>
UniversalDownloader.downloadStream() #
Downloads a file from a byte stream and saves it locally.
Parameters:
stream(Streamfilename(String, required): The filename to save as
Returns: Future<void>
UniversalDownloader.downloadData() #
Downloads a file from binary data and saves it locally.
Parameters:
data(Uint8List, required): The binary data to savefilename(String, required): The filename to save as
Returns: Future<void>
UniversalDownloader.downloadFromUrlStream() #
Downloads a file from a URL using streaming with progress tracking. More memory-efficient for large files.
Parameters:
url(String, required): The URL to download fromfilename(String, required): The filename to save asonProgress(ProgressCallback?, optional): Progress update callbackonComplete(CompleteCallback?, optional): Success callbackonError(ErrorCallback?, optional): Error callbackallowSelfSignedCertificate(bool, optional): Allow self-signed SSL certificates (native platforms only)
Returns: Future<DownloadResult>
UniversalDownloader.downloadWebFile() #
Enhanced web download method with better CORS and file type handling. Recommended for PDFs, music files, and other media content that browsers typically try to open instead of download.
Parameters:
url(String, required): The URL to download fromfileName(String, required): The filename to save asonProgress(ProgressCallback?, optional): Progress update callbackonComplete(CompleteCallback?, optional): Success callbackonError(ErrorCallback?, optional): Error callback
Returns: Future<DownloadResult>
Example:
import 'package:universal_downloader/universal_downloader.dart';
// Better for PDFs and music files
final result = await UniversalDownloader.downloadWebFile(
url: "https://example.com/document.pdf",
fileName: "document.pdf",
onComplete: (filePath) {
print("PDF downloaded successfully: $filePath");
},
onError: (error) {
print("Download failed: $error");
},
);
Platform Properties #
UniversalDownloader.platformName
Gets the current platform name as a string.
Returns: String ("Android", "iOS", "Web", "Windows", "macOS", "Linux", or "Unknown")
UniversalDownloader.supportsDirectorySelection
Checks if the current platform supports custom directory selection.
Returns: bool (true for Windows, macOS, Linux; false for Android, iOS, Web)
UniversalDownloader.supportsProgressTracking
Checks if the current platform supports download progress tracking.
Returns: bool (true for all platforms)
Models #
DownloadProgress
class DownloadProgress {
final int totalBytes; // Total bytes to download
final int downloadedBytes; // Bytes downloaded so far
final double percentage; // Progress percentage (0.0-100.0)
final double? speed; // Download speed (bytes/second)
}
DownloadResult
class DownloadResult {
final String filePath; // Where the file was saved
final String url; // Original download URL
final String fileName; // Filename used
final int totalBytes; // Total bytes downloaded
final bool isSuccess; // Whether download succeeded
final String? errorMessage; // Error message if failed
}
Callbacks #
typedef ProgressCallback = void Function(DownloadProgress progress);
typedef CompleteCallback = void Function(String filePath);
typedef ErrorCallback = void Function(String error);
Web Download Improvements #
Enhanced File Type Support #
The web downloader now supports ALL file types without any restrictions:
- ✅ PDF Files: Enhanced handling to force download instead of opening in browser
- ✅ Music Files: MP3, WAV, OGG, and other audio formats
- ✅ Video Files: MP4, WebM, AVI, MOV, and other video formats
- ✅ Document Files: DOC, DOCX, XLS, XLSX, PPT, PPTX
- ✅ Archive Files: ZIP, RAR, 7Z, TAR, GZ
- ✅ Image Files: JPG, PNG, GIF, BMP, SVG, WEBP
- ✅ All Other Formats: Any file type is supported
Universal Download Support #
- No file extension restrictions - all file types work
- Automatic file type detection and optimal handling
- Smart download strategies based on file characteristics
- Fallback mechanisms for problematic scenarios
Multiple Download Strategies #
When standard download fails, the package now tries several fallback methods:
- Fetch + Base64: Downloads file data and encodes it for reliable transfer
- Direct Link: Creates download links with proper attributes
- Aggressive Methods: Uses iframes and multiple anchor strategies for stubborn files
- Window Methods: Falls back to window.open with download parameters
CORS Handling #
- Automatic detection of CORS issues
- Graceful fallback when cross-origin requests are blocked
- Better error messages with specific solutions
Browser Compatibility #
- Works across all modern browsers (Chrome, Firefox, Safari, Edge)
- Handles browser-specific quirks for different file types
- Provides clear feedback when manual intervention is needed
Error Handling #
The package provides comprehensive error handling with specific exception types:
try {
await UniversalDownloader.downloadFile(
url: "invalid-url",
fileName: "test.pdf",
);
} on NetworkDownloadException catch (e) {
print("Network error: $e");
} on FileSystemDownloadException catch (e) {
print("File system error: $e");
} on PermissionDownloadException catch (e) {
print("Permission error: $e");
} on DownloadException catch (e) {
print("General download error: $e");
}
Example #
Check out the example directory for a complete Flutter app demonstrating all features of the universal_downloader package.
To run the example:
cd example
flutter pub get
flutter run
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog #
1.0.0 #
- Initial release
- Support for all Flutter platforms
- Progress tracking
- Platform-optimized storage
- Comprehensive error handling
- Web download support
- Full documentation and examples