Browse Source

Add Android implementation for #27

Ben Hsieh 8 years ago
parent
commit
4960f0a3ac

+ 17
- 28
src/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java View File

1
 package com.RNFetchBlob;
1
 package com.RNFetchBlob;
2
 
2
 
3
-import android.app.DownloadManager;
4
-import android.content.Context;
5
-import android.net.Uri;
6
-import android.os.Environment;
7
-
8
-import com.facebook.react.bridge.Arguments;
9
 import com.facebook.react.bridge.Callback;
3
 import com.facebook.react.bridge.Callback;
4
+import com.facebook.react.bridge.Promise;
10
 import com.facebook.react.bridge.ReactApplicationContext;
5
 import com.facebook.react.bridge.ReactApplicationContext;
11
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
6
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
12
 import com.facebook.react.bridge.ReactMethod;
7
 import com.facebook.react.bridge.ReactMethod;
13
 import com.facebook.react.bridge.ReadableArray;
8
 import com.facebook.react.bridge.ReadableArray;
14
 import com.facebook.react.bridge.ReadableMap;
9
 import com.facebook.react.bridge.ReadableMap;
15
-import com.facebook.react.bridge.ReadableMapKeySetIterator;
16
-import com.facebook.react.bridge.WritableArray;
17
-import com.facebook.react.bridge.WritableMap;
18
-import com.facebook.react.modules.core.DeviceEventManagerModule;
19
-import com.loopj.android.http.AsyncHttpClient;
20
-import com.loopj.android.http.AsyncHttpResponseHandler;
21
-import com.loopj.android.http.Base64;
22
-import com.loopj.android.http.MySSLSocketFactory;
23
-import com.loopj.android.http.RequestParams;
24
-
25
-import java.io.ByteArrayOutputStream;
26
-import java.io.File;
27
-import java.security.KeyStore;
28
-import java.util.HashMap;
29
-import java.util.Map;
30
 
10
 
31
-import cz.msebera.android.httpclient.HttpEntity;
32
-import cz.msebera.android.httpclient.entity.AbstractHttpEntity;
33
-import cz.msebera.android.httpclient.entity.ByteArrayEntity;
34
-import cz.msebera.android.httpclient.entity.ContentType;
35
-import cz.msebera.android.httpclient.entity.FileEntity;
36
-import cz.msebera.android.httpclient.entity.mime.MultipartEntityBuilder;
37
-import cz.msebera.android.httpclient.entity.mime.content.ContentBody;
11
+import java.util.Map;
38
 
12
 
39
 public class RNFetchBlob extends ReactContextBaseJavaModule {
13
 public class RNFetchBlob extends ReactContextBaseJavaModule {
40
 
14
 
119
         RNFetchBlobFS.removeSession(paths, callback);
93
         RNFetchBlobFS.removeSession(paths, callback);
120
     }
94
     }
121
 
95
 
96
+    @ReactMethod
97
+    public void readFile(String path, String encoding, Promise promise) {
98
+        RNFetchBlobFS.readFile(path, encoding, promise);
99
+    }
100
+
101
+    @ReactMethod
102
+    public void writeFileArray(String path, ReadableArray data, Promise promise) {
103
+        RNFetchBlobFS.writeFile(path, data, promise);
104
+    }
105
+
106
+    @ReactMethod
107
+    public void writeFile(String path, String encoding, String data, Promise promise) {
108
+        RNFetchBlobFS.writeFile(path, encoding, data, promise);
109
+    }
110
+
122
     @ReactMethod
111
     @ReactMethod
