Ver código fonte

Merge branch '0.10.6'

Ben Hsieh 6 anos atrás
pai
commit
0ea4a4a0c3

+ 11
- 3
android.js Ver arquivo

@@ -21,18 +21,26 @@ function actionViewIntent(path:string, mime:string = 'text/plain') {
21 21
   if(Platform.OS === 'android')
22 22
     return RNFetchBlob.actionViewIntent(path, mime)
23 23
   else
24
-    return Promise.reject('RNFetchBlob.actionViewIntent only supports Android.')
24
+    return Promise.reject('RNFetchBlob.android.actionViewIntent only supports Android.')
25 25
 }
26 26
 
27 27
 function getContentIntent(mime:string) {
28 28
   if(Platform.OS === 'android')
29 29
     return RNFetchBlob.getContentIntent(mime)
30 30
   else
31
-    return Promise.reject('RNFetchBlob.getContentIntent only supports Android.')
31
+    return Promise.reject('RNFetchBlob.android.getContentIntent only supports Android.')
32
+}
33
+
34
+function addCompleteDownload(config) {
35
+  if(Platform.OS === 'android')
36
+    return RNFetchBlob.addCompleteDownload(config)
37
+  else
38
+    return Promise.reject('RNFetchBlob.android.addCompleteDownload only supports Android.')
32 39
 }
33 40
 
34 41
 
35 42
 export default {
36 43
   actionViewIntent,
37
-  getContentIntent
44
+  getContentIntent,
45
+  addCompleteDownload
38 46
 }

+ 29
- 0
android/src/main/java/com/RNFetchBlob/RNFetchBlob.java Ver arquivo

@@ -1,6 +1,7 @@
1 1
 package com.RNFetchBlob;
2 2
 
3 3
 import android.app.Activity;
4
+import android.app.DownloadManager;
4 5
 import android.content.Intent;
5 6
 import android.net.Uri;
6 7
 
@@ -15,6 +16,7 @@ import com.facebook.react.bridge.ReadableArray;
15 16
 import com.facebook.react.bridge.ReadableMap;
16 17
 
17 18
 // Cookies
19
+import com.facebook.react.bridge.WritableMap;
18 20
 import com.facebook.react.modules.network.ForwardingCookieHandler;
19 21
 import com.facebook.react.modules.network.CookieJarContainer;
20 22
 import com.facebook.react.modules.network.OkHttpClientProvider;
@@ -341,4 +343,31 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
341 343
 
342 344
     }
343 345
 
346
+    @ReactMethod
347
+    public void addCompleteDownload (ReadableMap config, Promise promise) {
348
+        DownloadManager dm = (DownloadManager) RNFetchBlob.RCTContext.getSystemService(RNFetchBlob.RCTContext.DOWNLOAD_SERVICE);
349
+        String path = RNFetchBlobFS.normalizePath(config.getString("path"));
350
+        if(path == null) {
351
+            promise.reject("RNFetchblob.addCompleteDownload can not resolve URI:" + config.getString("path"), "RNFetchblob.addCompleteDownload can not resolve URI:" + path);
352
+            return;
353
+        }
354
+        try {
355
+            WritableMap stat = RNFetchBlobFS.statFile(path);
356
+            dm.addCompletedDownload(
357
+                    config.hasKey("title") ? config.getString("title") : "",
358
+                    config.hasKey("description") ? config.getString("description") : "",
359
+                    true,
360
+                    config.hasKey("mime") ? config.getString("mime") : null,
361
+                    path,
362
+                    Long.valueOf(stat.getString("size")),
363
+                    config.hasKey("showNotification") && config.getBoolean("showNotification")
364
+            );
365
+            promise.resolve(null);
366
+        }
367
+        catch(Exception ex) {
368
+            promise.reject("RNFetchblob.addCompleteDownload failed", ex.getStackTrace().toString());
369
+        }
370
+
371
+    }
372
+
344 373
 }

+ 11
- 6
android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java Ver arquivo

