flutter_downloader icon indicating copy to clipboard operation
flutter_downloader copied to clipboard

Task filename and savedDir isn't updated when using saveInPublicStorage (Android)

Open Berdsen opened this issue 11 months ago • 10 comments

Describe the bug When downloading a file to the public downloads folder using the saveInPublicStorage= true, the task properties aren't updated. So when the finished callback comes back and I wan't to open the file, FlutterDownloader.open(taskId) won't work.

To Reproduce

Steps to reproduce the behavior:

  1. Download a file
final taskId = await FlutterDownloader.enqueue(
      url: urlString,
      savedDir: path!,
      headers: {'Cookie': cookies},
      showNotification: true,
      openFileFromNotification: true,
      saveInPublicStorage: Platform.isAndroid ? true : false,
);
  1. Try to open fhe file from within portListener from callback
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
_port.listen((message) {
      String id = message[0];

      Future.delayed(const Duration(seconds: 1), () {
        FlutterDownloader.loadTasksWithRawQuery(query: "SELECT * FROM task WHERE task_id='$id'").then((tasks) {
          if (tasks == null || tasks.isEmpty) return;

          final task = tasks.first;
          final taskFilename = task.filename;
          final taskSavedDir = task.savedDir;
          
          // here filename and savedDir are not correct
          FlutterDownloader.open(taskId: id).then((value) => {debugPrint('Open file: $value')});
        });
      });
 });

Expected behavior

The task should (like the notification) have the correct filename and saved dir to let FlutterDownloader.open work

In DownloadWorker.kt line 387ff. the taskDao.update isn't run with the new filename

Device information:

  • Device: Android
  • OS: Android v13
  • plugin version v1.11.6

Berdsen avatar Feb 28 '24 09:02 Berdsen

@Berdsen Please open the file once the download progress is completed.

You can check the status and progress like this _port.listen((dynamic data) { final taskId = (data as List)[0] as String; final status = DownloadTaskStatus.fromInt(data[1] as int); final progress = data[2] as int; });

balajiks-dev avatar Mar 05 '24 05:03 balajiks-dev

Ah sorry. I forgot to mention, that the sender just sends the message when the status is completed and the progress is equal to 100. But unfortunately the file doesn't exist in the given path, because the saved filepath in the task entry remains in the application directory (../Android/data/...) but is saved correctly in the Downloads folder

Berdsen avatar Mar 05 '24 07:03 Berdsen

@Berdsen If you don't want to open the file. Comment this line

FlutterDownloader.open(taskId: id).then((value) => {debugPrint('Open file: $value')});

balajiks-dev avatar Mar 05 '24 08:03 balajiks-dev

@Berdsen Can you please add console log output by setting debug in Initialization.

await FlutterDownloader.initialize(debug: true);

balajiks-dev avatar Mar 05 '24 08:03 balajiks-dev

@balajiks-dev The debug output I get is the following

I/flutter (13527): ### - onDownloadStart
D/HostConnection(13527): createUnique: call
D/HostConnection(13527): HostConnection::get() New Host Connection established 0xb400007ae95f9f90, tid 13729
D/HostConnection(13527): HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_vulkan_queue_submit_with_commands ANDROID_EMU_sync_buffer_data ANDROID_EMU_vulkan_async_qsri ANDROID_EMU_read_color_buffer_dma ANDROID_EMU_hwc_multi_configs GL_OES_EGL_image_external_essl3 GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_3_0 
D/EGL_emulation(13527): eglMakeCurrent: 0xb400007ae95f9ed0: ver 3 0 (tinfo 0x7cfea70380) (first time)
D/DownloadWorker(13527): DownloadWorker{url=<URL>,filename=null,savedDir=/storage/emulated/0/Android/data/com.example.app/files,header={ /* STRIPPED */ },isResume=false,status=ENQUEUED
D/DownloadWorker(13527): Update notification: {notificationId: 2, title: <URL>, status: RUNNING, progress: 0}
D/DownloadWorker(13527): Open connection to <URL>
D/DownloadWorker(13527): Headers = { /* STRIPPED */ }
D/DownloadWorker(13527): Content-Length = 70150
D/DownloadWorker(13527): Charset = null
D/DownloadWorker(13527): Content-Disposition = attachment; filename=FILENAME.pdf
D/DownloadWorker(13527): fileName = FILENAME.pdf
D/DownloadWorker(13527): Update notification: {notificationId: 2, title: FILENAME.pdf, status: RUNNING, progress: 5}
8 D/DownloadWorker(13527): Update too frequently!!!!, this should be dropped
D/DownloadWorker(13527): Setting an intent to open the file /storage/emulated/0/Download/FILENAME.pdf
D/DownloadWorker(13527): Update too frequently!!!!, but it is the final update, we should sleep a second to ensure the update call can be processed
D/DownloadWorker(13527): Update notification: {notificationId: 2, title: FILENAME.pdf, status: COMPLETE, progress: 100}
D/DownloadWorker(13527): File downloaded
I/flutter (13527): Task: 76385681-c2f2-43e9-b72a-fe37b9a11d0b, status: DownloadTaskStatus.complete, progress: 100
I/WM-WorkerWrapper(13527): Worker result SUCCESS for Work [ id=76385681-c2f2-43e9-b72a-fe37b9a11d0b, tags={ flutter_download_task, vn.hunghd.flutterdownloader.DownloadWorker } ]
I/flutter (13527): Open file: true

But in the code part, where the the task is read the follwing savedDir is retrieved from the task

savedDir: "/storage/emulated/0/Android/data/com.example.app/files"

_port.listen((message) {
      String id = message[0];

      Future.delayed(const Duration(seconds: 1), () {
        FlutterDownloader.loadTasksWithRawQuery(query: "SELECT * FROM task WHERE task_id='$id'").then((tasks) {
          if (tasks == null || tasks.isEmpty) return;

          final task = tasks.first;
          final taskId = task.taskId;
          final status = task.status;
          final progress = task.progress;

          debugPrint('Task: $taskId, status: $status, progress: $progress');

          FlutterDownloader.open(taskId: id).then((value) => {debugPrint('Open file: $value')});
        });
      });
    });

Berdsen avatar Mar 05 '24 09:03 Berdsen

@Berdsen See here savedDir=/storage/emulated/0/Android/data/com.example.app/files

Add the file name correctly and once File downloaded. Check the local storage of the file.

balajiks-dev avatar Mar 05 '24 09:03 balajiks-dev

Yes. But when the saveInPublicStorage flag is set, the file doesn't exist as /storage/emulated/0/Android/data/com.example.app/files/FILENAME.pdf but is stored as /storage/emulated/0/Download/FILENAME.pdf I could get the filename and rewrite the path, but if the file is downloaded multiple times, the flutter_downloader correctly adds a number like FILENAME (1).pdf and also this filename isn't populated to the task entry, which has just the start information savedDir and original filename

Berdsen avatar Mar 05 '24 10:03 Berdsen

@Berdsen Got your point. But I can't reproduce it. If possible, add example project in any public repo and share me the link here please.

balajiks-dev avatar Mar 05 '24 16:03 balajiks-dev

@balajiks-dev See here the repo Also check the TODO, where the problem can be seen

Berdsen avatar Mar 06 '24 10:03 Berdsen

@Berdsen Ok I will check and let you know in this week.

balajiks-dev avatar Mar 12 '24 05:03 balajiks-dev