0

I'm using flutter_downloader: ^1.9.1 to download files. It's working fine, The file gets downloaded in the download folder. But the issue is after the file is downloaded the notification wrongly shows as failed and, On the notification click it's not redirecting to the download folder. Your help will save my day.

void _download(String url) async {
    final status = await Permission.storage.request();

    if (status.isGranted) {
      final externalDir = await getExternalStorageDirectory();

      final id = await FlutterDownloader.enqueue(
        fileName: "LRMonoPhase4.mp3",
        url: 'https://www.kozco.com/tech/LRMonoPhase4.mp3',
        savedDir: '/storage/emulated/0/Download',
        showNotification: true,
        openFileFromNotification: true,
      );
    } else {
      print('Permission Denied');
    }
  }

This is the provider

<provider
    android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
    android:authorities="im.mingguang.mingguang_app.flutter_downloader.provider"
    android:exported="false"
    android:grantUriPermissions="true"
    android:requestLegacyExternalStorage="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

Finally this is the Log

D/DownloadWorker( 4447): DownloadWorker{url=https://www.kozco.com/tech/LRMonoPhase4.mp3,filename=LRMonoPhase4.mp3,savedDir=/data/user/0/com.rsoft.salezrobot/app_flutter,header={},isResume=false,status=ENQUEUED
D/DownloadWorker( 4447): Update notification: {notificationId: 10, title: LRMonoPhase4.mp3, status: RUNNING, progress: 0}
D/DownloadWorker( 4447): Open connection to https://www.kozco.com/tech/LRMonoPhase4.mp3
D/DownloadWorker( 4447): Headers = {}
D/TrafficStats( 4447): tagSocket(172) with statsTag=0xffffffff, statsUid=-1
D/EGL_emulation( 4447): app_time_stats: avg=21.56ms min=5.27ms max=97.80ms count=47
I/trustAllHosts( 4447): checkServerTrusted
D/DownloadWorker( 4447): Content-Type = audio/mpeg
D/DownloadWorker( 4447): Content-Length = 931630
D/DownloadWorker( 4447): Charset = null
D/DownloadWorker( 4447): fileName = LRMonoPhase4.mp3
D/DownloadWorker( 4447): Update notification: {notificationId: 10, title: LRMonoPhase4.mp3, status: RUNNING, progress: 1}
D/EGL_emulation( 4447): app_time_stats: avg=19.26ms min=7.83ms max=39.89ms count=52
D/DownloadWorker( 4447): Update too frequently!!!!, this should be dropped
D/DownloadWorker( 4447): Update too frequently!!!!, this should be dropped

enter image description here

enter image description here

Anand
  • 4,355
  • 2
  • 35
  • 45

2 Answers2

2
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <root-path
        name="root"
        path="." />
</paths>

This solve the problem , just create a new file named provider_paths.xml and add the above code to the file

the path to put the file is

android\app\src\main\res\xml\provider_paths.xml

Just create folder named xml in the res folder after that restart the app and you are good to go.

Above error is caused by a specific error that show that flutter_downloader cannot find the file, if you read properly the error log there is this error

Failed to find configured root that contains /data/data/com.<my-company-name>.<my-package.name>/app_flutter/...
1

Based on the documentation something should be missing on your android manifest file,

<provider
    android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
    android:authorities="${applicationId}.flutter_downloader.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

I don't know if it is linked to the "failed" message displayed in the notification but you should check the logs to have more infos.

Finally, you have to define a callback.

await FlutterDownloader.registerCallback(callback); 

More informations about the callback.

ReceivePort _port = ReceivePort();

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

  IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
  _port.listen((dynamic data) {
    String id = data[0];
    DownloadTaskStatus status = data[1];
    int progress = data[2];
    setState((){ });
  });

  FlutterDownloader.registerCallback(downloadCallback);
}

@override
void dispose() {
  IsolateNameServer.removePortNameMapping('downloader_send_port');
  super.dispose();
}

@pragma('vm:entry-point')
static void downloadCallback(String id, DownloadTaskStatus status, int progress) {
  final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
  send.send([id, status, progress]);
}

Note : On Android, you can only open a downloaded file if it is placed in the external storage and there's at least one application that can read that file type on your device.

Example of working log :

I/trustAllHosts(20572): checkServerTrusted
D/DownloadWorker(20572): Content-Type = application/pdf
D/DownloadWorker(20572): Content-Length = 9263524
D/DownloadWorker(20572): Charset = null
D/DownloadWorker(20572): Content-Disposition = null
D/DownloadWorker(20572): fileName = 6014708.pdf
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Update too frequently!!!!, this should be dropped
D/DownloadWorker(20572): Setting an intent to open the file /storage/emulated/0/Download/6014708.pdf
D/DownloadWorker(20572): Update too frequently!!!!, but it is the final update, we should sleep a second to ensure the update call can be processed
D/DownloadWorker(20572): Update notification: {notificationId: 6, title: 6014708.pdf, status: COMPLETE, progress: 100}
D/DownloadWorker(20572): File downloaded
I/WM-WorkerWrapper(20572): Worker result SUCCESS for Work [ id=0b6d1bbe-7c7e-4f48-9783-baed5b3ade51, tags={ flutter_download_task, vn.hunghd.flutterdownloader.DownloadWorker } ]
Zhar
  • 3,330
  • 2
  • 24
  • 25
  • I done this already bt not works – Anand Nov 17 '22 at 04:15
  • I added the log chek now – Anand Nov 17 '22 at 04:31
  • is the log complete ? i added my log (debug mode) in my answer to compare. You should have something like "File downloaded" at the end. There is something strange with your progress @1 value too isn't it ? maybe that's why your status isn't complete it seems still RUNNING in your case – Zhar Nov 17 '22 at 10:01
  • do you use a real phone or emulator ? it's should have side effects with emulator – Zhar Nov 17 '22 at 10:10