tharak-android 0.0.1

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.
Files changed (33) hide show
  1. package/README.md +1 -0
  2. package/build.gradle +45 -0
  3. package/consumer-rules.pro +0 -0
  4. package/libs/vital-sdk.aar +0 -0
  5. package/package.json +22 -0
  6. package/proguard-rules.pro +21 -0
  7. package/src/androidTest/androidTest.iml +11 -0
  8. package/src/androidTest/java/org/tharak/core/ExampleInstrumentedTest.java +27 -0
  9. package/src/androidTest/java/org/thiragatisoft/core/ExampleInstrumentedTest.java +26 -0
  10. package/src/main/AndroidManifest.xml +5 -0
  11. package/src/main/java/org/thiragatisoft/core/AppUtils.java +31 -0
  12. package/src/main/java/org/thiragatisoft/core/FileSelector.java +162 -0
  13. package/src/main/java/org/thiragatisoft/core/MainActivity.java +27 -0
  14. package/src/main/java/org/thiragatisoft/core/RestClient.java +298 -0
  15. package/src/main/java/org/thiragatisoft/core/VitalActivity.java +612 -0
  16. package/src/main/java/org/thiragatisoft/core/VitalsPlugin.java +15 -0
  17. package/src/main/java/org/thiragatisoft/core/VolleyMultipartRequest.java +218 -0
  18. package/src/main/java/org/thiragatisoft/core/http/CapacitorCookieManager.java +175 -0
  19. package/src/main/java/org/thiragatisoft/core/http/CapacitorHttpUrlConnection.java +408 -0
  20. package/src/main/java/org/thiragatisoft/core/http/FilesystemUtils.java +65 -0
  21. package/src/main/java/org/thiragatisoft/core/http/FormUploader.java +219 -0
  22. package/src/main/java/org/thiragatisoft/core/http/Http.java +275 -0
  23. package/src/main/java/org/thiragatisoft/core/http/HttpRequestHandler.java +515 -0
  24. package/src/main/java/org/thiragatisoft/core/http/ICapacitorHttpUrlConnection.java +15 -0
  25. package/src/main/java/org/thiragatisoft/core/http/JSValue.java +68 -0
  26. package/src/main/java/org/thiragatisoft/core/http/MimeType.java +17 -0
  27. package/src/main/main.iml +12 -0
  28. package/src/test/java/org/tharak/ExampleUnitTest.java +17 -0
  29. package/src/test/java/org/tharak/JSObjectTest.java +209 -0
  30. package/src/test/java/org/tharak/PluginMethodHandleTest.java +44 -0
  31. package/src/test/java/org/tharak/util/HostMaskTest.java +70 -0
  32. package/src/test/java/org/thiragatisoft/core/ExampleUnitTest.java +17 -0
  33. package/src/test/test.iml +11 -0
