Browse Source

Add android #2 implementation

Ben Hsieh 8 years ago
parent
commit
c6dca24841

+ 38
- 14
src/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java View File

@@ -1,8 +1,8 @@
1 1
 package com.RNFetchBlob;
2 2
 
3 3
 import android.net.Uri;
4
-import android.text.style.AlignmentSpan;
5 4
 
5
+import com.facebook.react.bridge.Arguments;
6 6
 import com.facebook.react.bridge.Callback;
7 7
 import com.facebook.react.bridge.ReactApplicationContext;
8 8
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
@@ -10,23 +10,17 @@ import com.facebook.react.bridge.ReactMethod;
10 10
 import com.facebook.react.bridge.ReadableArray;
11 11
 import com.facebook.react.bridge.ReadableMap;
12 12
 import com.facebook.react.bridge.ReadableMapKeySetIterator;
13
+import com.facebook.react.bridge.WritableMap;
14
+import com.facebook.react.modules.core.DeviceEventManagerModule;
13 15
 import com.loopj.android.http.AsyncHttpClient;
14 16
 import com.loopj.android.http.AsyncHttpResponseHandler;
15 17
 import com.loopj.android.http.Base64;
16
-import com.loopj.android.http.BinaryHttpResponseHandler;
17 18
 import com.loopj.android.http.RequestParams;
18 19
 
19 20
 import java.io.ByteArrayOutputStream;
20
-import java.nio.charset.Charset;
21
-import java.nio.charset.StandardCharsets;
21
+import java.io.File;
22 22
 
23
-import cz.msebera.android.httpclient.Header;
24
-import cz.msebera.android.httpclient.entity.BufferedHttpEntity;
25 23
 import cz.msebera.android.httpclient.entity.ByteArrayEntity;
26
-import cz.msebera.android.httpclient.entity.ContentType;
27
-import cz.msebera.android.httpclient.entity.StringEntity;
28
-import cz.msebera.android.httpclient.message.BasicHeader;
29
-import cz.msebera.android.httpclient.protocol.HTTP;
30 24
 
31 25
 public class RNFetchBlob extends ReactContextBaseJavaModule {
32 26
 
@@ -41,7 +35,27 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
41 35
     }
42 36
 
43 37
     @ReactMethod
