tharak-android 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +1 -0
- package/build.gradle +45 -0
- package/consumer-rules.pro +0 -0
- package/libs/vital-sdk.aar +0 -0
- package/package.json +22 -0
- package/proguard-rules.pro +21 -0
- package/src/androidTest/androidTest.iml +11 -0
- package/src/androidTest/java/org/tharak/core/ExampleInstrumentedTest.java +27 -0
- package/src/androidTest/java/org/thiragatisoft/core/ExampleInstrumentedTest.java +26 -0
- package/src/main/AndroidManifest.xml +5 -0
- package/src/main/java/org/thiragatisoft/core/AppUtils.java +31 -0
- package/src/main/java/org/thiragatisoft/core/FileSelector.java +162 -0
- package/src/main/java/org/thiragatisoft/core/MainActivity.java +27 -0
- package/src/main/java/org/thiragatisoft/core/RestClient.java +298 -0
- package/src/main/java/org/thiragatisoft/core/VitalActivity.java +612 -0
- package/src/main/java/org/thiragatisoft/core/VitalsPlugin.java +15 -0
- package/src/main/java/org/thiragatisoft/core/VolleyMultipartRequest.java +218 -0
- package/src/main/java/org/thiragatisoft/core/http/CapacitorCookieManager.java +175 -0
- package/src/main/java/org/thiragatisoft/core/http/CapacitorHttpUrlConnection.java +408 -0
- package/src/main/java/org/thiragatisoft/core/http/FilesystemUtils.java +65 -0
- package/src/main/java/org/thiragatisoft/core/http/FormUploader.java +219 -0
- package/src/main/java/org/thiragatisoft/core/http/Http.java +275 -0
- package/src/main/java/org/thiragatisoft/core/http/HttpRequestHandler.java +515 -0
- package/src/main/java/org/thiragatisoft/core/http/ICapacitorHttpUrlConnection.java +15 -0
- package/src/main/java/org/thiragatisoft/core/http/JSValue.java +68 -0
- package/src/main/java/org/thiragatisoft/core/http/MimeType.java +17 -0
- package/src/main/main.iml +12 -0
- package/src/test/java/org/tharak/ExampleUnitTest.java +17 -0
- package/src/test/java/org/tharak/JSObjectTest.java +209 -0
- package/src/test/java/org/tharak/PluginMethodHandleTest.java +44 -0
- package/src/test/java/org/tharak/util/HostMaskTest.java +70 -0
- package/src/test/java/org/thiragatisoft/core/ExampleUnitTest.java +17 -0
- 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
|
+
}
|