123
     public void lstat(String path, Callback callback) {
112
     public void lstat(String path, Callback callback) {
124
         RNFetchBlobFS.lstat(path, callback);
113
         RNFetchBlobFS.lstat(path, callback);

+ 120
- 5
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java View File

8
 
8
 
9
 import com.facebook.react.bridge.Arguments;
9
 import com.facebook.react.bridge.Arguments;
10
 import com.facebook.react.bridge.Callback;
10
 import com.facebook.react.bridge.Callback;
11
+import com.facebook.react.bridge.Promise;
11
 import com.facebook.react.bridge.ReactApplicationContext;
12
 import com.facebook.react.bridge.ReactApplicationContext;
12
 import com.facebook.react.bridge.ReadableArray;
13
 import com.facebook.react.bridge.ReadableArray;
13
 import com.facebook.react.bridge.ReadableMap;
14
 import com.facebook.react.bridge.ReadableMap;
18
 
19
 
19
 import java.io.File;
20
 import java.io.File;
20
 import java.io.FileInputStream;
21
 import java.io.FileInputStream;
22
+import java.io.FileNotFoundException;
21
 import java.io.FileOutputStream;
23
 import java.io.FileOutputStream;
22
 import java.io.IOException;
24
 import java.io.IOException;
23
 import java.io.InputStream;
25
 import java.io.InputStream;
25
 import java.io.OutputStreamWriter;
27
 import java.io.OutputStreamWriter;
26
 import java.nio.charset.Charset;
28
 import java.nio.charset.Charset;
27
 import java.nio.charset.StandardCharsets;
29
 import java.nio.charset.StandardCharsets;
30
+import java.util.ArrayList;
28
 import java.util.HashMap;
31
 import java.util.HashMap;
29
 import java.util.Map;
32
 import java.util.Map;
30
 import java.util.UUID;
33
 import java.util.UUID;
34
+import java.util.concurrent.ExecutionException;
31
 
35
 
32
 import cz.msebera.android.httpclient.util.EncodingUtils;
36
 import cz.msebera.android.httpclient.util.EncodingUtils;
33
 
37
 
48
         this.emitter = ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
52
         this.emitter = ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
49
     }
53
     }
50
 
54
 