44
-    public void fetchBlob(String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
38
+    public void flush(String taskId) {
39
+        try {
40
+            new File(RNFetchBlobFS.TempFilePath + taskId).delete();
41
+        } catch(Exception err) {
42
+            WritableMap args = Arguments.createMap();
43
+            args.putString("event", "error");
44
+            args.putString("detail", err.getMessage());
45
+            this.getReactApplicationContext()
46
+                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
47
+                    .emit("RNFetchBlobMessage", args);
48
+        }
49
+    }
50
+
51
+    @ReactMethod
52
+    public void readStream(String taskId, String encoding) {
53
+        RNFetchBlobFS fs = new RNFetchBlobFS(this.getReactApplicationContext());
54
+        fs.readStream(taskId, encoding);
55
+    }
56
+
57
+    @ReactMethod
58
+    public void fetchBlob(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
45 59
 
46 60
         try {
47 61
             Uri uri = Uri.parse(url);
@@ -70,8 +84,13 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
70 84
                 entity.setContentType(headers.getString("Content-Type"));
71 85
             }
72 86
 
87
+            AsyncHttpResponseHandler handler;
88
+
73 89
             // create handler
74
-            AsyncHttpResponseHandler handler = new RNFetchBlobHandler(this.getReactApplicationContext(), taskId, callback);
90
+            if(options.getBoolean("fileCache") || options.getString("path") != null)
91
+                handler = new RNFetchBlobFileHandler(this.getReactApplicationContext(), taskId, callback);
92
+            else
93
+                handler = new RNFetchBlobBinaryHandler(this.getReactApplicationContext(), taskId, callback);
75 94
 
76 95
             // send request
77 96
             switch(method.toLowerCase()) {
@@ -95,7 +114,7 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
95 114
     }
96 115
 
97 116
     @ReactMethod
98
-    public void fetchBlobForm(String taskId, String method, String url, ReadableMap headers, ReadableArray body, final Callback callback) {
117
+    public void fetchBlobForm(ReadableMap options, String taskId, String method, String url, ReadableMap headers, ReadableArray body, final Callback callback) {
99 118
 
100 119
         try {
101 120
             Uri uri = Uri.parse(url);
@@ -155,8 +174,13 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
155 174
                 req.addHeader("Content-Type", headers.getString("Content-Type") + "; charset=utf8; boundary=" + boundary);
156 175
             }
157 176
 
177
+            AsyncHttpResponseHandler handler;
178
+
158 179
             // create handler
159
-            AsyncHttpResponseHandler handler = new RNFetchBlobHandler(this.getReactApplicationContext(), taskId, callback);
180
+            if(options.getBoolean("fileCache") || options.getString("path") != null)
181
+                handler = new RNFetchBlobFileHandler(this.getReactApplicationContext(), taskId, callback);
182
+            else
183
+                handler = new RNFetchBlobBinaryHandler(this.getReactApplicationContext(), taskId, callback);
160 184
 
161 185
             // send request
162 186
             switch(method.toLowerCase()) {

src/android/src/main/java/com/RNFetchBlob/RNFetchBlobHandler.java → src/android/src/main/java/com/RNFetchBlob/RNFetchBlobBinaryHandler.java View File

@@ -7,16 +7,19 @@ import com.facebook.react.bridge.ReactContext;
7 7
 import com.facebook.react.modules.core.DeviceEventManagerModule;
8 8
 import com.loopj.android.http.AsyncHttpResponseHandler;
9 9
 import com.loopj.android.http.Base64;
10
+import com.loopj.android.http.FileAsyncHttpResponseHandler;
11
+
12
+import java.io.File;
10 13
 
11 14
 import cz.msebera.android.httpclient.Header;
12 15
 
13
-public class RNFetchBlobHandler extends AsyncHttpResponseHandler {
16
+public class RNFetchBlobBinaryHandler extends AsyncHttpResponseHandler {
14 17
 
15 18
     Callback onResponse;
16 19
     ReactContext mCtx;
17 20
     String mTaskId;
18 21
 
19
-    RNFetchBlobHandler(ReactContext ctx, String taskId, Callback onResponse) {
22
+    RNFetchBlobBinaryHandler(ReactContext ctx, String taskId, Callback onResponse) {
20 23
 
21 24
         this.onResponse = onResponse;
22 25
         this.mTaskId = taskId;
@@ -41,11 +44,12 @@ public class RNFetchBlobHandler extends AsyncHttpResponseHandler {
41 44
 
42 45
         // emit event to js context
43 46
         this.mCtx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
44
-                 .emit("RNFetchBlobProgress", args);
47
+                .emit("RNFetchBlobProgress", args);
45 48
     }
46 49
 
47 50
     @Override
48 51
     public void onFailure(final int statusCode, final Header[] headers, byte[] binaryData, final Throwable error) {
49 52
         this.onResponse.invoke(statusCode, error.getMessage()+ ", "+ error.getCause());
50 53
     }
54
+
51 55
 }

+ 77
- 0
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java View File

@@ -0,0 +1,77 @@
1
+package com.RNFetchBlob;
2
+
3
+import android.os.Environment;
4
+
5
+import com.facebook.react.bridge.Arguments;
6
+import com.facebook.react.bridge.ReactApplicationContext;
7
+import com.facebook.react.bridge.WritableMap;
8
+import com.facebook.react.modules.core.DeviceEventManagerModule;
9
+import com.loopj.android.http.Base64;
10
+
11
+import java.io.FileInputStream;
12
+
13
+import cz.msebera.android.httpclient.util.EncodingUtils;
14
+
15
+/**
16
+ * Created by wkh237 on 2016/5/26.
17
+ */
18
+public class RNFetchBlobFS {
19
+
20
+    static String DocumentDir = Environment.getExternalStorageDirectory().toString();
21
+    static String TempFilePath = Environment.getExternalStorageDirectory().toString() + "/RNFetchBlobCache/dltmp";
22
+
23
+    ReactApplicationContext mCtx;
24
+    DeviceEventManagerModule.RCTDeviceEventEmitter emitter;
25
+
26
+
27
+    RNFetchBlobFS(ReactApplicationContext ctx) {
28
+        this.mCtx = ctx;
29
+        this.emitter = ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
30
+    }
31
+
32
+    public void readStream(String taskId, String encoding) {
33
+        try {
34
+
35
+            FileInputStream fs = mCtx.openFileInput(RNFetchBlobFS.TempFilePath + taskId);
36
+            byte[] buffer = new byte[1024];
37
+            int cursor = 0;
38
+            boolean error = false;
39
+
40
+            if (encoding.toLowerCase() == "utf8") {
41
+                while ((cursor = fs.read(buffer)) != -1) {
42
+                    String chunk = new String(buffer, 0, cursor, "UTF-8");
43
+                    emitFSData(taskId, "data", chunk);
44
+                }
45
+            } else if (encoding.toLowerCase() == "ascii") {
46
+                while ((cursor = fs.read(buffer)) != -1) {
47
+                    String chunk = EncodingUtils.getAsciiString(buffer, 0, cursor);
48
+                    emitFSData(taskId, "data", chunk);
49
+                }
50
+            } else if (encoding.toLowerCase() == "base64") {
51
+                while ((cursor = fs.read(buffer)) != -1) {
52
+                    emitFSData(taskId, "data", Base64.encodeToString(buffer, Base64.NO_WRAP));
53
+                }
54
+            } else {
55
+                String msg = "unrecognized encoding `" + encoding + "`";
56
+                emitFSData(taskId, "error", msg);
57
+                error = true;
58
+            }
59
+
60
+            if(!error)
61
+                emitFSData(taskId, "end", "");
62
+
63
+        } catch (Exception err) {
64
+            emitFSData(taskId, "error", err.getLocalizedMessage());
65
+        }
66
+
67
+    }
68
+
69
+    void emitFSData(String taskId, String event, String data) {
70
+        WritableMap eventData = Arguments.createMap();
71
+        eventData.putString("event", event);
72
+        eventData.putString("detail", data);
73
+        this.emitter.emit("RNFetchBlobStream" + taskId, eventData);
74
+    }
75
+}
76
+
77
+

+ 55
- 0
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFileHandler.java View File

@@ -0,0 +1,55 @@
1
+package com.RNFetchBlob;
2
+
3
+import com.facebook.react.bridge.Arguments;
4
+import com.facebook.react.bridge.Callback;
5
+import com.facebook.react.bridge.ReactContext;
6
+import com.facebook.react.bridge.WritableMap;
7
+import com.facebook.react.modules.core.DeviceEventManagerModule;
8
+import com.loopj.android.http.FileAsyncHttpResponseHandler;
9
+
10
+import java.io.File;
11
+
12
+import cz.msebera.android.httpclient.Header;
13
+
14
+/**
15
+ * Created by wkh237 on 2016/5/26.
16
+ */
17
+public class RNFetchBlobFileHandler extends FileAsyncHttpResponseHandler {
18
+
19
+    Callback onResponse;
20
+    ReactContext mCtx;
21
+    String mTaskId;
22
+
23
+    RNFetchBlobFileHandler(ReactContext ctx, String taskId, Callback onResponse) {
24
+        // save temp file to RNFetchBlobCache/dltmp${taskId}
25
+        super(new File(RNFetchBlobFS.TempFilePath + taskId), false, false);
26
+        this.onResponse = onResponse;
27
+        this.mTaskId = taskId;
28
+        this.mCtx = ctx;
29
+    }
30
+
31
+    @Override
32
+    public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) {
33
+        this.onResponse.invoke(statusCode, throwable.getMessage()+ ", "+ throwable.getCause());
34
+    }
35
+
36
+    @Override
37
+    public void onProgress(long bytesWritten, long totalSize) {
38
+        super.onProgress(bytesWritten, totalSize);
39
+
40
+        // on progress, emit RNFetchBlobProgress event with ticketId, bytesWritten, and totalSize
41
+        WritableMap args = Arguments.createMap();
42
+        args.putString("taskId", this.mTaskId);
43
+        args.putString("written", String.valueOf(bytesWritten));
44
+        args.putString("total", String.valueOf(totalSize));
45
+
46
+        // emit event to js context
47
+        this.mCtx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
48
+                .emit("RNFetchBlobProgress", args);
49
+    }
50
+
51
+    @Override
52
+    public void onSuccess(int statusCode, Header[] headers, File file) {
53
+        this.onResponse.invoke(null, file.getAbsolutePath());
54
+    }
55
+}