@kesha-antonov/react-native-background-downloader 2.10.0 → 3.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,27 +8,14 @@ import com.facebook.react.bridge.Promise;
8
8
  import com.facebook.react.bridge.ReactApplicationContext;
9
9
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
10
  import com.facebook.react.bridge.ReactMethod;
11
- import com.facebook.react.bridge.Arguments;
12
11
  import com.facebook.react.bridge.ReadableMap;
13
12
  import com.facebook.react.bridge.ReadableMapKeySetIterator;
14
13
  import com.facebook.react.bridge.WritableArray;
15
14
  import com.facebook.react.bridge.WritableMap;
16
15
  import com.facebook.react.modules.core.DeviceEventManagerModule;
17
- import com.tonyodev.fetch2.Download;
18
- import com.tonyodev.fetch2core.Downloader;
19
- import com.tonyodev.fetch2okhttp.OkHttpDownloader;
20
- import com.tonyodev.fetch2.Error;
21
- import com.tonyodev.fetch2.Fetch;
22
- import com.tonyodev.fetch2.FetchConfiguration;
23
- import com.tonyodev.fetch2.FetchListener;
24
- import com.tonyodev.fetch2.NetworkType;
25
- import com.tonyodev.fetch2.Priority;
26
- import com.tonyodev.fetch2.Request;
27
- import com.tonyodev.fetch2.Status;
28
- import com.tonyodev.fetch2core.DownloadBlock;
29
- import com.tonyodev.fetch2core.Func;
30
- import com.tonyodev.fetch2.HttpUrlConnectionDownloader;
31
- import com.tonyodev.fetch2core.Downloader;
16
+
17
+ import android.app.DownloadManager;
18
+ import android.app.DownloadManager.Request;
32
19
 
33
20
  import org.jetbrains.annotations.NotNull;
34
21
 
@@ -42,16 +29,33 @@ import java.util.Date;
42
29
  import java.util.HashMap;
43
30
  import java.util.List;
44
31
  import java.util.Map;
32
+ import java.util.Scanner;
45
33
 
46
34
  import javax.annotation.Nullable;
47
35
 
48
- import okhttp3.OkHttpClient;
49
-
50
36
  import java.util.Set;
51
37
  import java.net.URL;
52
38
  import java.net.URLConnection;
39
+ import java.nio.file.Files;
40
+ import java.nio.file.StandardCopyOption;
41
+
42
+ import android.content.BroadcastReceiver;
43
+ import android.content.Context;
44
+ import android.content.Intent;
45
+ import android.content.IntentFilter;
46
+ import android.util.LongSparseArray;
47
+
48
+ import com.facebook.react.bridge.Callback;
53
49
 
