Open scgough opened 3 years ago
I encountered the same issue. When using .fetch().progress() instead of .config().fetch().progress() it works properly. I suspect the bound fetch function returned by config() might be the culprit, found in the js code. However I have not been able to find the root cause.
Digging through multiple download issues in Android, I also noticed progress not returning received and total bytes.
The culprit seemed to be
if (reportConfig != null && reportConfig.shouldReport(progress /* progress */)) {
if (contentLength() != -1) {
// For non-chunked downloads
reportProgress(mTaskId, bytesDownloaded, contentLength());
} else {
// For chunked downloads
if (!isEndMarkerReceived) {
// THIS INDICATED WE ARE ALWAYS SENDING 0 and -1 for chunked downloads.
reportProgress(mTaskId, 0, contentLength());
} else{
reportProgress(mTaskId, bytesDownloaded, bytesDownloaded);
}
}
}
Not sure how I could change the download to a non-chunked one but testing by replacing that line with
reportProgress(mTaskId, bytesDownloaded, bytesDownloaded);
I think in this/my case it is down to the fact I have useDownloadManager: true
set. When using Download Manager no progress event fires at all.
and when removing the useDownloadManager
application crashes!
I modified RNFetchBlobReq.java to solve it. Add this:
private final int QUERY = 1314;
private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
private Future<?> future;
private Handler mHandler = new Handler(new Handler.Callback() {
public boolean handleMessage(Message msg) {
switch (msg.what) {
case QUERY:
Bundle data = msg.getData();
long id = data.getLong("downloadManagerId");
if (id == downloadManagerId) {
Context appCtx = RNFetchBlob.RCTContext.getApplicationContext();
DownloadManager downloadManager = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
Cursor cursor = downloadManager.query(query);
if (cursor != null && cursor.moveToFirst()) {
long written = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
long total = cursor.getLong(cursor.getColumnIndex(
DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
cursor.close();
RNFetchBlobProgressConfig reportConfig = getReportProgress(taskId);
float progress = (total != -1) ? written / total : 0;
if (reportConfig != null && reportConfig.shouldReport(progress /* progress */)) {
WritableMap args = Arguments.createMap();
args.putString("taskId", String.valueOf(taskId));
args.putString("written", String.valueOf(written));
args.putString("total", String.valueOf(total));
args.putString("chunk", "");
RNFetchBlob.RCTContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(RNFetchBlobConst.EVENT_PROGRESS, args);
}
if (total == written) {
future.cancel(true);
}
}
}
}
return true;
}
});
@Override
public void run() {
// use download manager instead of default HTTP implementation
if (options.addAndroidDownloads != null && options.addAndroidDownloads.hasKey("useDownloadManager")) {
if (options.addAndroidDownloads.getBoolean("useDownloadManager")) {
....
// add this lines:
future = scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
Message msg = mHandler.obtainMessage();
Bundle data = new Bundle();
data.putLong("downloadManagerId", downloadManagerId);
msg.setData(data);
msg.what = QUERY;
mHandler.sendMessage(msg);
}
}, 0, 100, TimeUnit.MILLISECONDS);
//add lines end.
return;
}
....
}
//edit releaseTaskResource
private void releaseTaskResource() {
...
if (future != null && !future.isCancelled())
future.cancel(true);
if (scheduledExecutorService != null && !scheduledExecutorService.isShutdown())
scheduledExecutorService.shutdown();
}
@leonineli i tried to implement your code, but, now i'm receiving incompatibility with gradle. I receive the error of i need update my code to Gradle 7.0
@ebnersilva If it is difficult to change the code, you can use my fork, but I can't guarantee that it is the latest code.
yarn add li-rn-fetch-blob
hi @joltup, is there any chance that this fixes will be merged to your master?
Project package versions: rn-fetch-blob: 0.12.0 React: 16.11.0 RN: 0.62.2
Tested on: iOS: 14 Android: 11
Download Progress (Android):
I have a strange issue in that progress doesn't seem to be firing on Android for downloads. iOS works fine.
Download Usage:
I've done some digging around the java code but haven't found anything yet. I'm happy to contribute on this and add a PR so if anyone else is experiencing this issue and has any info let me know - let's try and get this sorted!