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
 package com.RNFetchBlob;
1
 package com.RNFetchBlob;
2
 
2
 
3
 import android.net.Uri;
3
 import android.net.Uri;
4
-import android.text.style.AlignmentSpan;
5
 
4
 
5
+import com.facebook.react.bridge.Arguments;
6
 import com.facebook.react.bridge.Callback;
6
 import com.facebook.react.bridge.Callback;
7
 import com.facebook.react.bridge.ReactApplicationContext;
7
 import com.facebook.react.bridge.ReactApplicationContext;
8
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
8
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
 import com.facebook.react.bridge.ReadableArray;
10
 import com.facebook.react.bridge.ReadableArray;
11
 import com.facebook.react.bridge.ReadableMap;
11
 import com.facebook.react.bridge.ReadableMap;
12
 import com.facebook.react.bridge.ReadableMapKeySetIterator;
12
 import com.facebook.react.bridge.ReadableMapKeySetIterator;
13
+import com.facebook.react.bridge.WritableMap;
14
+import com.facebook.react.modules.core.DeviceEventManagerModule;
13
 import com.loopj.android.http.AsyncHttpClient;
15
 import com.loopj.android.http.AsyncHttpClient;
14
 import com.loopj.android.http.AsyncHttpResponseHandler;
16
 import com.loopj.android.http.AsyncHttpResponseHandler;
15
 import com.loopj.android.http.Base64;
17
 import com.loopj.android.http.Base64;
16
-import com.loopj.android.http.BinaryHttpResponseHandler;
17
 import com.loopj.android.http.RequestParams;
18
 import com.loopj.android.http.RequestParams;
18
 
19
 
19
 import java.io.ByteArrayOutputStream;
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
 import cz.msebera.android.httpclient.entity.ByteArrayEntity;
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
 public class RNFetchBlob extends ReactContextBaseJavaModule {
25
 public class RNFetchBlob extends ReactContextBaseJavaModule {
32
 
26
 
41
     }
35
     }
42
 
36
 
43
     @ReactMethod
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
         try {
60
         try {
47
             Uri uri = Uri.parse(url);
61
             Uri uri = Uri.parse(url);
70
                 entity.setContentType(headers.getString("Content-Type"));
84
                 entity.setContentType(headers.getString("Content-Type"));
71
             }
85
             }
72
 
86
 
87
+            AsyncHttpResponseHandler handler;
88
+
73
             // create handler
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
             // send request
95
             // send request
77
             switch(method.toLowerCase()) {
96
             switch(method.toLowerCase()) {
95
     }
114
     }
96
 
115
 
97
     @ReactMethod
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
         try {
119
         try {
101
             Uri uri = Uri.parse(url);
120
             Uri uri = Uri.parse(url);
155
                 req.addHeader("Content-Type", headers.getString("Content-Type") + "; charset=utf8; boundary=" + boundary);
174
                 req.addHeader("Content-Type", headers.getString("Content-Type") + "; charset=utf8; boundary=" + boundary);
156
             }
175
             }
157
 
176
 
177
+            AsyncHttpResponseHandler handler;
178
+
158
             // create handler
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
             // send request
185
             // send request
162
             switch(method.toLowerCase()) {
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
 import com.facebook.react.modules.core.DeviceEventManagerModule;
7
 import com.facebook.react.modules.core.DeviceEventManagerModule;
8
 import com.loopj.android.http.AsyncHttpResponseHandler;
8
 import com.loopj.android.http.AsyncHttpResponseHandler;
9
 import com.loopj.android.http.Base64;
9
 import com.loopj.android.http.Base64;
10
+import com.loopj.android.http.FileAsyncHttpResponseHandler;
11
+
12
+import java.io.File;
10
 
13
 
11
 import cz.msebera.android.httpclient.Header;
14
 import cz.msebera.android.httpclient.Header;
12
 
15
 
13
-public class RNFetchBlobHandler extends AsyncHttpResponseHandler {
16
+public class RNFetchBlobBinaryHandler extends AsyncHttpResponseHandler {
14
 
17
 
15
     Callback onResponse;
18
     Callback onResponse;
16
     ReactContext mCtx;
19
     ReactContext mCtx;
17
     String mTaskId;
20
     String mTaskId;
18
 
21
 
19
-    RNFetchBlobHandler(ReactContext ctx, String taskId, Callback onResponse) {
22
+    RNFetchBlobBinaryHandler(ReactContext ctx, String taskId, Callback onResponse) {
20
 
23
 
21
         this.onResponse = onResponse;
24
         this.onResponse = onResponse;
22
         this.mTaskId = taskId;
25
         this.mTaskId = taskId;
41
 
44
 
42
         // emit event to js context
45
         // emit event to js context
43
         this.mCtx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
46
         this.mCtx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
44
-                 .emit("RNFetchBlobProgress", args);
47
+                .emit("RNFetchBlobProgress", args);
45
     }
48
     }
46
 
49
 
47
     @Override
50
     @Override
48
     public void onFailure(final int statusCode, final Header[] headers, byte[] binaryData, final Throwable error) {
51
     public void onFailure(final int statusCode, final Header[] headers, byte[] binaryData, final Throwable error) {
49
         this.onResponse.invoke(statusCode, error.getMessage()+ ", "+ error.getCause());
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

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

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
+}