781flyingdutchman / background_downloader

Flutter plugin for file downloads and uploads
Other
162 stars 76 forks source link

Single Download Progress Notification for Multiple URLs #332

Closed Seyien closed 5 months ago

Seyien commented 5 months ago

configureNotification, ForGroup, group, groupNotificationId, FileDownloader().enqueue and downloadBatch for 1 day, I couldn't get exactly what I wanted.

All the results led me to notifications created specifically for a single url. While some of them were creating notifications one after the other, some of them were providing information about the download on a single notification but on a single url.

What I want is to show a notification before all these downloads start, specify the total task and show a notification as a percentage of completion over the completed task.

For example

The user clicks on one or more download buttons to download a total of 60 images of whatever they choose. I would like to start this as download start, success 0 and total tasks available, and increase them one by one as the images are downloaded and show the difference as a percentage.

If there is such a feature and I didn't see it, sorry for that, I didn't see it.

Seyien commented 5 months ago

it looks like I was able to do this with another notification package. Thanks for everything though.

781flyingdutchman commented 5 months ago

Hi, happy to help. First, I don't think you'll be able to accomplish this with another package, as when you app moves to the background you won't be getting updates, and you won't be able to change your notification counter. So, unless you are no concerned about true background downloads, you will need to use the built-in groupnotification.

To take the 60 task example, let's call that a group of task and you give that group a unique id, yourGroupId. You configure a notification for that group using

FileDownloader.configureNotificationForGroup(yourGroupId
            running: const TaskNotification(
                '{numFinished} out of {numTotal}', 'Progress = {progress}'),
            complete:
                const TaskNotification('Done!', 'Loaded {numTotal} files'),
            error: const TaskNotification(
                'Error', '{numFailed}/{numTotal} failed'),
            progressBar: true,
            groupNotificationId: yourGroupId);

This ensure that every task that is part of group 'groupId' will use this notification.

You then enqueue every one of you 60 tasks, but make sure that each task's group is set to yourGroupId.

That should get you the behavior that I think you want.

Seyien commented 5 months ago

I tried what you suggested and in my example it shows 60 notification badge. If this number is even more, there will be high values like 1000.

Is there an option not to show the number of notification badge?

781flyingdutchman commented 5 months ago

Depends on the platform. On Android, it should update the notification so there is only one. On iOS unfortunately that option does not exist, so it will generate a new notification if the text of the notification changes (so if you have a counter, it will indeed generate a new notification for every update). My suggestion would be to show only a "download in progress" type message on iOS, so that it doesn't repeat.

You said you had managed to do this with a different package, and I'm curious how they solved that issue on iOS. Can you share what package you used and the code you used to update (without triggering new notifications for every update)?

781flyingdutchman commented 5 months ago

Specific to badge count, I think that's an app setting (to show that) on both platforms. When you describe behavior can you be specific as to what platform? Thanks!

Seyien commented 5 months ago

I'm trying to improve myself on android devices with flutter. The package I mentioned above is "awesome_notifications: ^0.9.3+1".

As far as they mentioned, I can only implement the solution I mentioned on the android side. I haven't tried whether the application works for a long time in the background or not.

Also I wrote 60 notifications, I should have written Badge :,)

The code I wrote is realized with some controls and increasing the counters in the relevant places. However, while trying it on my physical phone, I realized that the number of badges is around 200 :,)

Maybe the "awesome" package has a feature to not show badges. I didn't look much.

some of the places I manage in my code

  Future<void> startBulkDownload() async {
    if (isDownloading.value == false) {
      currentStep.value = 0;
      maxTask.value = 0;
    }
    final int tempMaxTask = maxTask.value;
    isDownloading.value = true;
    await maxTaskCount();

    if (maxTask.value == tempMaxTask) return;

    // Initialize notification
    await NotificationService.showNotification(
      channelKey: 'progress_bar',
      title: '...',
      body: '0%',
      notificationLayout: NotificationLayout.ProgressBar,
      progress: 1.0,
      locked: true,
    );

          taskStatusCallback: (update) async {
            if (update.status == TaskStatus.complete && maxTask.value != 0) {
              currentStep.value++;
              if (kDebugMode) {
                print("currentStep: ${currentStep.value}");
                print("maxTask: ${maxTask.value}");
              }
              await NotificationService.showNotification(
                channelKey: 'progress_bar',
                title: '',
                notificationLayout: NotificationLayout.ProgressBar,
                progress: (currentStep.value / maxTask.value * 100).floor().toDouble(),
                locked: true,
              );
              if (currentStep.value == maxTask.value) {
                isDownloading.value = false;
                currentStep.value = 0;
                maxTask.value = 0;
                await Future.delayed(const Duration(milliseconds: 700));
                // Show completion notification
                await NotificationService.showNotification(
                  channelKey: 'progress_bar',
                  title: '',
                  body: '',
                  notificationLayout: NotificationLayout.Default,
                );
              }
            }
          },
781flyingdutchman commented 5 months ago

I don't think the downloader package explicitly asks for a badge indicator so not sure where that is coming from. The code you show using the awesome package won't work as soon as your app moves to the background. It will then stop receiving updates and the counter will stop and not reflect the actual download count. That's why you have to use group notifications from the background downloader package.

Seyien commented 5 months ago

Thank you very much for your replies.