@@ -0,0 +1,408 @@
1
+ package org.thiragatisoft.core.http;
2
+
3
+ import android.os.Build;
4
+ import android.os.LocaleList;
5
+ import android.text.TextUtils;
6
+ import com.getcapacitor.JSArray;
7
+ import com.getcapacitor.JSObject;
8
+ import com.getcapacitor.PluginCall;
9
+ import java.io.DataOutputStream;
10
+ import java.io.IOException;
11
+ import java.io.InputStream;
12
+ import java.net.HttpURLConnection;
13
+ import java.net.ProtocolException;
14
+ import java.net.SocketTimeoutException;
15
+ import java.net.URL;
16
+ import java.net.URLEncoder;
17
+ import java.net.UnknownServiceException;
18
+ import java.nio.charset.StandardCharsets;
19
+ import java.util.Iterator;
20
+ import java.util.List;
21
+ import java.util.Locale;
22
+ import java.util.Map;
23
+ import org.json.JSONException;
24
+ import org.json.JSONObject;
25
+
26
+ public class CapacitorHttpUrlConnection implements ICapacitorHttpUrlConnection {
27
+
28
+ private final HttpURLConnection connection;
29
+
30
+ /**
31
+ * Make a new CapacitorHttpUrlConnection instance, which wraps around HttpUrlConnection
32
+ * and provides some helper functions for setting request headers and the request body
33
+ * @param conn the base HttpUrlConnection. You can pass the value from
34
+ * {@code (HttpUrlConnection) URL.openConnection()}
35
+ */
36
+ public CapacitorHttpUrlConnection(HttpURLConnection conn) {
37
+ connection = conn;
38
+ this.setDefaultRequestProperties();
39
+ }
40
+
41
+ /**
42
+ * Returns the underlying HttpUrlConnection value
43
+ * @return the underlying HttpUrlConnection value
44
+ */
45
+ public HttpURLConnection getHttpConnection() {
46
+ return connection;
47
+ }
48
+
49
+ /**
50
+ * Set the value of the {@code allowUserInteraction} field of
51
+ * this {@code URLConnection}.
52
+ *
53
+ * @param isAllowedInteraction the new value.
54
+ * @throws IllegalStateException if already connected
55
+ */
56
+ public void setAllowUserInteraction(boolean isAllowedInteraction) {
57
+ connection.setAllowUserInteraction(isAllowedInteraction);
58
+ }
59
+
60
+ /**
61
+ * Set the method for the URL request, one of:
62
+ * <UL>
63
+ * <LI>GET
64
+ * <LI>POST
65
+ * <LI>HEAD
66
+ * <LI>OPTIONS
67
+ * <LI>PUT
68
+ * <LI>DELETE
69
+ * <LI>TRACE
70
+ * </UL> are legal, subject to protocol restrictions. The default
71
+ * method is GET.
72
+ *
73
+ * @param method the HTTP method
74
+ * @exception ProtocolException if the method cannot be reset or if
75
+ * the requested method isn't valid for HTTP.
76
+ * @exception SecurityException if a security manager is set and the
77
+ * method is "TRACE", but the "allowHttpTrace"
78
+ * NetPermission is not granted.
79
+ */
80
+ public void setRequestMethod(String method) throws ProtocolException {
81
+ connection.setRequestMethod(method);
82
+ }
83
+
84
+ /**
85
+ * Sets a specified timeout value, in milliseconds, to be used
86
+ * when opening a communications link to the resource referenced
87
+ * by this URLConnection. If the timeout expires before the
88
+ * connection can be established, a
89
+ * java.net.SocketTimeoutException is raised. A timeout of zero is
90
+ * interpreted as an infinite timeout.
91
+ *
92
+ * <p><strong>Warning</strong>: If the hostname resolves to multiple IP
93
+ * addresses, Android's default implementation of {@link HttpURLConnection}
94
+ * will try each in
95
+ * <a href="http://www.ietf.org/rfc/rfc3484.txt">RFC 3484</a> order. If
96
+ * connecting to each of these addresses fails, multiple timeouts will
97
+ * elapse before the connect attempt throws an exception. Host names
98
+ * that support both IPv6 and IPv4 always have at least 2 IP addresses.
99
+ *
100
+ * @param timeout an {@code int} that specifies the connect
101
+ * timeout value in milliseconds
102
+ * @throws IllegalArgumentException if the timeout parameter is negative
103
+ */
104
+ public void setConnectTimeout(int timeout) {
105
+ if (timeout < 0) {
106
+ throw new IllegalArgumentException("timeout can not be negative");
107
+ }
108
+ connection.setConnectTimeout(timeout);
109
+ }
110
+
111
+ /**
112
+ * Sets the read timeout to a specified timeout, in
113
+ * milliseconds. A non-zero value specifies the timeout when
114
+ * reading from Input stream when a connection is established to a
115
+ * resource. If the timeout expires before there is data available
116
+ * for read, a java.net.SocketTimeoutException is raised. A
117
+ * timeout of zero is interpreted as an infinite timeout.
118
+ *
119
+ * @param timeout an {@code int} that specifies the timeout
120
+ * value to be used in milliseconds
121
+ * @throws IllegalArgumentException if the timeout parameter is negative
122
+ */
123
+ public void setReadTimeout(int timeout) {
124
+ if (timeout < 0) {
125
+ throw new IllegalArgumentException("timeout can not be negative");
126
+ }
127
+ connection.setReadTimeout(timeout);
128
+ }
129
+
130
+ /**
131
+ * Sets whether automatic HTTP redirects should be disabled
132
+ * @param disableRedirects the flag to determine if redirects should be followed
133
+ */
134
+ public void setDisableRedirects(boolean disableRedirects) {
135
+ connection.setInstanceFollowRedirects(!disableRedirects);
136
+ }
137
+
138
+ /**
139
+ * Sets the request headers given a JSObject of key-value pairs
140
+ * @param headers the JSObject values to map to the HttpUrlConnection request headers
141
+ */
142
+ public void setRequestHeaders(JSObject headers) {
143
+ Iterator<String> keys = headers.keys();
144
+ while (keys.hasNext()) {
145
+ String key = keys.next();
146
+ String value = headers.getString(key);
147
+ connection.setRequestProperty(key, value);
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Sets the value of the {@code doOutput} field for this
153
+ * {@code URLConnection} to the specified value.
154
+ * <p>
155
+ * A URL connection can be used for input and/or output. Set the DoOutput
156
+ * flag to true if you intend to use the URL connection for output,
157
+ * false if not. The default is false.
158
+ *
159
+ * @param shouldDoOutput the new value.
160
+ * @throws IllegalStateException if already connected
161
+ */
162
+ public void setDoOutput(boolean shouldDoOutput) {
163
+ connection.setDoOutput(shouldDoOutput);
164
+ }
165
+
166
+ /**
167
+ *
168
+ * @param call
169
+ * @throws JSONException
170
+ * @throws IOException
171
+ */
172
+ public void setRequestBody(PluginCall call, JSValue body) throws JSONException, IOException {
173
+ String contentType = connection.getRequestProperty("Content-Type");
174
+ String dataString = "";
175
+
176
+ if (contentType == null || contentType.isEmpty()) return;
177
+
178
+ if (contentType.contains("application/json")) {
179
+ JSArray jsArray = null;
180
+ if (body != null) {
181
+ dataString = body.toString();
182
+ } else {
183
+ jsArray = call.getArray("data", null);
184
+ }
185
+ if (jsArray != null) {
186
+ dataString = jsArray.toString();
187
+ } else if (body == null) {
188
+ dataString = call.getString("data");
189
+ }
190
+ this.writeRequestBody(dataString.toString());
191
+ } else if (contentType.contains("application/x-www-form-urlencoded")) {
192
+ StringBuilder builder = new StringBuilder();
193
+ if(body.getValue() instanceof String){
194
+ builder.append(body.getValue());
195
+ }else {
196
+ JSObject obj = body.toJSObject();
197
+ Iterator<String> keys = obj.keys();
198
+ while (keys.hasNext()) {
199
+ String key = keys.next();
200
+ Object d = obj.get(key);
201
+ builder.append(key).append("=").append(URLEncoder.encode(d.toString(), "UTF-8"));
202
+
203
+ if (keys.hasNext()) {
204
+ builder.append("&");
205
+ }
206
+ }
207
+ }
208
+ this.writeRequestBody(builder.toString());
209
+ } else if (contentType.contains("multipart/form-data")) {
210
+ /*FormUploader uploader = new FormUploader(connection);
211
+
212
+ JSObject obj = body.toJSObject();
213
+ Iterator<String> keys = obj.keys();
214
+ while (keys.hasNext()) {
215
+ String key = keys.next();
216
+ String d = obj.get(key).toString();
217
+ if("file".equals(key)){
218
+ try {
219
+ JSONObject file = new JSONObject(d);
220
+ uploader.addFileBase64Part(key, file.getString("name"), file.getString("base64"));
221
+ }catch (Exception ex){
222
+ //Do Nothing
223
+ }
224
+ }else
225
+ uploader.addFormField(key, d);
226
+ }
227
+ uploader.finish();*/
228
+ JSObject obj = body.toJSObject();
229
+ FormUploader builder = new FormUploader(connection);
230
+ builder.addFileBase64Part("file", obj);
231
+ builder.finish();
232
+ } else {
233
+ this.writeRequestBody(body.toString());
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Writes the provided string to the HTTP connection managed by this instance.
239
+ *
240
+ * @param body The string value to write to the connection stream.
241
+ */
242
+ private void writeRequestBody(String body) throws IOException {
243
+ try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
244
+ os.write(body.getBytes(StandardCharsets.UTF_8));
245
+ os.flush();
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Opens a communications link to the resource referenced by this
251
+ * URL, if such a connection has not already been established.
252
+ * <p>
253
+ * If the {@code connect} method is called when the connection
254
+ * has already been opened (indicated by the {@code connected}
255
+ * field having the value {@code true}), the call is ignored.
256
+ * <p>
257
+ * URLConnection objects go through two phases: first they are
258
+ * created, then they are connected. After being created, and
259
+ * before being connected, various options can be specified
260
+ * (e.g., doInput and UseCaches). After connecting, it is an
261
+ * error to try to set them. Operations that depend on being
262
+ * connected, like getContentLength, will implicitly perform the
263
+ * connection, if necessary.
264
+ *
265
+ * @throws SocketTimeoutException if the timeout expires before
266
+ * the connection can be established
267
+ * @exception IOException if an I/O error occurs while opening the
268
+ * connection.
269
+ */
270
+ public void connect() throws IOException {
271
+ connection.connect();
272
+ }
273
+
274
+ /**
275
+ * Gets the status code from an HTTP response message.
276
+ * For example, in the case of the following status lines:
277
+ * <PRE>
278
+ * HTTP/1.0 200 OK
279
+ * HTTP/1.0 401 Unauthorized
280
+ * </PRE>
281
+ * It will return 200 and 401 respectively.
282
+ * Returns -1 if no code can be discerned
283
+ * from the response (i.e., the response is not valid HTTP).
284
+ * @throws IOException if an error occurred connecting to the server.
285
+ * @return the HTTP Status-Code, or -1
286
+ */
287
+ public int getResponseCode() throws IOException {
288
+ return connection.getResponseCode();
289
+ }
290
+
291
+ /**
292
+ * Returns the value of this {@code URLConnection}'s {@code URL}
293
+ * field.
294
+ *
295
+ * @return the value of this {@code URLConnection}'s {@code URL}
296
+ * field.
297
+ * @see java.net.URLConnection#url
298
+ */
299
+ public URL getURL() {
300
+ return connection.getURL();
301
+ }
302
+
303
+ /**
304
+ * Returns the error stream if the connection failed
305
+ * but the server sent useful data nonetheless. The
306
+ * typical example is when an HTTP server responds
307
+ * with a 404, which will cause a FileNotFoundException
308
+ * to be thrown in connect, but the server sent an HTML
309
+ * help page with suggestions as to what to do.
310
+ *
311
+ * <p>This method will not cause a connection to be initiated. If
312
+ * the connection was not connected, or if the server did not have
313
+ * an error while connecting or if the server had an error but
314
+ * no error data was sent, this method will return null. This is
315
+ * the default.
316
+ *
317
+ * @return an error stream if any, null if there have been no
318
+ * errors, the connection is not connected or the server sent no
319
+ * useful data.
320
+ */
321
+ @Override
322
+ public InputStream getErrorStream() {
323
+ return connection.getErrorStream();
324
+ }
325
+
326
+ /**
327
+ * Returns the value of the named header field.
328
+ * <p>
329
+ * If called on a connection that sets the same header multiple times
330
+ * with possibly different values, only the last value is returned.
331
+ *
332
+ *
333
+ * @param name the name of a header field.
334
+ * @return the value of the named header field, or {@code null}
335
+ * if there is no such field in the header.
336
+ */
337
+ @Override
338
+ public String getHeaderField(String name) {
339
+ return connection.getHeaderField(name);
340
+ }
341
+
342
+ /**
343
+ * Returns an input stream that reads from this open connection.
344
+ *
345
+ * A SocketTimeoutException can be thrown when reading from the
346
+ * returned input stream if the read timeout expires before data
347
+ * is available for read.
348
+ *
349
+ * @return an input stream that reads from this open connection.
350
+ * @exception IOException if an I/O error occurs while
351
+ * creating the input stream.
352
+ * @exception UnknownServiceException if the protocol does not support
353
+ * input.
354
+ * @see #setReadTimeout(int)
355
+ */
356
+ @Override
357
+ public InputStream getInputStream() throws IOException {
358
+ return connection.getInputStream();
359
+ }
360
+
361
+ /**
362
+ * Returns an unmodifiable Map of the header fields.
363
+ * The Map keys are Strings that represent the
364
+ * response-header field names. Each Map value is an
365
+ * unmodifiable List of Strings that represents
366
+ * the corresponding field values.
367
+ *
368
+ * @return a Map of header fields
369
+ */
370
+ public Map<String, List<String>> getHeaderFields() {
371
+ return connection.getHeaderFields();
372
+ }
373
+
374
+ /**
375
+ * Sets the default request properties on the newly created connection.
376
+ * This is called as early as possible to allow overrides by user-provided values.
377
+ */
378
+ private void setDefaultRequestProperties() {
379
+ connection.setRequestProperty("Accept-Charset", StandardCharsets.UTF_8.name());
380
+ String acceptLanguage = buildDefaultAcceptLanguageProperty();
381
+ if (!TextUtils.isEmpty(acceptLanguage)) {
382
+ connection.setRequestProperty("Accept-Language", acceptLanguage);
383
+ }
384
+ }
385
+
386
+ /**
387
+ * Builds and returns a locale string describing the device's current locale preferences.
388
+ */
389
+ private String buildDefaultAcceptLanguageProperty() {
390
+ Locale locale;
391
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
392
+ locale = LocaleList.getDefault().get(0);
393
+ } else {
394
+ locale = Locale.getDefault();
395
+ }
396
+ String result = "";
397
+ String lang = locale.getLanguage();
398
+ String country = locale.getCountry();
399
+ if (!TextUtils.isEmpty(lang)) {
400
+ if (!TextUtils.isEmpty(country)) {
401
+ result = String.format("%s-%s,%s;q=0.5", lang, country, lang);
402
+ } else {
403
+ result = String.format("%s;q=0.5", lang);
404
+ }
405
+ }
406
+ return result;
407
+ }
408
+ }
@@ -0,0 +1,65 @@
1
+ package org.thiragatisoft.core.http;
2
+
3
+ import android.content.Context;
4
+ import android.net.Uri;
5
+ import android.os.Environment;
6
+ import java.io.File;
7
+
8
+ public class FilesystemUtils {
9
+
10
+ public static final String DIRECTORY_DOCUMENTS = "DOCUMENTS";
11
+ public static final String DIRECTORY_APPLICATION = "APPLICATION";
12
+ public static final String DIRECTORY_DOWNLOADS = "DOWNLOADS";
13
+ public static final String DIRECTORY_DATA = "DATA";
14
+ public static final String DIRECTORY_CACHE = "CACHE";
15
+ public static final String DIRECTORY_EXTERNAL = "EXTERNAL";
16
+ public static final String DIRECTORY_EXTERNAL_STORAGE = "EXTERNAL_STORAGE";
17
+
18
+ public static File getFileObject(Context c, String path, String directory) {
19
+ if (directory == null || path.startsWith("file://")) {
20
+ Uri u = Uri.parse(path);
21
+ if (u.getScheme() == null || u.getScheme().equals("file")) {
22
+ return new File(u.getPath());
23
+ }
24
+ }
25
+
26
+ File androidDirectory = FilesystemUtils.getDirectory(c, directory);
27
+
28
+ if (androidDirectory == null) {
29
+ return null;
30
+ } else {
31
+ if (!androidDirectory.exists()) {
32
+ androidDirectory.mkdir();
33
+ }
34
+ }
35
+
36
+ return new File(androidDirectory, path);
37
+ }
38
+
39
+ public static File getDirectory(Context c, String directory) {
40
+ switch (directory) {
41
+ case DIRECTORY_APPLICATION:
42
+ case DIRECTORY_DATA:
43
+ return c.getFilesDir();
44
+ case DIRECTORY_DOCUMENTS:
45
+ return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
46
+ case DIRECTORY_DOWNLOADS:
47
+ return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
48
+ case DIRECTORY_CACHE:
49
+ return c.getCacheDir();
50
+ case DIRECTORY_EXTERNAL:
51
+ return c.getExternalFilesDir(null);
52
+ case DIRECTORY_EXTERNAL_STORAGE:
53
+ return Environment.getExternalStorageDirectory();
54
+ }
55
+ return null;
56
+ }
57
+
58
+ /**
59
+ * True if the given directory string is a public storage directory, which is accessible by the user or other apps.
60
+ * @param directory the directory string.
61
+ */
62
+ public static boolean isPublicDirectory(String directory) {
63
+ return (DIRECTORY_DOCUMENTS.equals(directory) || DIRECTORY_DOWNLOADS.equals(directory) || "EXTERNAL_STORAGE".equals(directory));
64
+ }
65
+ }
@@ -0,0 +1,219 @@
1
+ package org.thiragatisoft.core.http;
2
+
3
+ import android.util.Base64;
4
+
5
+ import com.getcapacitor.JSObject;
6
+ import java.io.File;
7
+ import java.io.FileInputStream;
8
+ import java.io.IOException;
9
+ import java.io.OutputStream;
10
+ import java.io.OutputStreamWriter;
11
+ import java.io.PrintWriter;
12
+ import java.net.HttpURLConnection;
13
+ import java.net.URLConnection;
14
+ import java.util.Iterator;
15
+ import java.util.UUID;
16
+ import org.json.JSONException;
17
+ import org.json.JSONObject;
18
+
19
+ public class FormUploader {
20
+
21
+ private final String LINE_FEED = "\r\n";
22
+ private final String boundary;
23
+ private final String charset = "UTF-8";
24
+ private final OutputStream outputStream;
25
+ private final PrintWriter prWriter;
26
+
27
+ /**
28
+ * This constructor initializes a new HTTP POST request with content type
29
+ * is set to multipart/form-data
30
+ * @param connection The HttpUrlConnection to use to upload a Form
31
+ * @throws IOException Thrown if unable to parse the OutputStream of the connection
32
+ */
33
+ public FormUploader(HttpURLConnection connection) throws IOException {
34
+ UUID uuid = UUID.randomUUID();
35
+ boundary = uuid.toString();
36
+
37
+ connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
38
+
39
+ outputStream = connection.getOutputStream();
40
+ prWriter = new PrintWriter(new OutputStreamWriter(outputStream, charset), true);
41
+ }
42
+
43
+ /**
44
+ * Adds a form field to the request
45
+ *
46
+ * @param name field name
47
+ * @param value field value
48
+ */
49
+ public void addFormField(String name, String value) {
50
+ prWriter
51
+ .append(LINE_FEED)
52
+ .append("--")
53
+ .append(boundary)
54
+ .append(LINE_FEED)
55
+ .append("Content-Disposition: form-data; name=\"")
56
+ .append(name)
57
+ .append("\"")
58
+ .append(LINE_FEED)
59
+ .append("Content-Type: text/plain; charset=")
60
+ .append(charset)
61
+ .append(LINE_FEED)
62
+ .append(LINE_FEED)
63
+ .append(value)
64
+ .append(LINE_FEED)
65
+ .append("--")
66
+ .append(boundary)
67
+ .append("--")
68
+ .append(LINE_FEED);
69
+ prWriter.flush();
70
+ }
71
+
72
+ /**
73
+ * Adds a form field to the prWriter
74
+ *
75
+ * @param name field name
76
+ * @param value field value
77
+ */
78
+ private void appendFieldToWriter(String name, String value) {
79
+ prWriter
80
+ .append(LINE_FEED)
81
+ .append("--")
82
+ .append(boundary)
83
+ .append(LINE_FEED)
84
+ .append("Content-Disposition: form-data; name=\"")
85
+ .append(name)
86
+ .append("\"")
87
+ .append(LINE_FEED)
88
+ .append("Content-Type: text/plain; charset=")
89
+ .append(charset)
90
+ .append(LINE_FEED)
91
+ .append(LINE_FEED)
92
+ .append(value);
93
+ }
94
+
95
+ /**
96
+ * Adds a upload file section to the request
97
+ *
98
+ * @param fieldName name attribute in <input type="file" name="..." />
99
+ * @param uploadFile a File to be uploaded
100
+ * @throws IOException Thrown if unable to parse the OutputStream of the connection
101
+ */
102
+ public void addFilePart(String fieldName, File uploadFile, JSObject data) throws IOException {
103
+ String fileName = uploadFile.getName();
104
+ prWriter
105
+ .append(LINE_FEED)
106
+ .append("--")
107
+ .append(boundary)
108
+ .append(LINE_FEED)
109
+ .append("Content-Disposition: form-data; name=\"")
110
+ .append(fieldName)
111
+ .append("\"; filename=\"")
112
+ .append(fileName)
113
+ .append("\"")
114
+ .append(LINE_FEED)
115
+ .append("Content-Type: ")
116
+ .append(URLConnection.guessContentTypeFromName(fileName))
117
+ .append(LINE_FEED)
118
+ .append(LINE_FEED);
119
+ prWriter.flush();
120
+
121
+ FileInputStream inputStream = new FileInputStream(uploadFile);
122
+ byte[] buffer = new byte[4096];
123
+ int bytesRead;
124
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
125
+ outputStream.write(buffer, 0, bytesRead);
126
+ }
127
+ outputStream.flush();
128
+ inputStream.close();
129
+
130
+ if (data != null) {
131
+ Iterator<String> keyIterator = data.keys();
132
+ while (keyIterator.hasNext()) {
133
+ String key = keyIterator.next();
134
+ try {
135
+ Object value = data.get(key);
136
+
137
+ if (!(value instanceof String)) continue;
138
+
139
+ appendFieldToWriter(key, value.toString());
140
+ } catch (JSONException e) {
141
+ e.printStackTrace();
142
+ }
143
+ }
144
+ }
145
+
146
+ prWriter.append(LINE_FEED).append("--").append(boundary).append("--").append(LINE_FEED);
147
+ prWriter.flush();
148
+ }
149
+
150
+ /**
151
+ * Adds a header field to the request.
152
+ *
153
+ * @param name - name of the header field
154
+ * @param value - value of the header field
155
+ */
156
+ public void addHeaderField(String name, String value) {
157
+ prWriter.append(name).append(": ").append(value).append(LINE_FEED);
158
+ prWriter.flush();
159
+ }
160
+
161
+ /**
162
+ * Completes the request and receives response from the server.
163
+ * returns a list of Strings as response in case the server returned
164
+ * status OK, otherwise an exception is thrown.
165
+ */
166
+ public void finish() {
167
+ prWriter.append(LINE_FEED);
168
+ prWriter.flush();
169
+ prWriter.append("--").append(boundary).append("--").append(LINE_FEED);
170
+ prWriter.close();
171
+ }
172
+ public void addFileBase64Part(String fieldName, JSONObject data){
173
+ try {
174
+ JSONObject file = new JSONObject(data.getString("file"));
175
+ String fileName = file.getString("name");
176
+ String base64 = file.getString("base64");
177
+ prWriter
178
+ .append(LINE_FEED)
179
+ .append("--")
180
+ .append(boundary)
181
+ .append(LINE_FEED)
182
+ .append("Content-Disposition: form-data; name=\"")
183
+ .append(fieldName)
184
+ .append("\"; filename=\"")
185
+ .append(fileName)
186
+ .append("\"")
187
+ .append(LINE_FEED)
188
+ .append("Content-Type: ")
189
+ .append(URLConnection.guessContentTypeFromName(fileName))
190
+ .append(LINE_FEED)
191
+ .append(LINE_FEED);
192
+ prWriter.flush();
193
+ byte[] buffer = Base64.decode(base64, Base64.DEFAULT);
194
+ outputStream.write(buffer);
195
+ outputStream.flush();
196
+
197
+ if (data != null) {
198
+ Iterator<String> keyIterator = data.keys();
199
+ while (keyIterator.hasNext()) {
200
+ String key = keyIterator.next();
201
+ try {
202
+ Object value = data.get(key);
203
+
204
+ if (!(value instanceof String)) continue;
205
+
206
+ appendFieldToWriter(key, value.toString());
207
+ } catch (JSONException e) {
208
+ e.printStackTrace();
209
+ }
210
+ }
211
+ }
212
+
213
+ prWriter.append(LINE_FEED).append("--").append(boundary).append("--").append(LINE_FEED);
214
+ prWriter.flush();
215
+ }catch (Exception ex){
216
+ ex.printStackTrace();
217
+ }
218
+ }
219
+ }