@@ -250,10 +250,7 @@ public class RNFetchBlobFS {
250 250
                 CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
251 251
                 while ((cursor = fs.read(buffer)) != -1) {
252 252
                     encoder.encode(ByteBuffer.wrap(buffer).asCharBuffer());
253
-                    String chunk = new String(buffer);
254
-                    if(cursor != bufferSize) {
255
-                        chunk = chunk.substring(0, cursor);
256
-                    }
253
+                    String chunk = new String(buffer, 0, cursor);
257 254
                     emitStreamEvent(streamId, "data", chunk);
258 255
                     if(tick > 0)
259 256
                         SystemClock.sleep(tick);
@@ -882,13 +879,21 @@ public class RNFetchBlobFS {
882 879
         return false;
883 880
     }
884 881
 
882
+    /**
883
+     * Normalize the path, remove URI scheme (xxx://) so that we can handle it.
884
+     * @param path URI string.
885
+     * @return Normalized string
886
+     */
885 887
     static String normalizePath(String path) {
886 888
         if(path == null)
887 889
             return null;
888
-        Uri uri = Uri.parse(path);
889
-        if(uri.getScheme() == null) {
890
+        if(!path.matches("\\w+\\:.*"))
890 891
             return path;
892
+        if(path.startsWith("file://")) {
893
+            return path.replace("file://", "");
891 894
         }
895
+
896
+        Uri uri = Uri.parse(path);
892 897
         if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
893 898
             return path;
894 899
         }

+ 8
- 14
ios/RNFetchBlobNetwork.m Ver arquivo

@@ -82,6 +82,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
82 82
     NSMutableArray * redirects;
83 83
     ResponseFormat responseFormat;
84 84
     BOOL * followRedirect;
85
+    BOOL backgroundTask;
85 86
 }
86 87
 
87 88
 @end
@@ -168,6 +169,8 @@ NSOperationQueue *taskQueue;
168 169
     self.expectedBytes = 0;
169 170
     self.receivedBytes = 0;
170 171
     self.options = options;
172
+    
173
+    backgroundTask = [options valueForKey:@"IOSBackgroundTask"] == nil ? NO : [[options valueForKey:@"IOSBackgroundTask"] boolValue];
171 174
     followRedirect = [options valueForKey:@"followRedirect"] == nil ? YES : [[options valueForKey:@"followRedirect"] boolValue];
172 175
     isIncrement = [options valueForKey:@"increment"] == nil ? NO : [[options valueForKey:@"increment"] boolValue];
173 176
     redirects = [[NSMutableArray alloc] init];
@@ -192,13 +195,12 @@ NSOperationQueue *taskQueue;
192 195
 
193 196
     // the session trust any SSL certification
194 197
     NSURLSessionConfiguration *defaultConfigObject;
195
-    if(!followRedirect)
196
-    {
197
-        defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
198
-    }
199
-    else
198
+
199
+    defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
200
+
201
+    if(backgroundTask)
200 202
     {
201
-        NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:taskId];
203
+        defaultConfigObject = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:taskId];
202 204
     }
203 205
 
204 206
     // set request timeout
@@ -247,14 +249,6 @@ NSOperationQueue *taskQueue;
247 249
         [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
248 250
     __block UIApplication * app = [UIApplication sharedApplication];
249 251
 
250
-    // #115 handling task expired when application entering backgound for a long time
251
-    UIBackgroundTaskIdentifier tid = [app beginBackgroundTaskWithName:taskId expirationHandler:^{
252
-        NSLog([NSString stringWithFormat:@"session %@ expired", taskId ]);
253
-        [expirationTable setObject:task forKey:taskId];
254
-        // comment out this one as it might cause app crash #271
255
-//        [app endBackgroundTask:tid];
256
-    }];
257
-
258 252
 }
259 253
 
260 254
 // #115 Invoke fetch.expire event on those expired requests so that the expired event can be handled

+ 28
- 14
polyfill/Fetch.js Ver arquivo

@@ -57,24 +57,38 @@ class RNFetchBlobFetchPolyfill {
57 57
       // task is a progress reportable and cancellable Promise, however,
58 58
       // task.then is not, so we have to extend task.then with progress and
59 59
       // cancel function
60
-      let task = promise
60
+      let progressHandler, uploadHandler, cancelHandler
61
+      let statefulPromise = promise
61 62
           .then((body) => {
62
-            return RNFetchBlob.config(config)
63
-            .fetch(options.method, url, options.headers, body)
63
+            let task = RNFetchBlob.config(config)
64
+              .fetch(options.method, url, options.headers, body)
65
+            if(progressHandler)
66
+              task.progress(progressHandler)
67
+            if(uploadHandler)
68
+              task.uploadProgress(uploadHandler)
69
+            if(cancelHandler)
70
+              task.cancel()
71
+            return task.then((resp) => {
72
+              log.verbose('response', resp)
73
+              // release blob cache created when sending request
74
+              if(blobCache !== null && blobCache instanceof Blob)
75
+                blobCache.close()
76
+              return Promise.resolve(new RNFetchBlobFetchRepsonse(resp))
77
+            })
64 78
           })
65 79
 
66
-      let statefulPromise = task.then((resp) => {
67
-        log.verbose('response', resp)
68
-        // release blob cache created when sending request
69
-        if(blobCache !== null && blobCache instanceof Blob)
70
-          blobCache.close()
71
-        return Promise.resolve(new RNFetchBlobFetchRepsonse(resp))
72
-      })
73
-
74 80
       // extend task.then progress with report and cancelling functions
75
-      statefulPromise.cancel = task.cancel
76
-      statefulPromise.progress = task.progress
77
-      statefulPromise.uploadProgress = task.uploadProgress
81
+      statefulPromise.progress = (fn) => {
82
+        progressHandler = fn
83
+      }
84
+      statefulPromise.uploadProgress = (fn) => {
85
+        uploadHandler = fn
86
+      }
87
+      statefulPromise.cancel = () => {
88
+        cancelHandler = true
89
+        if(task.cancel)
90
+          task.cancel()
91
+      }
78 92
 
79 93
       return statefulPromise
80 94