image_downloader_v2 0.34.0
image_downloader_v2: ^0.34.0 copied to clipboard
Flutter plugin that downloads images on the Internet and saves them on device.
image_downloader_v2 #
A Flutter plugin to download images and videos from the internet and save them directly to the device's photo library/gallery or custom storage directory. Preserves original metadata such as Exif (DateTimeOriginal) and GPS (Latitude, Longitude).
Features #
- Direct Downloads: Download images and videos straight to the gallery or app storage.
- Progress Updates: Real-time progress updates with callbacks.
- Custom Destinations: Flexible storage directory support (Downloads, Pictures, DCIM, Movies, or custom subdirectories).
- Metadata Preservation: Retains EXIF data and GPS coordinates.
- Built-in Preview: Open/preview saved files using native platform viewers (
UIDocumentInteractionController/Intent). - Modern Platform Support:
- Full Dart 3 & Flutter 3+ compatibility.
- iOS: Swift Package Manager (SPM) and CocoaPods (iOS 12.0+).
- Android: Android 14+ compatible with modern Gradle configurations.
Getting Started #
Installation #
Add image_downloader_v2 to your pubspec.yaml:
dependencies:
image_downloader_v2: ^0.34.0
Run in your terminal:
flutter pub get
Platform Configuration #
iOS
Add the following keys to your Info.plist file located in <project root>/ios/Runner/Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to the photo library to save downloaded images.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app requires write access to the photo library to save downloaded images.</string>
Android
Add the following permission to your AndroidManifest.xml (located in <project root>/android/app/src/main/AndroidManifest.xml).
Note: If you use
inExternalFilesDir(), storage permission is not required.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
If you plan to use ImageDownloader.open(path) for previewing on Android, register the FileProvider inside the <application> tag of your AndroidManifest.xml:
<provider
android:name="com.rizkyghofur.imagedownloader.FileProvider"
android:authorities="${applicationId}.image_downloader.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
Then create android/app/src/main/res/xml/provider_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Usage Examples #
1. Basic Download #
import 'package:flutter/services.dart';
import 'package:image_downloader_v2/image_downloader_v2.dart';
Future<void> downloadImage(String url) async {
try {
// Download image and get image ID
final imageId = await ImageDownloader.downloadImage(url);
if (imageId == null) {
// Permission denied or operation aborted
return;
}
// Retrieve details of the saved image
final fileName = await ImageDownloader.findName(imageId);
final path = await ImageDownloader.findPath(imageId);
final size = await ImageDownloader.findByteSize(imageId);
final mimeType = await ImageDownloader.findMimeType(imageId);
print('Downloaded: $fileName, Path: $path, Size: $size bytes, Mime: $mimeType');
} on PlatformException catch (error) {
print('Download failed: $error');
}
}
2. Custom Save Destination (Android) #
You can specify default system directories or custom nested directories:
// Option A: Save to Public Pictures
await ImageDownloader.downloadImage(
url,
destination: AndroidDestinationType.directoryPictures
..subDirectory("custom_folder/sample.png"),
);
// Option B: Save to App External Files Dir (no WRITE_EXTERNAL_STORAGE permission required)
await ImageDownloader.downloadImage(
url,
destination: AndroidDestinationType.custom(directory: 'custom_folder')
..inExternalFilesDir()
..subDirectory("sample.png"),
);
Available Android Destinations:
| Destination | Description |
|---|---|
AndroidDestinationType.directoryDownloads |
Public Download directory |
AndroidDestinationType.directoryPictures |
Public Pictures directory |
AndroidDestinationType.directoryDCIM |
Public DCIM (Camera) directory |
AndroidDestinationType.directoryMovies |
Public Movies directory |
AndroidDestinationType.custom(...) |
User-defined custom destination |
3. Track Download Progress #
Register a progress callback to track download percentages:
@override
void initState() {
super.initState();
ImageDownloader.callback(onProgressUpdate: (String? imageId, int progress) {
setState(() {
_progress = progress; // 0 - 100
});
});
}
4. Cancel a Download #
await ImageDownloader.cancel();
5. Preview / Open Saved Image #
final path = await ImageDownloader.findPath(imageId!);
if (path != null) {
await ImageDownloader.open(path);
}
6. Error Handling #
try {
await ImageDownloader.downloadImage(url);
} on PlatformException catch (error) {
if (error.code == "404") {
print("Image not found (404)");
} else if (error.code == "unsupported_file") {
// Unsupported files are still saved temporarily
final tempPath = error.details?["unsupported_file_path"];
print("Unsupported file format saved at: $tempPath");
} else {
print("Error: ${error.message}");
}
}
Author & Maintainer #
- Author: Rizky Abdul Ghafur
- Email: rizky.abdulghofur@gmail.com
- GitHub: @rizkyghofur
License #
This project is licensed under the MIT License - see the LICENSE file for details.