Why do my downloads fail sometimes using flutter_downloader?
Asked Answered
G

3

2

I'm using the flutter_downloader plugin to download files for my app users. On both Android and iOS, downloads sometimes fail with this error message: flutter: not found task corresponding to given task id. With iOS, sometimes my download tasks would just be enqueued and not executed at all. Sometimes they run smoothly.

I found that running flutter clean and rebuilding the app seems to make this disappear for a bit (download successful and file can be opened in relevant apps), but when I build the Flutter app again after changing something, the error comes back. I've enabled Android cleartext traffic, to no avail.

Here's a minimal reproduction of my code:

import 'dart:isolate';
import 'dart:ui';

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

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

_initializeFlutterDownloader()async{
    WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize();
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Downloader Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Downloader Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ReceivePort _port = ReceivePort();

  @override
  void initState() {
    super.initState();
    _downloadListener();
  }

  static void downloadCallback(
      String id, DownloadTaskStatus status, int progress) {
    final SendPort send =
        IsolateNameServer.lookupPortByName('downloader_send_port');
    send.send([id, status, progress]);
  }

  _downloadListener() {
    IsolateNameServer.registerPortWithName(
        _port.sendPort, 'downloader_send_port');
    _port.listen((dynamic data) {
      String id = data[0];
      DownloadTaskStatus status = data[1];
      if (status.toString() == "DownloadTaskStatus(3)") {
        FlutterDownloader.open(taskId: id);
      }
    });
    FlutterDownloader.registerCallback(downloadCallback);
  }

  void _download() async {
    String _localPath =
        (await findLocalPath()) + Platform.pathSeparator + 'Example_Downloads';

    final savedDir = Directory(_localPath);
    bool hasExisted = await savedDir.exists();
    if (!hasExisted) {
      savedDir.create();
    }
    String _url =
        "https://www.colonialkc.org/wp-content/uploads/2015/07/Placeholder.png";
    final download = await FlutterDownloader.enqueue(
      url: _url,
      savedDir: _localPath,
      showNotification: true,
      openFileFromNotification: true,
    );
  }

  Future<String> findLocalPath() async {
    final directory =
        // (MyGlobals.platform == "android")
        // ?
        await getExternalStorageDirectory();
    // : await getApplicationDocumentsDirectory();
    return directory.path;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _download,
        child: Icon(Icons.file_download),
      ),
    );
  }
}

Here's my flutter doctor results:

[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.14.6 18G95, locale en-ID)
    • Flutter version 1.12.13+hotfix.5 at /Users/ictmacbook2/flutter
    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800
    • Engine revision 2994f7e1e6
    • Dart version 2.7.0


[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at /Users/ictmacbook2/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 10.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.3, Build version 10G8
    • CocoaPods version 1.7.5

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 43.0.1
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.42.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.8.1

[✓] Connected device (1 available)
    • iPad • 1ba96acf871024d9097348342ff6d84fe5013c16 • ios • iOS 12.4.1

• No issues found!
Goiter answered 24/2, 2020 at 8:12 Comment(1)
Updated your issue on github with some information that might help. Namely, pinpointed the errors locations ERROR_INVALID_TASK_ID on iOS and invalid_task_id on Android. When solution is found please make sure it's posted here and accepted. The problem in my opinion lies in unsuccessful enqueuing of tasks or unsuccessful resuming of enqueued tasks.Sennet
G
3

According to the suggestions on this issue I opened on GitHub, I changed my if from if (status.toString() == "DownloadTaskStatus(3)") to if (status.toString() == "DownloadTaskStatus(3)" && progress == 100 &&id!=null).

For good measure, I also queried for the specific task we're looking for in my downloadListener function, like so:

  _downloadListener() {
    IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
    _port.listen((dynamic data) {
      String id = data[0];
      DownloadTaskStatus status = data[1];
      int progress = data[2];
      if (status.toString() == "DownloadTaskStatus(3)" && progress == 100 && id != null) {
          String query = "SELECT * FROM task WHERE task_id='" + id + "'";
          var tasks = FlutterDownloader.loadTasksWithRawQuery(query: query);
          //if the task exists, open it
          if (tasks != null) FlutterDownloader.open(taskId: id);
      }
    });
    FlutterDownloader.registerCallback(downloadCallback);
  }

It all runs smoothly now. Just a note, whenever I hot refresh, the tasks would just be enqueued and not executed. Had to abort and rebuild the app for the downloads to work properly again.

Goiter answered 26/2, 2020 at 6:32 Comment(2)
Can we please reach out iam having some problems with the pluginSthilaire
Dude, you are god. Works like a charmUnderwent
A
0

I think it's a concurrency problem, where that state is turned to complete before the task has been saved to the SQLite. and when I add a slight delay and it works fine.

this is my code

if (status == DownloadTaskStatus.complete) {
        _state = status;
        context.showSnackbarSuccess(context.locale.downloadSuccess);
        await Future.delayed(const Duration(seconds: 1));
        unawaited(FlutterDownloader.open(taskId: taskId));
        return;
      }
Annabel answered 2/1, 2023 at 15:21 Comment(0)
H
0

Error while opening the file after the download flutter: not found task corresponding to given task id This Worked for me

Hedonism answered 22/9 at 11:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.