File Downloader in flutter : A Comptehensive Guide to implement file downloading feature in flutter.

 



File Downloader in Flutter: A Complete Guide

Introduction

Downloading files in a Flutter app is a common requirement, whether for offline access, media consumption, or document storage. In this guide, we will implement a file downloader in Flutter using the dio package and flutter_downloader. We will handle permissions, display progress indicators, and ensure a smooth user experience.

Prerequisites

Before we start, ensure you have:

  • Flutter installed

  • Basic knowledge of Flutter and Dart

  • An IDE (VS Code or Android Studio)

Step 1: Setting Up Dependencies

Open your pubspec.yaml file and add the required packages:

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.3.2
  permission_handler: ^10.4.3
  flutter_downloader: ^1.11.6

Run flutter pub get to install them.

Step 2: Configuring Permissions

For Android, update AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

For iOS, open Info.plist and add:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Step 3: Implementing the Download Logic

Create a new Dart file file_downloader.dart:

      import 'package:dio/dio.dart';
      import 'package:permission_handler/permission_handler.dart';

      class FileDownloader {
        final Dio _dio = Dio();

        Future<void> downloadFile(
            String url, String savePath, Function(int, int) onReceiveProgress) async {
          var status = await Permission.storage.request();
          if (status.isGranted) {
            try {
              await _dio.download(url, savePath,
                  onReceiveProgress: onReceiveProgress);
            } on DioError catch (e) {
              if (e.type == DioErrorType.unknown) {
                throw Exception("No address associated with hostname: $url");
              } else {
                print(e.message);
                throw Exception("Download failed: ${e.message}");
              }
            } catch (e) {
              print(e);
              throw Exception("Unexpected error: $e");
            }
          } else {
            throw Exception("Permission Denied!");
          }
        }
      }

Step 4: Integrating with UI

Modify main.dart to include a download button:

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

        void main() {
          runApp(MyApp());
        }

        class MyApp extends StatefulWidget {
          @override
          _MyAppState createState() => _MyAppState();
        }

        class _MyAppState extends State<MyApp> {
          final FileDownloader fileDownloader = FileDownloader();
          final String fileUrl =
              'https://link.testfile.org/500MB'; // Ensure this URL is correct
          final String savePath = '/storage/emulated/0/Download/dummyfile.zip';

          double _progress = 0.0;
          String _status = "Idle";

          void _startDownload() async {
            setState(() {
              _status = "Downloading...";
            });

            try {
              await fileDownloader.downloadFile(fileUrl, savePath, (count, total) {
                setState(() {
                  _progress = count / total;
                });
              });
              setState(() {
                _status = "Download Complete!";
              });
            } catch (e) {
              setState(() {
                _status = "Download Failed: $e";
              });
            }
          }

          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: Scaffold(
                appBar: AppBar(title: Text("File Downloader")),
                body: Center(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      ElevatedButton(
                        onPressed: _startDownload,
                        child: Text("Download File"),
                      ),
                      SizedBox(height: 20),
                      LinearProgressIndicator(value: _progress),
                      SizedBox(height: 20),
                      Text(_status),
                    ],
                  ),
                ),
              ),
            );
          }
        }

Step 5: Running the App

Run your app using:

flutter run

Now, pressing the download button will download the file to the specified path.

Conclusion

We successfully implemented a file downloader in Flutter, handling permissions and showing progress updates. You can further enhance it by integrating a progress bar and error handling for a better user experience.


Post a Comment

Previous Post Next Post