55
+    /**
56
+     * Write string with encoding to file
57
+     * @param path Destination file path.
58
+     * @param encoding Encoding of the string.
59
+     * @param data Array passed from JS context.
60
+     * @param promise
61
+     */
62
+    static public void writeFile(String path, String encoding, String data, final Promise promise) {
63
+        AsyncTask<String, Integer, Integer> task = new AsyncTask<String, Integer, Integer>() {
64
+            @Override
65
+            protected Integer doInBackground(String... args) {
66
+                String path = args[0];
67
+                String encoding = args[1];
68
+                String data = args[2];
69
+                File f = new File(path);
70
+                try {
71
+                    FileOutputStream fout = new FileOutputStream(f);
72
+                    fout.write(stringToBytes(data, encoding));
73
+                    fout.close();
74
+                    promise.resolve(null);
75
+                } catch (Exception e) {
76
+                    promise.reject("RNFetchBlob writeFileError", e.getLocalizedMessage());
77
+                }
78
+                return null;
79
+            }
80
+        };
81
+        task.execute(path, encoding, data);
82
+    }
83
+
84
+    /**
85
+     * Write array of bytes into file
86
+     * @param path Destination file path.
87
+     * @param data Array passed from JS context.
88
+     * @param promise
89
+     */
90
+    static public void writeFile(String path, ReadableArray data, final Promise promise) {
91
+        AsyncTask<Object, Integer, Integer> task = new AsyncTask<Object, Integer, Integer>() {
92
+            @Override
93
+            protected Integer doInBackground(Object... args) {
94
+                String path = String.valueOf(args[0]);
95
+                ReadableArray data = (ReadableArray) args[2];
96
+                File f = new File(path);
97
+                try {
98
+                    FileOutputStream os = new FileOutputStream(f);
99
+                    byte [] bytes = new byte[data.size()];
100
+                    for(int i=0;i<data.size();i++) {
101
+                        bytes[i] = (byte) data.getInt(i);
102
+                    }
103
+                    os.write(bytes);
104
+                    os.close();
105
+                    promise.resolve(null);
106
+                } catch (Exception e) {
107
+                    promise.reject("RNFetchBlob writeFileError", e.getLocalizedMessage());
108
+                }
109
+                return null;
110
+            }
111
+        };
112
+        task.execute(path, data);
113
+    }
114
+
115
+    /**
116
+     * Read file with a buffer that has the same size as the target file.
117
+     * @param path  Path of the file.
118
+     * @param encoding  Encoding of read stream.
119
+     * @param promise
120
+     */
121
+    static public void readFile(String path, String encoding, final Promise promise ) {
122
+        AsyncTask task = new AsyncTask<String, Integer, Integer>() {
123
+            @Override
124
+            protected Integer doInBackground(String... strings) {
125
+                try {
126
+                    String path = strings[0];
127
+                    String encoding = strings[1];
128
+                    File f = new File(path);
129
+                    int length = (int) f.length();
130
+                    byte[] bytes = new byte[length];
131
+                    FileInputStream in = new FileInputStream(f);
132
+                    in.read(bytes);
133
+                    in.close();
134
+                    switch (encoding.toLowerCase()) {
135
+                        case "base64" :
136
+                            promise.resolve(Base64.encodeToString(bytes, 0));
137
+                            break;
138
+                        case "ascii" :
139
+                            WritableArray asciiResult = Arguments.createArray();
140
+                            for(byte b : bytes) {
141
+                                asciiResult.pushInt((int)b);
142
+                            }
143
+                            promise.resolve(bytes);
144
+                            break;
145
+                        case "utf8" :
146
+                            promise.resolve(new String(bytes));
147
+                            break;
148
+                        default:
149
+                            promise.resolve(new String(bytes));
150
+                            break;
151
+                    }
152
+                }
153
+                catch(Exception err) {
154
+                    promise.reject("ReadFile Error", err.getLocalizedMessage());
155
+                }
156
+                return null;
157
+            }
158
+        };
159
+        task.execute(path, encoding);
160
+    }
161
+
51
     /**
162
     /**
52
      * Static method that returns system folders to JS context
163
      * Static method that returns system folders to JS context
53
      * @param ctx   React Native application context
164
      * @param ctx   React Native application context
106
                         }
217
                         }
107
                     } else if (encoding.equalsIgnoreCase("ascii")) {
218
                     } else if (encoding.equalsIgnoreCase("ascii")) {
108
                         while ((cursor = fs.read(buffer)) != -1) {
219
                         while ((cursor = fs.read(buffer)) != -1) {
109
-                            String chunk = "[";
220
+                            WritableArray chunk = Arguments.createArray();
110
                             for(int i =0;i<cursor;i++)
221
                             for(int i =0;i<cursor;i++)
111
                             {
222
                             {
112
-                                chunk += (int)buffer[i];
113
-                                if(i+1 < cursor)
114
-                                    chunk += ",";
223
+                                chunk.pushInt((int)buffer[i]);
115
                             }
224
                             }
116
-                            chunk = chunk + "]";
117
                             emitStreamEvent(eventName, "data", chunk);
225
                             emitStreamEvent(eventName, "data", chunk);
118
                         }
226
                         }
119
                     } else if (encoding.equalsIgnoreCase("base64")) {
227
                     } else if (encoding.equalsIgnoreCase("base64")) {
530
         this.emitter.emit(streamName, eventData);
638
         this.emitter.emit(streamName, eventData);
531
     }
639
     }
532
 
640
 
641
+    void emitStreamEvent(String streamName, String event, WritableArray  data) {
642
+        WritableMap eventData = Arguments.createMap();
643
+        eventData.putString("event", event);
644
+        eventData.putArray("detail", data);
645
+        this.emitter.emit(streamName, eventData);
646
+    }
647
+
533
     // TODO : should we remove this ?
648
     // TODO : should we remove this ?
534
     void emitFSData(String taskId, String event, String data) {
649
     void emitFSData(String taskId, String event, String data) {
535
         WritableMap eventData = Arguments.createMap();
650
         WritableMap eventData = Arguments.createMap();

+ 4
- 0
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java View File

1
 package com.RNFetchBlob;
1
 package com.RNFetchBlob;
2
 
2
 
3
+import android.app.DownloadManager;
4
+import android.content.Context;
5
+import android.net.Uri;
6
+
3
 import com.facebook.react.bridge.Callback;
7
 import com.facebook.react.bridge.Callback;
4
 import com.facebook.react.bridge.ReactApplicationContext;
8
 import com.facebook.react.bridge.ReactApplicationContext;
5
 import com.facebook.react.bridge.ReadableArray;
9
 import com.facebook.react.bridge.ReadableArray;