{"id":36213142,"url":"https://github.com/anandhakrishnan-codeblock/downloader_flutter","last_synced_at":"2026-01-13T22:01:06.157Z","repository":{"id":324930891,"uuid":"1098838998","full_name":"Anandhakrishnan-CodeBlock/downloader_flutter","owner":"Anandhakrishnan-CodeBlock","description":"A powerful Flutter download plugin supporting Android \u0026 iOS with real-time progress, parallel downloads, background safety, system DownloadManager integration, iOS URLSession delegate support.","archived":false,"fork":false,"pushed_at":"2025-11-20T14:11:41.000Z","size":102771,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T20:45:36.541Z","etag":null,"topics":["android","android-app","background-worker","download-manager","downloader","flutter","flutter-plugin","ios","ios-app"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/downloader_flutter","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Anandhakrishnan-CodeBlock.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-18T08:00:00.000Z","updated_at":"2025-11-20T14:03:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Anandhakrishnan-CodeBlock/downloader_flutter","commit_stats":null,"previous_names":["anandhakrishnan-codeblock/downloader_flutter"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Anandhakrishnan-CodeBlock/downloader_flutter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anandhakrishnan-CodeBlock%2Fdownloader_flutter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anandhakrishnan-CodeBlock%2Fdownloader_flutter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anandhakrishnan-CodeBlock%2Fdownloader_flutter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anandhakrishnan-CodeBlock%2Fdownloader_flutter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Anandhakrishnan-CodeBlock","download_url":"https://codeload.github.com/Anandhakrishnan-CodeBlock/downloader_flutter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anandhakrishnan-CodeBlock%2Fdownloader_flutter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28403750,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T21:51:37.118Z","status":"ssl_error","status_checked_at":"2026-01-13T21:45:14.585Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-app","background-worker","download-manager","downloader","flutter","flutter-plugin","ios","ios-app"],"created_at":"2026-01-11T04:05:41.709Z","updated_at":"2026-01-13T22:01:06.122Z","avatar_url":"https://github.com/Anandhakrishnan-CodeBlock.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Downloader Flutter\n\nA powerful Flutter download plugin supporting Android \u0026 iOS with real-time progress, parallel downloads, background safety, system [DownloadManager](https://developer.android.com/reference/android/app/DownloadManager) integration, iOS [URLSessionDownloadDelegate](https://developer.apple.com/documentation/foundation/urlsessiondownloaddelegate) support, automatic file saving, Photos library export, and EventChannel-based streaming updates. Designed for handling large files with accurate progress tracking and smooth cross-platform performance.\n\nFlutter Downloader Plugin\nA full-featured, cross-platform file downloader built for Flutter, supporting Android \u0026 iOS with real-time progress, safe background execution, system-level integrations, and a clean EventChannel-driven update stream.\n\nThis plugin provides advanced download capabilities:\n\n### Android Demo \n![Android_Downloader_Flutter_GIF](https://github.com/user-attachments/assets/24ffba7b-6b60-49f5-8527-28dd4d35cb87)\n\n### iOS Demo\n![iOS_Downloader_Flutter_GIF](https://github.com/user-attachments/assets/a809e1f9-4d91-4109-9c9d-055e5b498e9d)\n\n# 🚀 Features\n\n## Android Support\n\n- Uses Android DownloadManager for reliable system-level downloading\n\n- Supports parallel / multiple downloads simultaneously\n\n- Real-time progress updates using EventChannel\n\n- Safe background execution using coroutines (Dispatchers.IO)\n\n- Automatic file handling and storage management\n\n- Saves images/videos to Gallery when requested\n\n- Toast feedback for start/error (optional)\n\n- Thread-safe updates using Dispatchers.Main\n\n- Kotlin implementation optimized for performance\n\n## iOS Support\n\n- Uses URLSessionDownloadDelegate for accurate progress tracking\n\n- Supports true percentage (%) progress\n\n- Parallel file downloads with per-file delegates\n\n- Automatic movement of temporary downloaded files\n\n- Optional save to Photos app\n\n- Sends real-time events using Flutter EventChannel\n\n- 100% main-thread safe event dispatching\n\n- Swift implementation with clean status mapping\n\n## Support\n| Platform | Status |\n|:--------:|:------:|\n| Android  |   ✅    |\n|   iOS    |   ✅    |\n| Windows  |   ❌    |\n|  Linux   |   ❌    |\n|  macOs   |   ❌    |\n\n# Plugin Configuration\n## Android (Permission)\n- Internet Permission Required\n```\n\n\u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n```\n\n## iOS (Info.plist)\n### 1. Photo Library Access (required)\n\u003e Because your code calls PHPhotoLibrary.requestAuthorization(...) and saves images/videos.\n```\n\u003ckey\u003eNSPhotoLibraryAddUsageDescription\u003c/key\u003e\n\u003cstring\u003eThis app saves downloaded media files to your Photos library.\u003c/string\u003e\n\u003ckey\u003eNSPhotoLibraryUsageDescription\u003c/key\u003e\n\u003cstring\u003eThis app needs access to your Photos to save and view downloaded files.\u003c/string\u003e\n```\n\n### 2. App Transport Security (for HTTP downloads)\n\u003e If any of your download URLs use HTTP (not HTTPS), iOS will block them unless you add this:\n- Option A – Allow only specific domains (recommended)\n```\n\u003ckey\u003eNSAppTransportSecurity\u003c/key\u003e\n\u003cdict\u003e\n    \u003ckey\u003eNSExceptionDomains\u003c/key\u003e\n    \u003cdict\u003e\n        \u003ckey\u003ecommondatastorage.googleapis.com\u003c/key\u003e\n        \u003cdict\u003e\n            \u003ckey\u003eNSIncludesSubdomains\u003c/key\u003e\n            \u003ctrue/\u003e\n            \u003ckey\u003eNSExceptionAllowsInsecureHTTPLoads\u003c/key\u003e\n            \u003ctrue/\u003e\n            \u003ckey\u003eNSExceptionRequiresForwardSecrecy\u003c/key\u003e\n            \u003cfalse/\u003e\n        \u003c/dict\u003e\n    \u003c/dict\u003e\n\u003c/dict\u003e\n```\n\n- Option B – Allow all HTTP (for testing only)\n```\n\u003ckey\u003eNSAppTransportSecurity\u003c/key\u003e\n\u003cdict\u003e\n  \u003ckey\u003eNSAllowsArbitraryLoads\u003c/key\u003e\n  \u003ctrue/\u003e\n\u003c/dict\u003e\n```\n\n### 3. File Sharing (for “On My iPhone → AppName”)\n\u003e To let users see downloaded files in the Files app:\n```\n\u003ckey\u003eUIFileSharingEnabled\u003c/key\u003e\n\u003ctrue/\u003e\n\u003ckey\u003eLSSupportsOpeningDocumentsInPlace\u003c/key\u003e\n\u003ctrue/\u003e\n```\n\n### 4. Background downloads (optional but recommended)\n\u003e If you want downloads to continue when the app goes into the background:\n```\n\u003ckey\u003eUIBackgroundModes\u003c/key\u003e\n\u003carray\u003e\n\u003cstring\u003efetch\u003c/string\u003e\n\u003cstring\u003eprocessing\u003c/string\u003e\n\u003c/array\u003e\n```\n# Usage\n- Object creation for DownloaderFlutter() class.\n```\n\nfinal _downloaderFlutterPlugin = DownloaderFlutter();\n```\n## Single file download\n```\n    await _downloaderFlutterPlugin.downloadSingleFile(\n        url: 'https://images.pexels.com/photos/10725897/pexels-photo-10725897.jpeg',\n        fileName: \"image.jpeg\",\n         saveToPhoto: true, (Optional)\n         showToastAndroid: false, (Optional)\n         response: (data) {\n             debugPrint(\"Response In App: $data\");\n         },\n    ) ?? 'Downloader Not Connected';\n```\n#### Properties downloadSingleFile \n| **Property**         | **Type** |      **Example Value**       | **Description**                                                           |  \n|:---------------------|:--------:|:----------------------------:|:--------------------------------------------------------------------------|\n| **url**              |  String  | https://example.com/file.mp4 | The full download URL of the file.                                        |\n| **fileName**         |  String  |         my_video.mp4         | Name of the saved file, including its extension.                          |\n| **saveToPhoto**      |   bool   |          true/false          | iOS only — when true, saves downloaded media files to the Photos app.     |\n| **showToastAndroid** |   bool   |          true/false          | Android only — when true, shows a toast message after download completes. |\n| **response**         |  String  |    \"success\" or \"failed\"     | String response/status returned by the function.                          |\n\n## Multiple file download\n```\n    await _downloaderFlutterPlugin.downloadMultipleFile(\n        urls: [\n          'https://images.pexels.com/photos/177598/pexels-photo-177598.jpeg',\n          'https://images.pexels.com/photos/577585/pexels-photo-577585.jpeg',\n          'https://images.pexels.com/photos/1181244/pexels-photo-1181244.jpeg',\n          'https://images.pexels.com/photos/4816921/pexels-photo-4816921.jpeg',\n          'https://images.pexels.com/photos/248515/pexels-photo-248515.png',\n        ],\n        fileNames: [\n          'image1.jpg',\n          'image2.jpg',\n          'image3.jpg',\n          'image4.jpg',\n          'image5.png',\n        ],\n        saveToPhoto: true, (Optional)\n        showToastAndroid: true, (Optional)\n        response: (data) {\n          debugPrint(\"Response In App: $data\");\n        },\n      ) ?? 'Downloader Not Connected';\n```\n#### Properties downloadMultipleFile\n| **Property**         |   **Type**   |                     **Example Value**                      | **Description**                                                           |  \n|:---------------------|:------------:|:----------------------------------------------------------:|:--------------------------------------------------------------------------|\n| **urls**             | List\u003cString\u003e | [\"https://example.com/a.mp4\", \"https://example.com/b.jpg\"] | The full download URL of the file.                                        |\n| **fileNames**        | List\u003cString\u003e |                [\"video1.mp4\", \"image1.jpg\"]                | Name of the saved file, including its extension.                          |\n| **saveToPhoto**      |     bool     |                         true/false                         | iOS only — when true, saves downloaded media files to the Photos app.     |\n| **showToastAndroid** |     bool     |                         true/false                         | Android only — when true, shows a toast message after download completes. |\n| **response**         |    String    |                   \"success\" or \"failed\"                    | String response/status returned by the function.                          |\n\n## Event listener for downloadProgress\n```\n\n    _downloaderFlutterPlugin.downloadProgress().listen((event) {\n        handleDownloadEvent(event);\n    });\n```\n\n## Download handler \n```\n    void handleDownloadEvent(Map\u003cString, dynamic\u003e event) {\n    \n    final status = event[\"status\"] as String?;\n    \n    if (status == null) {\n      debugPrint(\"⚠️ Unknown event: $event\");\n      return;\n    }\n\n    final fileName = event[\"fileName\"] as String? ?? \"unknown\";\n\n    switch (status) {\n      case \"started\":\n        debugPrint(\"🚀 Started $fileName\");\n        break;\n\n      case \"progress\":\n        final progress = event[\"progress\"] as int? ?? 0;\n        debugPrint(\"📊 Progress $fileName: $progress%\");\n        break;\n\n      case \"success\":\n        debugPrint(\"✅ Completed $fileName\");\n        break;\n\n      case \"saved\":\n        debugPrint(\"📷 Saved to photo $fileName\");\n        break;\n\n      case \"failed\":\n        debugPrint(\"❌ Failed $fileName\");\n        break;\n\n      case \"completed\":\n        debugPrint(\"🎉 Download completed $fileName\");\n        break;\n\n      case \"error\":\n        final message = event[\"message\"] as String? ?? \"Unknown error\";\n        debugPrint(\"⚠️ Error: $message\");\n        break;\n\n      default:\n        debugPrint(\"❓ Unknown status: $status\");\n    }\n  }\n```\n#### Properties handleDownloadEvent\n| **Status Value** |          **When Triggered**          |                      **Meaning / Behavior**                       |  \n|:-----------------|:------------------------------------:|:-----------------------------------------------------------------:|\n| **started**      |         When download begins         |        Indicates download has started for the given file.         |\n| **progress**     |        During active download        |          Provides incremental progress updates (0–100).           |\n| **success**      | When file is successfully downloaded |    File is saved locally in the device's documents directory.     |\n| **saved**        | When file saved to Photos (iOS only) |  Confirms that the media file has been added to the Photos app.   |\n| **failed**       |         When download fails          | File couldn’t be downloaded due to error (e.g., network failure). |\n| **completed**    | When all download operations finish  |   Indicates full workflow completed (download + optional save).   |\n| **error**        |    When an internal error occurs     |       Provides an error message detailing what went wrong.        |\n\n# Bugs/Requests\nFeel free to open an issue if you encounter any problems or think that the plugin is missing some feature.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanandhakrishnan-codeblock%2Fdownloader_flutter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanandhakrishnan-codeblock%2Fdownloader_flutter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanandhakrishnan-codeblock%2Fdownloader_flutter/lists"}