Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File downloaded in background doesn't appear in the destination folder on some Android devices #39

Open
LMakshow opened this issue Jan 15, 2025 · 1 comment

Comments

@LMakshow
Copy link
Contributor

Is this a bug report, a feature request, or a question?

Bug report

Is the bug specific to iOS or Android? Or can it be reproduced on both platforms?

The bug is specific to Android and only to some Android devices, it doesn't reproduce on the tested Samsung and Pixel phones on Android 12, 13, and 15, and also emulators. European Xiaomi firmware seems not affected as well (tested on some Xiaomi Redmi)
The bug reproduces on my Xiaomi 11 Ultra, using Chinese (Localized) MiUI 14 on Android 13, and it might be related to the custom DownloadManager implementation of the Chinese vendor.

Environment

React native: 0.76.6
react-native-background-downloader: 3.2.6

Target Platform:
Android (13)

Steps to Reproduce

  1. Start downloading via app
  2. Close the app while the download is still in progress
  3. Wait till the download is finished
  4. Open the app

Expected Behavior

  1. The file should appear in the destination folder and the app can proceed with the checkForExistingDownloads() to process the download and completeHandler()

Actual Behavior

  1. RNBackgroundDownloader.checkForExistingDownloads() returns the task with the task.state === 'DONE' as expected, but the file is absent in the destination folder.

On this Xiaomi 11 Ultra, the downloaded file is placed in some temporary folder and deleted after the completeHandler() is called. To mitigate the issue, I'm currently using the following patch that implicitly triggers setFileChangesBeforeCompletion() function in the case of a download that is finished while the app is closed. This change ensures that the file is moved to the destination folder on all of the tested Android devices.

diff --git a/node_modules/@kesha-antonov/react-native-background-downloader/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java b/node_modules/@kesha-antonov/react-native-background-downloader/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java
index 2bf0895..cf8c355 100644
--- a/node_modules/@kesha-antonov/react-native-background-downloader/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java
+++ b/node_modules/@kesha-antonov/react-native-background-downloader/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java
@@ -369,12 +369,26 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
               RNBGDTaskConfig config = downloadIdToConfig.get(downloadId);
 
               if (config != null) {
+                int status = downloadStatus.getInt("status");
+                // Handle completed downloads that weren't processed
+                if (status == DownloadManager.STATUS_SUCCESSFUL) {
+                  String localUri = downloadStatus.getString("localUri");
+                  if (localUri != null) {
+                    try {
+                      Future<Boolean> future = setFileChangesBeforeCompletion(localUri, config.destination);
+                      future.get();
+                    } catch (Exception e) {
+                      Log.e(getName(), "Failed to move completed download: " + e.getMessage());
+                    }
+                  }
+                }
+
                 WritableMap params = Arguments.createMap();
 
                 params.putString("id", config.id);
                 params.putString("metadata", config.metadata);
-                Integer status = stateMap.get(downloadStatus.getInt("status"));
-                int state = status != null ? status : 0;
+                Integer mappedStatus = stateMap.get(downloadStatus.getInt("status"));
+                int state = mappedStatus != null ? mappedStatus : 0;
                 params.putInt("state", state);
 
                 double bytesDownloaded = downloadStatus.getDouble("bytesDownloaded");
@sudo-m3z1m
Copy link

Hi, I have about the same problem. The only difference is that my file does not disappear when downloading, but appears with the original name. The problem is that I need another - a specific file name after the download is complete.

Changing the source code does not quite suit me, is there a better solution to this problem now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants