Flutter_Downloader Tutorial: Implement File Downloads in Flutter

Haris Bin Nasir Avatar

·

·

The flutter_downloader package is a powerful tool for handling file downloads in Flutter applications. It provides a reliable and efficient way to download files directly to the device, supports background downloading, and allows you to monitor download progress. This tutorial will walk you through setting up and using flutter_downloader in your Flutter app, with easy-to-follow code examples.

What is flutter_downloader and Why Use It?

The flutter_downloader package allows you to add download functionality to your Flutter apps, making it ideal for applications that require file downloading, such as media players, document viewers, or e-learning apps. Key features include:

  • Background Downloads: Downloads continue even when the app is minimized.
  • Progress Tracking: Track and display the progress of each download.
  • Pause and Resume: Users can pause and resume downloads as needed.
  • Error Handling: Provides error handling capabilities to manage download failures.

Let’s dive into the setup process and implementation.

Setting Up flutter_downloader

Step 1: Add Dependencies

Add flutter_downloader and path_provider (for file storage) to your pubspec.yaml file:

flutter_downloader:
A Flutter package for efficient file downloading, supporting background downloads, progress tracking, and control options like pause and resume. To get the dependency click here.

path_provider:
A Flutter plugin that provides platform-specific paths for storing files, essential for saving downloaded files in accessible directories. To get the dependency click here.

dependencies:
  flutter:
    sdk: flutter
  flutter_downloader: ^1.11.8
  path_provider: ^2.1.5

Run flutter pub get to install the packages.

flutter pub get

Step 2: Configure Platform-Specific Settings

To use flutter_downloader, you need to configure platform-specific settings for Android and iOS.

Android Setup

  • Open AndroidManifest.xml and add the following permissions to allow downloading and file storage:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
  • Add the following service configuration in the <application> tag:
<service android:name="vn.hunghd.flutterdownloader.DownloadService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true"/>

iOS Setup

For iOS, open your Info.plist file and add this permission to enable background downloads:

<key>UIBackgroundModes</key>
<array>
  <string>fetch</string>
  <string>processing</string>
</array>

Step 3: Initialize flutter_downloader

To initialize flutter_downloader, add the following code in your main() function:

import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await FlutterDownloader.initialize(debug: true);  // Set to false for production
  runApp(MyApp());
}

With flutter_downloader initialized, we can now start using it to download files.

Basic Download Implementation in flutter_downloader

To begin downloading, we need to request storage permissions, define the download URL, set up the download function, and display the progress. Here’s how to do it step-by-step.

Step 1: Request Storage Permissions

On Android, you must request storage permissions before downloading files. Use the permission_handler package or create a method to request permissions directly:

import 'package:permission_handler/permission_handler.dart';

Future<void> requestPermissions() async {
  if (await Permission.storage.request().isGranted) {
    print("Storage permission granted.");
  } else {
    print("Storage permission denied.");
  }
}

Step 2: Define the Download Function

Create a function that takes the file URL and initiates the download. We’ll also set up a local file path to save the downloaded file.

import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';

Future<void> startDownload(String url) async {
  final directory = await getExternalStorageDirectory();
  final filePath = "${directory!.path}/my_downloaded_file.ext";

  final taskId = await FlutterDownloader.enqueue(
    url: url,
    savedDir: directory.path,
    fileName: "my_downloaded_file.ext",
    showNotification: true,
    openFileFromNotification: true,
  );

  print("Download started with Task ID: $taskId");
}

Explanation:

  • getExternalStorageDirectory(): Provides the path to the external storage directory.
  • FlutterDownloader.enqueue: Starts the download. It requires the URL, save directory, and filename.
  • showNotification: Shows a notification in the notification bar.
  • openFileFromNotification: Enables users to open the file from the notification.

Step 3: Displaying Download Progress

To show download progress, you need to register a callback for FlutterDownloader.registerCallback() and set up a listener:

void downloadCallback(String id, DownloadTaskStatus status, int progress) {
  print("Download task ($id) is in status: $status and progress: $progress%");
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await FlutterDownloader.initialize();
  FlutterDownloader.registerCallback(downloadCallback);  // Register the callback
  runApp(MyApp());
}

Step 4: Build the Download Button in the UI

Create a download button that triggers the startDownload function with a file URL:

import 'package:flutter/material.dart';

class DownloadScreen extends StatelessWidget {
  final String downloadUrl = "https://example.com/file.pdf";  // Replace with an actual file URL

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Download Example')),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            await requestPermissions();
            await startDownload(downloadUrl);
          },
          child: Text("Start Download"),
        ),
      ),
    );
  }
}

Managing Download States: Pause, Resume, and Cancel

flutter_downloader allows you to manage the download states by pausing, resuming, and canceling downloads.

Pausing a Download

To pause a download, call pause with the task ID:

Future<void> pauseDownload(String taskId) async {
  await FlutterDownloader.pause(taskId: taskId);
  print("Download paused with Task ID: $taskId");
}

Resuming a Download

To resume a paused download, use the resume method:

Future<void> resumeDownload(String taskId) async {
  final newTaskId = await FlutterDownloader.resume(taskId: taskId);
  print("Download resumed with new Task ID: $newTaskId");
}

Canceling a Download

To cancel a download, use the cancel method:

Future<void> cancelDownload(String taskId) async {
  await FlutterDownloader.cancel(taskId: taskId);
  print("Download canceled with Task ID: $taskId");
}

Full Example with Download Controls

Here’s a complete example with buttons to pause, resume, and cancel the download:

class DownloadManager extends StatefulWidget {
  @override
  _DownloadManagerState createState() => _DownloadManagerState();
}

class _DownloadManagerState extends State<DownloadManager> {
  String? _taskId;
  int _progress = 0;

  Future<void> startDownload(String url) async {
    final directory = await getExternalStorageDirectory();
    _taskId = await FlutterDownloader.enqueue(
      url: url,
      savedDir: directory!.path,
      showNotification: true,
      openFileFromNotification: true,
    );
  }

  void downloadCallback(String id, DownloadTaskStatus status, int progress) {
    if (id == _taskId) {
      setState(() {
        _progress = progress;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    FlutterDownloader.registerCallback(downloadCallback);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Download Manager')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('Download Progress: $_progress%'),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () async {
                  await startDownload('https://example.com/file.pdf');
                },
                child: Text('Start Download'),
              ),
              ElevatedButton(
                onPressed: () async {
                  if (_taskId != null) await FlutterDownloader.pause(taskId: _taskId!);
                },
                child: Text('Pause'),
              ),
              ElevatedButton(
                onPressed: () async {
                  if (_taskId != null) await FlutterDownloader.resume(taskId: _taskId!);
                },
                child: Text('Resume'),
              ),
              ElevatedButton(
                onPressed: () async {
                  if (_taskId != null) await FlutterDownloader.cancel(taskId: _taskId!);
                },
                child: Text('Cancel'),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

Explanation:

  • startDownload(): Initiates a download and saves the task ID for tracking.
  • downloadCallback(): Updates the download progress in real-time.
  • Buttons: Start, Pause, Resume, and Cancel buttons to control the download.

Conclusion

The flutter_downloader package is a versatile solution for implementing file downloads in your Flutter app. This Flutter_Downloader tutorial covered the setup, basic download functionality, and advanced features like tracking, pausing, resuming, and canceling downloads. With flutter_downloader, you can easily manage file downloads in your app, making it a perfect choice for applications that require reliable download functionality.As always, If you have found this tutorial on Flutter_Downloader useful do not forget to share it and leave a comment if you have any questions.

Happy Coding…!!!

Leave a Reply

Your email address will not be published. Required fields are marked *