54
- public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule implements FetchListener {
50
+ import java.util.ArrayList;
51
+ import java.util.Arrays;
52
+ import android.net.Uri;
53
+ import android.webkit.MimeTypeMap;
54
+ import android.database.Cursor;
55
+ import android.os.Build;
56
+ import android.os.Environment;
57
+
58
+ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
55
59
 
56
60
  private static final int TASK_RUNNING = 0;
57
61
  private static final int TASK_SUSPENDED = 1;
@@ -64,37 +68,117 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule imp
64
68
  private static final int ERR_FILE_NOT_FOUND = 3;
65
69
  private static final int ERR_OTHERS = 100;
66
70
 
67
- private static Map<Status, Integer> stateMap = new HashMap<Status, Integer>() {{
68
- put(Status.DOWNLOADING, TASK_RUNNING);
69
- put(Status.COMPLETED, TASK_COMPLETED);
70
- put(Status.PAUSED, TASK_SUSPENDED);
71
- put(Status.QUEUED, TASK_RUNNING);
72
- put(Status.CANCELLED, TASK_CANCELING);
73
- put(Status.FAILED, TASK_CANCELING);
74
- put(Status.REMOVED, TASK_CANCELING);
75
- put(Status.DELETED, TASK_CANCELING);
76
- put(Status.NONE, TASK_CANCELING);
77
- }};
78
-
79
- private Fetch fetch;
80
- private Map<String, Integer> idToRequestId = new HashMap<>();
81
- @SuppressLint("UseSparseArrays")
82
- private Map<Integer, RNBGDTaskConfig> requestIdToConfig = new HashMap<>();
71
+ private static Map<Integer, Integer> stateMap = new HashMap<Integer, Integer>() {
72
+ {
73
+ put(DownloadManager.STATUS_FAILED, TASK_CANCELING);
74
+ put(DownloadManager.STATUS_PAUSED, TASK_SUSPENDED);
75
+ put(DownloadManager.STATUS_PENDING, TASK_RUNNING);
76
+ put(DownloadManager.STATUS_RUNNING, TASK_RUNNING);
77
+ put(DownloadManager.STATUS_SUCCESSFUL, TASK_COMPLETED);
78
+ }
79
+ };
80
+
81
+ private Downloader downloader;
82
+
83
+ private Map<String, Long> condigIdToDownloadId = new HashMap<>();
84
+ private Map<Long, RNBGDTaskConfig> downloadIdToConfig = new HashMap<>();
83
85
  private DeviceEventManagerModule.RCTDeviceEventEmitter ee;
84
- private Date lastProgressReport = new Date();
85
- private HashMap<String, WritableMap> progressReports = new HashMap<>();
86
+ private Map<String, OnProgress> onProgressThreads = new HashMap<>();
87
+
86
88
  private static Object sharedLock = new Object();
87
89
 
90
+ BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
91
+ @Override
92
+ public void onReceive(Context context, Intent intent) {
93
+ Log.d(getName(), "RNBD: onReceive-1");
94
+ try {
95
+ long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
96
+ Log.d(getName(), "RNBD: onReceive-2 " + downloadId);
97
+
98
+ RNBGDTaskConfig config = downloadIdToConfig.get(downloadId);
99
+
100
+ if (config != null) {
101
+ Log.d(getName(), "RNBD: onReceive-3");
102
+ WritableMap downloadStatus = downloader.checkDownloadStatus(downloadId);
103
+ int status = downloadStatus.getInt("status");
104
+
105
+ Log.d(getName(), "RNBD: onReceive: status - " + status);
106
+
107
+ stopTrackingProgress(config.id);
108
+
109
+ synchronized (sharedLock) {
110
+ switch (status) {
111
+ case DownloadManager.STATUS_SUCCESSFUL: {
112
+ // MOVES FILE TO DESTINATION
113
+ String localUri = downloadStatus.getString("localUri");
114
+ Log.d(getName(), "RNBD: onReceive: localUri " + localUri + " destination " + config.destination);
115
+ File file = new File(localUri);
116
+ Log.d(getName(), "RNBD: onReceive: file exists " + file.exists());
117
+ File dest = new File(config.destination);
118
+ Log.d(getName(), "RNBD: onReceive: dest exists " + dest.exists());
119
+ Files.move(file.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
120
+
121
+ WritableMap params = Arguments.createMap();
122
+ params.putString("id", config.id);
123
+ params.putString("location", config.destination);
124
+
125
+ ee.emit("downloadComplete", params);
126
+ break;
127
+ }
128
+ case DownloadManager.STATUS_FAILED: {
129
+ Log.e(getName(), "Error in enqueue: " + downloadStatus.getInt("status") + ":"
130
+ + downloadStatus.getInt("reason") + ":" + downloadStatus.getString("reasonText"));
131
+
132
+ WritableMap params = Arguments.createMap();
133
+ params.putString("id", config.id);
134
+ params.putInt("errorCode", downloadStatus.getInt("reason"));
135
+ params.putString("error", downloadStatus.getString("reasonText"));
136
+ ee.emit("downloadFailed", params);
137
+ break;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ } catch (Exception e) {
143
+ Log.e(getName(), "downloadReceiver: onReceive. " + Log.getStackTraceString(e));
144
+ }
145
+ }
146
+ };
147
+
88
148
  public RNBackgroundDownloaderModule(ReactApplicationContext reactContext) {
89
149
  super(reactContext);
90
150
 
91
151
  ReadableMap emptyMap = Arguments.createMap();
92
152
  this.initDownloader(emptyMap);
153
+
154
+ downloader = new Downloader(reactContext);
155
+
156
+ IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
157
+ compatRegisterReceiver(reactContext, downloadReceiver, filter, true);
158
+ }
159
+
160
+ // TAKEN FROM
161
+ // https://github.com/facebook/react-native/pull/38256/files#diff-d5e21477eeadeb0c536d5870f487a8528f9a16ae928c397fec7b255805cc8ad3
162
+ private void compatRegisterReceiver(Context context, BroadcastReceiver receiver, IntentFilter filter,
163
+ boolean exported) {
164
+ if (Build.VERSION.SDK_INT >= 34 && context.getApplicationInfo().targetSdkVersion >= 34) {
165
+ context.registerReceiver(
166
+ receiver, filter, exported ? Context.RECEIVER_EXPORTED : Context.RECEIVER_NOT_EXPORTED);
167
+ } else {
168
+ context.registerReceiver(receiver, filter);
169
+ }
170
+ }
171
+
172
+ private void stopTrackingProgress(String configId) {
173
+ OnProgress onProgressTh = onProgressThreads.get(configId);
174
+ if (onProgressTh != null) {
175
+ onProgressTh.interrupt();
176
+ onProgressThreads.remove(configId);
177
+ }
93
178
  }
94
179
 
95
180
  @Override
96
181
  public void onCatalystInstanceDestroy() {
97
- fetch.close();
98
182
  }
99
183
 
100
184
  @Override
@@ -132,46 +216,27 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule imp
132
216
  constants.put("TaskSuspended", TASK_SUSPENDED);
133
217
  constants.put("TaskCanceling", TASK_CANCELING);
134
218
  constants.put("TaskCompleted", TASK_COMPLETED);
135
- constants.put("PriorityHigh", Priority.HIGH.getValue());
136
- constants.put("PriorityNormal", Priority.NORMAL.getValue());
137
- constants.put("PriorityLow", Priority.LOW.getValue());
138
- constants.put("OnlyWifi", NetworkType.WIFI_ONLY.getValue());
139
- constants.put("AllNetworks", NetworkType.ALL.getValue());
219
+
140
220
  return constants;
141
221
  }
142
222
 
143
223
  @ReactMethod
144
224
  public void initDownloader(ReadableMap options) {
145
- if (fetch != null) {
146
- fetch.close();
147
- fetch = null;
148
- }
149
-
150
- Downloader.FileDownloaderType downloaderType = options.getString("type") == "parallel"
151
- ? Downloader.FileDownloaderType.PARALLEL
152
- : Downloader.FileDownloaderType.SEQUENTIAL;
153
-
154
- OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
155
- final Downloader okHttpDownloader = new OkHttpDownloader(okHttpClient,
156
- downloaderType);
225
+ Log.d(getName(), "RNBD: initDownloader");
157
226
 
158
227
  loadConfigMap();
159
- FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this.getReactApplicationContext())
160
- .setDownloadConcurrentLimit(4)
161
- .setHttpDownloader(okHttpDownloader)
162
- .enableRetryOnNetworkGain(true)
163
- .setHttpDownloader(new HttpUrlConnectionDownloader(downloaderType))
164
- .build();
165
- fetch = Fetch.Impl.getInstance(fetchConfiguration);
166
- fetch.addListener(this);
228
+
229
+ // TODO. MAYBE REINIT DOWNLOADER
167
230
  }
168
231
 
169
- private void removeFromMaps(int requestId) {
170
- synchronized(sharedLock) {
171
- RNBGDTaskConfig config = requestIdToConfig.get(requestId);
232
+ private void removeFromMaps(long downloadId) {
233
+ Log.d(getName(), "RNBD: removeFromMaps");
234
+
235
+ synchronized (sharedLock) {
236
+ RNBGDTaskConfig config = downloadIdToConfig.get(downloadId);
172
237
  if (config != null) {
173
- idToRequestId.remove(config.id);
174
- requestIdToConfig.remove(requestId);
238
+ condigIdToDownloadId.remove(config.id);
239
+ downloadIdToConfig.remove(downloadId);
175
240
 
176
241
  saveConfigMap();
177
242
  }
@@ -179,11 +244,13 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule imp
179
244
  }
180
245
 
181
246
  private void saveConfigMap() {
182
- synchronized(sharedLock) {
247
+ Log.d(getName(), "RNBD: saveConfigMap");
248
+
249
+ synchronized (sharedLock) {
183
250
  File file = new File(this.getReactApplicationContext().getFilesDir(), "RNFileBackgroundDownload_configMap");
184
251
  try {
185
252
  ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
186
- outputStream.writeObject(requestIdToConfig);
253
+ outputStream.writeObject(downloadIdToConfig);
187
254
  outputStream.flush();
188
255
  outputStream.close();
189
256
  } catch (IOException e) {
@@ -193,31 +260,17 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule imp
193
260
  }
194
261
 
195
262
  private void loadConfigMap() {
263
+ Log.d(getName(), "RNBD: loadConfigMap");
264
+
196
265
  File file = new File(this.getReactApplicationContext().getFilesDir(), "RNFileBackgroundDownload_configMap");
197
266
  try {
198
267
  ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file));
199
- requestIdToConfig = (Map<Integer, RNBGDTaskConfig>) inputStream.readObject();
268
+ downloadIdToConfig = (Map<Long, RNBGDTaskConfig>) inputStream.readObject();
200
269
  } catch (IOException | ClassNotFoundException e) {
201
270
  e.printStackTrace();
202
271
  }
203
272
  }
204
273
 
205
- private int convertErrorCode(Error error) {
206
- if ((error == Error.FILE_NOT_CREATED)
207
- || (error == Error.WRITE_PERMISSION_DENIED)) {
208
- return ERR_NO_WRITE_PERMISSION;
209
- } else if ((error == Error.CONNECTION_TIMED_OUT)
210
- || (error == Error.NO_NETWORK_CONNECTION)) {
211
- return ERR_NO_INTERNET;
212
- } else if (error == Error.NO_STORAGE_SPACE) {
213
- return ERR_STORAGE_FULL;
214
- } else if (error == Error.FILE_NOT_FOUND) {
215
- return ERR_FILE_NOT_FOUND;
216
- } else {
217
- return ERR_OTHERS;
218
- }
219
- }
220
-
221
274
  // JS Methods
222
275
  @ReactMethod
223
276
  public void download(ReadableMap options) {
@@ -226,277 +279,220 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule imp
226
279
  String destination = options.getString("destination");
227
280
  ReadableMap headers = options.getMap("headers");
228
281
  String metadata = options.getString("metadata");
282
+ int progressInterval = options.getInt("progressInterval");
283
+
284
+ boolean isAllowedOverRoaming = options.getBoolean("isAllowedOverRoaming");
285
+ boolean isAllowedOverMetered = options.getBoolean("isAllowedOverMetered");
286
+
287
+ Log.d(getName(), "RNBD: download " + id + " " + url + " " + destination + " " + metadata);
229
288
 
230
289
  if (id == null || url == null || destination == null) {
231
290
  Log.e(getName(), "id, url and destination must be set");
232
291
  return;
233
292
  }
234
293
 
235
- RNBGDTaskConfig config = new RNBGDTaskConfig(id, destination, metadata);
236
- final Request request = new Request(url, destination);
294
+ RNBGDTaskConfig config = new RNBGDTaskConfig(id, url, destination, metadata);
295
+ final Request request = new Request(Uri.parse(url));
296
+ request.setAllowedOverRoaming(isAllowedOverRoaming);
297
+ request.setAllowedOverMetered(isAllowedOverMetered);
298
+ request.setNotificationVisibility(Request.VISIBILITY_HIDDEN);
299
+ request.setRequiresCharging(false);
300
+
301
+ int uuid = (int) (System.currentTimeMillis() & 0xfffffff);
302
+ // GETS THE FILE EXTENSION FROM PATH
303
+ String extension = MimeTypeMap.getFileExtensionFromUrl(destination);
304
+
305
+ String fileName = uuid + "." + extension;
306
+ request.setDestinationInExternalFilesDir(this.getReactApplicationContext(), null, fileName);
307
+
308
+ // TOREMOVE
309
+ // request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS.toString(), fileName);
310
+ // request.setDestinationUri(Uri.parse(destination));
311
+
237
312
  if (headers != null) {
238
313
  ReadableMapKeySetIterator it = headers.keySetIterator();
239
314
  while (it.hasNextKey()) {
240
315
  String headerKey = it.nextKey();
241
- request.addHeader(headerKey, headers.getString(headerKey));
316
+ request.addRequestHeader(headerKey, headers.getString(headerKey));
242
317
  }
243
318
  }
244
- request.setPriority(options.hasKey("priority") ? Priority.valueOf(options.getInt("priority")) : Priority.NORMAL);
245
- request.setNetworkType(options.hasKey("network") ? NetworkType.valueOf(options.getInt("network")) : NetworkType.ALL);
246
319
 
247
- fetch.enqueue(request, new Func<Request>() {
248
- @Override
249
- public void call(Request download) {
250
- }
251
- }, new Func<Error>() {
252
- @Override
253
- public void call(Error error) {
254
- //An error occurred when enqueuing a request.
320
+ long downloadId = downloader.queueDownload(request);
255
321
 
256
- WritableMap params = Arguments.createMap();
257
- params.putString("id", id);
258
- params.putString("error", error.toString());
322
+ synchronized (sharedLock) {
323
+ condigIdToDownloadId.put(id, downloadId);
324
+ downloadIdToConfig.put(downloadId, config);
325
+ saveConfigMap();
259
326
 
260
- int convertedErrCode = convertErrorCode(error);
261
- params.putInt("errorcode", convertedErrCode);
262
- ee.emit("downloadFailed", params);
327
+ WritableMap downloadStatus = downloader.checkDownloadStatus(downloadId);
328
+ int status = downloadStatus.getInt("status");
263
329
 
264
- removeFromMaps(request.getId());
265
- fetch.remove(request.getId());
330
+ Log.d(getName(), "RNBD: download-1. status: " + status + " downloadId: " + downloadId);
266
331
 
267
- Log.e(getName(), "Error in enqueue: " + error.toString() + ":" + error.getValue());
268
- }
332
+ if (config.reportedBegin) {
333
+ return;
269
334
  }
270
- );
271
335
 
272
- synchronized(sharedLock) {
273
- lastProgressReport = new Date();
274
- idToRequestId.put(id, request.getId());
275
- requestIdToConfig.put(request.getId(), config);
336
+ config.reportedBegin = true;
276
337
  saveConfigMap();
338
+
339
+ Log.d(getName(), "RNBD: download-2 downloadId: " + downloadId);
340
+ // report begin & progress
341
+ //
342
+ // overlaped with thread to not block main thread
343
+ new Thread(new Runnable() {
344
+ public void run() {
345
+ try {
346
+ Log.d(getName(), "RNBD: download-3 downloadId: " + downloadId);
347
+
348
+ while (true) {
349
+ WritableMap downloadStatus = downloader.checkDownloadStatus(downloadId);
350
+ int status = downloadStatus.getInt("status");
351
+
352
+ Log.d(getName(), "RNBD: download-3.1 " + status + " downloadId: " + downloadId);
353
+
354
+ if (status == DownloadManager.STATUS_RUNNING) {
355
+ break;
356
+ }
357
+ if (status == DownloadManager.STATUS_FAILED || status == DownloadManager.STATUS_SUCCESSFUL) {
358
+ Log.d(getName(), "RNBD: download-3.2 " + status + " downloadId: " + downloadId);
359
+ Thread.currentThread().interrupt();
360
+ }
361
+
362
+ Thread.sleep(500);
363
+ }
364
+
365
+ // EMIT BEGIN
366
+ OnBegin onBeginTh = new OnBegin(config, ee);
367
+ onBeginTh.start();
368
+ // wait for onBeginTh to finish
369
+ onBeginTh.join();
370
+
371
+ Log.d(getName(), "RNBD: download-4 downloadId: " + downloadId);
372
+ OnProgress onProgressTh = new OnProgress(config, downloadId, ee, downloader, progressInterval);
373
+ onProgressThreads.put(config.id, onProgressTh);
374
+ onProgressTh.start();
375
+ Log.d(getName(), "RNBD: download-5 downloadId: " + downloadId);
376
+ } catch (Exception e) {
377
+ }
378
+ }
379
+ }).start();
380
+ Log.d(getName(), "RNBD: download-6 downloadId: " + downloadId);
277
381
  }
278
382
  }
279
383
 
384
+ // TODO: NOT WORKING WITH DownloadManager FOR NOW
280
385
  @ReactMethod
281
- public void pauseTask(String identifier) {
282
- synchronized(sharedLock) {
283
- Integer requestId = idToRequestId.get(identifier);
284
- if (requestId != null) {
285
- fetch.pause(requestId);
386
+ public void pauseTask(String configId) {
387
+ Log.d(getName(), "RNBD: pauseTask " + configId);
388
+
389
+ synchronized (sharedLock) {
390
+ Long downloadId = condigIdToDownloadId.get(configId);
391
+ if (downloadId != null) {
392
+ downloader.pauseDownload(downloadId);
286
393
  }
287
394
  }
288
395
  }
289
396
 
397
+ // TODO: NOT WORKING WITH DownloadManager FOR NOW
290
398
  @ReactMethod
291
- public void resumeTask(String identifier) {
292
- synchronized(sharedLock) {
293
- Integer requestId = idToRequestId.get(identifier);
294
- if (requestId != null) {
295
- fetch.resume(requestId);
399
+ public void resumeTask(String configId) {
400
+ Log.d(getName(), "RNBD: resumeTask " + configId);
401
+
402
+ synchronized (sharedLock) {
403
+ Long downloadId = condigIdToDownloadId.get(configId);
404
+ if (downloadId != null) {
405
+ downloader.resumeDownload(downloadId);
296
406
  }
297
407
  }
298
408
  }
299
409
 
300
410
  @ReactMethod
301
- public void stopTask(String identifier) {
302
- synchronized(sharedLock) {
303
- Integer requestId = idToRequestId.get(identifier);
304
- if (requestId != null) {
305
- fetch.cancel(requestId);
411
+ public void stopTask(String configId) {
412
+ Log.d(getName(), "RNBD: stopTask-1 " + configId);
413
+
414
+ synchronized (sharedLock) {
415
+ Long downloadId = condigIdToDownloadId.get(configId);
416
+ Log.d(getName(), "RNBD: stopTask-2 " + configId + " downloadId " + downloadId);
417
+ if (downloadId != null) {
418
+ // DELETES CONFIG HERE SO receiver WILL NOT THROW ERROR DOWNLOAD_FAILED TO THE
419
+ // USER
420
+ removeFromMaps(downloadId);
421
+ stopTrackingProgress(configId);
422
+
423
+ downloader.cancelDownload(downloadId);
306
424
  }
307
425
  }
308
426
  }
309
427
 
310
428
  @ReactMethod
311
- public void checkForExistingDownloads(final Promise promise) {
312
- fetch.getDownloads(new Func<List<Download>>() {
313
- @Override
314
- public void call(@NotNull List<Download> downloads) {
315
- WritableArray foundIds = Arguments.createArray();
316
-
317
- synchronized(sharedLock) {
318
- for (Download download : downloads) {
319
- if (requestIdToConfig.containsKey(download.getId())) {
320
- RNBGDTaskConfig config = requestIdToConfig.get(download.getId());
321
- WritableMap params = Arguments.createMap();
322
- params.putString("id", config.id);
323
- params.putString("metadata", config.metadata);
324
- params.putInt("state", stateMap.get(download.getStatus()));
325
- params.putInt("bytesWritten", (int)download.getDownloaded());
326
- params.putInt("totalBytes", (int)download.getTotal());
327
- params.putDouble("percent", ((double)download.getProgress()) / 100);
328
-
329
- foundIds.pushMap(params);
330
-
331
- // TODO: MAYBE ADD headers
332
-
333
- idToRequestId.put(config.id, download.getId());
334
- config.reportedBegin = true;
335
- } else {
336
- fetch.delete(download.getId());
337
- }
338
- }
339
- }
340
-
341
- promise.resolve(foundIds);
342
- }
343
- });
344
- }
345
-
346
- // Fetch API
347
- @Override
348
- public void onCompleted(Download download) {
349
- synchronized(sharedLock) {
350
- RNBGDTaskConfig config = requestIdToConfig.get(download.getId());
351
- if (config != null) {
352
- WritableMap params = Arguments.createMap();
353
- params.putString("id", config.id);
354
- params.putString("location", config.destination);
355
-
356
- ee.emit("downloadComplete", params);
357
- }
358
-
359
- removeFromMaps(download.getId());
360
- if (!fetch.isClosed()) {
361
- fetch.remove(download.getId());
429
+ public void completeHandler(String configId, final Promise promise) {
430
+ Log.d(getName(), "RNBD: completeHandler-1 " + configId);
431
+
432
+ synchronized (sharedLock) {
433
+ Long downloadId = condigIdToDownloadId.get(configId);
434
+ Log.d(getName(), "RNBD: completeHandler-2 " + configId + " downloadId " + downloadId);
435
+ if (downloadId != null) {
436
+ removeFromMaps(downloadId);
437
+ // REMOVES DOWNLOAD FROM DownloadManager SO IT WOULD NOT BE RETURNED IN checkForExistingDownloads
438
+ downloader.cancelDownload(downloadId);
362
439
  }
363
440
  }
364
441
  }
365
442
 
366
- @Override
367
- public void onProgress(Download download, long l, long l1) {
368
- synchronized(sharedLock) {
369
- RNBGDTaskConfig config = requestIdToConfig.get(download.getId());
370
- if (config == null) {
371
- return;
372
- }
373
-
374
- WritableMap params = Arguments.createMap();
375
- params.putString("id", config.id);
376
-
377
- if (!config.reportedBegin) {
378
- config.reportedBegin = true;
379
-
380
- params.putInt("expectedBytes", (int)download.getTotal());
443
+ @ReactMethod
444
+ public void checkForExistingDownloads(final Promise promise) {
445
+ Log.d(getName(), "RNBD: checkForExistingDownloads-1");
381
446
 
382
- // TODO: MAKE IT IN CUSTOM DOWNLOADER
383
- // https://github.com/tonyofrancis/Fetch/issues/347#issuecomment-478349299
384
- Thread th = new Thread(() -> {
385
- try {
386
- WritableMap headersMap = Arguments.createMap();
447
+ WritableArray foundIds = Arguments.createArray();
387
448
 
388
- URL urlC = new URL(download.getUrl());
389
- URLConnection con = urlC.openConnection();
390
- Map<String,List<String>> headers = con.getHeaderFields();
391
- Set<String> keys = headers.keySet();
392
- for (String key : keys) {
393
- String val = con.getHeaderField(key);
394
- headersMap.putString(key, val);
395
- }
396
- params.putMap("headers", headersMap);
397
-
398
- ee.emit("downloadBegin", params);
399
- } catch (IOException e) {
400
- e.printStackTrace();
401
- }
402
- });
403
- new Thread(new Runnable() {
404
- public void run() {
405
- try {
406
- th.start();
407
- th.join();
408
- } catch (InterruptedException e) {
409
- e.printStackTrace();
410
- }
411
- }
412
- }).start();
413
- } else {
414
- params.putInt("written", (int)download.getDownloaded());
415
- params.putInt("total", (int)download.getTotal());
416
- params.putDouble("percent", ((double)download.getProgress()) / 100);
417
- progressReports.put(config.id, params);
418
- Date now = new Date();
419
- if (now.getTime() - lastProgressReport.getTime() > 250) {
420
- WritableArray reportsArray = Arguments.createArray();
421
- for (WritableMap report : progressReports.values()) {
422
- reportsArray.pushMap(report);
423
- }
424
- ee.emit("downloadProgress", reportsArray);
425
- lastProgressReport = now;
426
- progressReports.clear();
427
- }
428
- }
429
- }
430
- }
449
+ synchronized (sharedLock) {
450
+ try {
451
+ DownloadManager.Query downloadQuery = new DownloadManager.Query();
452
+ Cursor cursor = downloader.downloadManager.query(downloadQuery);
431
453
 
432
- @Override
433
- public void onPaused(Download download) {
434
- }
454
+ if (cursor.moveToFirst()) {
455
+ do {
456
+ WritableMap result = downloader.getDownloadStatus(cursor);
457
+ Long downloadId = Long.parseLong(result.getString("downloadId"));
435
458
 
436
- @Override
437
- public void onResumed(Download download) {
438
- }
459
+ if (downloadIdToConfig.containsKey(downloadId)) {
460
+ Log.d(getName(), "RNBD: checkForExistingDownloads-2");
461
+ RNBGDTaskConfig config = downloadIdToConfig.get(downloadId);
462
+ WritableMap params = Arguments.createMap();
463
+ params.putString("id", config.id);
464
+ params.putString("metadata", config.metadata);
465
+ params.putInt("state", stateMap.get(result.getInt("status")));
439
466
 
440
- @Override
441
- public void onCancelled(Download download) {
442
- synchronized(sharedLock) {
443
- removeFromMaps(download.getId());
444
- fetch.delete(download.getId());
445
- }
446
- }
467
+ int bytesDownloaded = result.getInt("bytesDownloaded");
468
+ params.putInt("bytesDownloaded", bytesDownloaded);
447
469
 
448
- @Override
449
- public void onRemoved(Download download) {
450
- }
470
+ int bytesTotal = result.getInt("bytesTotal");
471
+ params.putInt("bytesTotal", bytesTotal);
451
472
 
452
- @Override
453
- public void onDeleted(Download download) {
454
- }
473
+ params.putDouble("percent", ((double) bytesDownloaded / bytesTotal));
455
474
 
456
- @Override
457
- public void onAdded(Download download) {
458
- }
475
+ foundIds.pushMap(params);
459
476
 
460
- @Override
461
- public void onQueued(Download download, boolean b) {
462
- }
477
+ // TODO: MAYBE ADD headers
463
478
 
464
- @Override
465
- public void onWaitingNetwork(Download download) {
466
- }
479
+ condigIdToDownloadId.put(config.id, downloadId);
467
480
 
468
- @Override
469
- public void onError(Download download, Error error, Throwable throwable) {
470
- synchronized(sharedLock) {
471
- RNBGDTaskConfig config = requestIdToConfig.get(download.getId());
472
-
473
- if (config != null ) {
474
- WritableMap params = Arguments.createMap();
475
- params.putString("id", config.id);
476
-
477
- int convertedErrCode = convertErrorCode(error);
478
- params.putInt("errorcode", convertedErrCode);
479
-
480
- if (error == Error.UNKNOWN && throwable != null) {
481
- params.putString("error", throwable.getLocalizedMessage());
482
- Log.e(getName(), "UNKNOWN Error in download: " + throwable.getLocalizedMessage());
483
- } else {
484
- params.putString("error", error.toString());
485
- Log.e(getName(), "Error in download: " + error.toString() + ":" + error.getValue());
481
+ // TOREMOVE
482
+ // config.reportedBegin = true;
483
+ } else {
484
+ Log.d(getName(), "RNBD: checkForExistingDownloads-3");
485
+ downloader.cancelDownload(downloadId);
486
+ }
487
+ } while (cursor.moveToNext());
486
488
  }
487
- ee.emit("downloadFailed", params);
488
- }
489
489
 
490
- removeFromMaps(download.getId());
491
- fetch.remove(download.getId());
490
+ cursor.close();
491
+ } catch (Exception e) {
492
+ Log.e(getName(), "Error in checkForExistingDownloads: " + e.getLocalizedMessage());
493
+ }
492
494
  }
493
- }
494
495
 
495
- @Override
496
- public void onDownloadBlockUpdated(Download download, DownloadBlock downloadBlock, int i) {
497
- }
498
-
499
- @Override
500
- public void onStarted(Download download, List<? extends DownloadBlock> list, int i) {
496
+ promise.resolve(foundIds);
501
497
  }
502
498
  }