react-native-blob-util 0.13.18 → 0.14.0
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.
- package/README.md +471 -406
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +86 -21
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilBody.java +14 -15
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +8 -6
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +21 -286
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java +278 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilPackage.java +6 -2
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +17 -21
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilStream.java +287 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilUtils.java +57 -2
- package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +5 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileDescription.java +19 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/MimeType.java +70 -0
- package/fs.js +2 -1
- package/index.d.ts +92 -1
- package/index.js +2 -0
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.m +2 -1
- package/ios/ReactNativeBlobUtilFS.h +1 -0
- package/ios/ReactNativeBlobUtilFS.m +4 -0
- package/mediacollection.js +33 -0
- package/package.json +1 -1
- package/scripts/prelink.js +1 -1
- package/types.js +3 -0
package/android/build.gradle
CHANGED
|
@@ -2,16 +2,17 @@ package com.ReactNativeBlobUtil;
|
|
|
2
2
|
|
|
3
3
|
import android.app.Activity;
|
|
4
4
|
import android.app.DownloadManager;
|
|
5
|
+
import android.content.ActivityNotFoundException;
|
|
5
6
|
import android.content.Intent;
|
|
6
|
-
import android.content.pm.PackageManager;
|
|
7
7
|
import android.net.Uri;
|
|
8
8
|
import android.os.Build;
|
|
9
|
+
import android.util.SparseArray;
|
|
9
10
|
|
|
11
|
+
import androidx.annotation.NonNull;
|
|
12
|
+
import androidx.annotation.RequiresApi;
|
|
10
13
|
import androidx.core.content.FileProvider;
|
|
11
14
|
|
|
12
|
-
import
|
|
13
|
-
import android.content.ActivityNotFoundException;
|
|
14
|
-
|
|
15
|
+
import com.ReactNativeBlobUtil.Utils.FileDescription;
|
|
15
16
|
import com.facebook.react.bridge.ActivityEventListener;
|
|
16
17
|
import com.facebook.react.bridge.Callback;
|
|
17
18
|
import com.facebook.react.bridge.LifecycleEventListener;
|
|
@@ -21,24 +22,22 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
|
21
22
|
import com.facebook.react.bridge.ReactMethod;
|
|
22
23
|
import com.facebook.react.bridge.ReadableArray;
|
|
23
24
|
import com.facebook.react.bridge.ReadableMap;
|
|
24
|
-
|
|
25
|
-
// Cookies
|
|
26
25
|
import com.facebook.react.bridge.WritableMap;
|
|
27
|
-
import com.facebook.react.modules.network.ForwardingCookieHandler;
|
|
28
26
|
import com.facebook.react.modules.network.CookieJarContainer;
|
|
27
|
+
import com.facebook.react.modules.network.ForwardingCookieHandler;
|
|
29
28
|
import com.facebook.react.modules.network.OkHttpClientProvider;
|
|
30
29
|
|
|
31
|
-
import okhttp3.JavaNetCookieJar;
|
|
32
|
-
import okhttp3.OkHttpClient;
|
|
33
|
-
|
|
34
|
-
import javax.annotation.Nullable;
|
|
35
|
-
|
|
36
30
|
import java.io.File;
|
|
37
31
|
import java.util.Map;
|
|
38
32
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
39
33
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
40
34
|
import java.util.concurrent.TimeUnit;
|
|
41
35
|
|
|
36
|
+
import javax.annotation.Nullable;
|
|
37
|
+
|
|
38
|
+
import okhttp3.JavaNetCookieJar;
|
|
39
|
+
import okhttp3.OkHttpClient;
|
|
40
|
+
|
|
42
41
|
import static android.app.Activity.RESULT_OK;
|
|
43
42
|
import static com.ReactNativeBlobUtil.ReactNativeBlobUtilConst.GET_CONTENT_INTENT;
|
|
44
43
|
|
|
@@ -81,6 +80,7 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
81
80
|
});
|
|
82
81
|
}
|
|
83
82
|
|
|
83
|
+
@NonNull
|
|
84
84
|
@Override
|
|
85
85
|
public String getName() {
|
|
86
86
|
return "ReactNativeBlobUtil";
|
|
@@ -114,9 +114,13 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
114
114
|
@ReactMethod
|
|
115
115
|
public void actionViewIntent(String path, String mime, @Nullable String chooserTitle, final Promise promise) {
|
|
116
116
|
try {
|
|
117
|
-
Uri uriForFile =
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
Uri uriForFile = null;
|
|
118
|
+
if (!ReactNativeBlobUtilUtils.isContentUri(path)) {
|
|
119
|
+
uriForFile = FileProvider.getUriForFile(this.getReactApplicationContext(),
|
|
120
|
+
this.getReactApplicationContext().getPackageName() + ".provider", new File(path));
|
|
121
|
+
} else {
|
|
122
|
+
uriForFile = Uri.parse(path);
|
|
123
|
+
}
|
|
120
124
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
121
125
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
122
126
|
// Create the intent with data and type
|
|
@@ -170,7 +174,7 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
170
174
|
|
|
171
175
|
@ReactMethod
|
|
172
176
|
public void writeArrayChunk(final String streamId, final ReadableArray dataArray, final Callback callback) {
|
|
173
|
-
|
|
177
|
+
ReactNativeBlobUtilStream.writeArrayChunk(streamId, dataArray, callback);
|
|
174
178
|
}
|
|
175
179
|
|
|
176
180
|
@ReactMethod
|
|
@@ -210,17 +214,17 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
210
214
|
|
|
211
215
|
@ReactMethod
|
|
212
216
|
public void writeStream(String path, String encode, boolean append, Callback callback) {
|
|
213
|
-
new
|
|
217
|
+
new ReactNativeBlobUtilStream(this.getReactApplicationContext()).writeStream(path, encode, append, callback);
|
|
214
218
|
}
|
|
215
219
|
|
|
216
220
|
@ReactMethod
|
|
217
221
|
public void writeChunk(String streamId, String data, Callback callback) {
|
|
218
|
-
|
|
222
|
+
ReactNativeBlobUtilStream.writeChunk(streamId, data, callback);
|
|
219
223
|
}
|
|
220
224
|
|
|
221
225
|
@ReactMethod
|
|
222
226
|
public void closeStream(String streamId, Callback callback) {
|
|
223
|
-
|
|
227
|
+
ReactNativeBlobUtilStream.closeStream(streamId, callback);
|
|
224
228
|
}
|
|
225
229
|
|
|
226
230
|
@ReactMethod
|
|
@@ -313,7 +317,7 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
313
317
|
fsThreadPool.execute(new Runnable() {
|
|
314
318
|
@Override
|
|
315
319
|
public void run() {
|
|
316
|
-
|
|
320
|
+
ReactNativeBlobUtilStream fs = new ReactNativeBlobUtilStream(ctx);
|
|
317
321
|
fs.readStream(path, encoding, bufferSize, tick, streamId);
|
|
318
322
|
}
|
|
319
323
|
});
|
|
@@ -386,7 +390,7 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
386
390
|
promise.reject("EINVAL", "ReactNativeBlobUtil.addCompleteDownload config or path missing.");
|
|
387
391
|
return;
|
|
388
392
|
}
|
|
389
|
-
String path =
|
|
393
|
+
String path = ReactNativeBlobUtilUtils.normalizePath(config.getString("path"));
|
|
390
394
|
if (path == null) {
|
|
391
395
|
promise.reject("EINVAL", "ReactNativeBlobUtil.addCompleteDownload can not resolve URI:" + config.getString("path"));
|
|
392
396
|
return;
|
|
@@ -418,4 +422,65 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
418
422
|
public void getSDCardApplicationDir(Promise promise) {
|
|
419
423
|
ReactNativeBlobUtilFS.getSDCardApplicationDir(this.getReactApplicationContext(), promise);
|
|
420
424
|
}
|
|
425
|
+
|
|
426
|
+
@ReactMethod
|
|
427
|
+
public void createMediaFile(ReadableMap filedata, String mt, Promise promise) {
|
|
428
|
+
if (!(filedata.hasKey("name") && filedata.hasKey("parentFolder") && filedata.hasKey("mimeType"))) {
|
|
429
|
+
promise.reject("ReactNativeBlobUtil.createMediaFile", "invalid filedata: " + filedata.toString());
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
if (mt == null) promise.reject("ReactNativeBlobUtil.createMediaFile", "invalid mediatype");
|
|
433
|
+
|
|
434
|
+
FileDescription file = new FileDescription(filedata.getString("name"), filedata.getString("mimeType"), filedata.getString("parentFolder"));
|
|
435
|
+
Uri res = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt));
|
|
436
|
+
if (res != null) promise.resolve(res.toString());
|
|
437
|
+
else promise.reject("ReactNativeBlobUtil.createMediaFile", "File could not be created");
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
441
|
+
@ReactMethod
|
|
442
|
+
public void writeToMediaFile(String fileUri, String path, Promise promise) {
|
|
443
|
+
boolean res = ReactNativeBlobUtilMediaCollection.writeToMediaFile(Uri.parse(fileUri), path, promise);
|
|
444
|
+
if(res) promise.resolve("Success");
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
@ReactMethod
|
|
448
|
+
public void copyToInternal(String contentUri, String destpath, Promise promise) {
|
|
449
|
+
ReactNativeBlobUtilMediaCollection.copyToInternal(Uri.parse(contentUri), destpath, promise);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
@ReactMethod
|
|
453
|
+
public void getBlob(String contentUri, String encoding, Promise promise) {
|
|
454
|
+
ReactNativeBlobUtilMediaCollection.getBlob(Uri.parse(contentUri), encoding, promise);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
458
|
+
@ReactMethod
|
|
459
|
+
public void copyToMediaStore(ReadableMap filedata, String mt, String path, Promise promise) {
|
|
460
|
+
if (!(filedata.hasKey("name") && filedata.hasKey("parentFolder") && filedata.hasKey("mimeType"))) {
|
|
461
|
+
promise.reject("ReactNativeBlobUtil.createMediaFile", "invalid filedata: " + filedata.toString());
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
if (mt == null) {
|
|
465
|
+
promise.reject("ReactNativeBlobUtil.createMediaFile", "invalid mediatype");
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
if (path == null) {
|
|
469
|
+
promise.reject("ReactNativeBlobUtil.createMediaFile", "invalid path");
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
FileDescription file = new FileDescription(filedata.getString("name"), filedata.getString("mimeType"), filedata.getString("parentFolder"));
|
|
474
|
+
Uri fileuri = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt));
|
|
475
|
+
|
|
476
|
+
if (fileuri == null) {
|
|
477
|
+
promise.reject("ReactNativeBlobUtil.createMediaFile", "File could not be created");
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
boolean res = ReactNativeBlobUtilMediaCollection.writeToMediaFile(fileuri, path, promise);
|
|
482
|
+
|
|
483
|
+
if(res) promise.resolve(fileuri.toString());
|
|
484
|
+
}
|
|
485
|
+
|
|
421
486
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
package com.ReactNativeBlobUtil;
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
import android.net.Uri;
|
|
5
4
|
import android.util.Base64;
|
|
6
5
|
|
|
6
|
+
import androidx.annotation.NonNull;
|
|
7
|
+
|
|
7
8
|
import com.facebook.react.bridge.Arguments;
|
|
8
9
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
9
10
|
import com.facebook.react.bridge.ReadableArray;
|
|
@@ -19,8 +20,6 @@ import java.io.IOException;
|
|
|
19
20
|
import java.io.InputStream;
|
|
20
21
|
import java.util.ArrayList;
|
|
21
22
|
|
|
22
|
-
import android.net.Uri;
|
|
23
|
-
|
|
24
23
|
import okhttp3.MediaType;
|
|
25
24
|
import okhttp3.RequestBody;
|
|
26
25
|
import okio.BufferedSink;
|
|
@@ -145,9 +144,9 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
145
144
|
// upload from storage
|
|
146
145
|
if (rawBody.startsWith(ReactNativeBlobUtilConst.FILE_PREFIX)) {
|
|
147
146
|
String orgPath = rawBody.substring(ReactNativeBlobUtilConst.FILE_PREFIX.length());
|
|
148
|
-
orgPath =
|
|
147
|
+
orgPath = ReactNativeBlobUtilUtils.normalizePath(orgPath);
|
|
149
148
|
// upload file from assets
|
|
150
|
-
if (
|
|
149
|
+
if (ReactNativeBlobUtilUtils.isAsset(orgPath)) {
|
|
151
150
|
try {
|
|
152
151
|
String assetName = orgPath.replace(ReactNativeBlobUtilConst.FILE_PREFIX_BUNDLE_ASSET, "");
|
|
153
152
|
return ReactNativeBlobUtil.RCTContext.getAssets().open(assetName);
|
|
@@ -155,7 +154,7 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
155
154
|
throw new Exception("error when getting request stream from asset : " + e.getLocalizedMessage());
|
|
156
155
|
}
|
|
157
156
|
} else {
|
|
158
|
-
File f = new File(
|
|
157
|
+
File f = new File(ReactNativeBlobUtilUtils.normalizePath(orgPath));
|
|
159
158
|
try {
|
|
160
159
|
if (!f.exists())
|
|
161
160
|
f.createNewFile();
|
|
@@ -187,7 +186,7 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
187
186
|
* Create a temp file that contains content of multipart form data content
|
|
188
187
|
*
|
|
189
188
|
* @return The cache file object
|
|
190
|
-
* @throws IOException
|
|
189
|
+
* @throws IOException .
|
|
191
190
|
*/
|
|
192
191
|
private File createMultipartBodyCache() throws IOException {
|
|
193
192
|
String boundary = "ReactNativeBlobUtil-" + mTaskId;
|
|
@@ -215,9 +214,9 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
215
214
|
// upload from storage
|
|
216
215
|
if (data.startsWith(ReactNativeBlobUtilConst.FILE_PREFIX)) {
|
|
217
216
|
String orgPath = data.substring(ReactNativeBlobUtilConst.FILE_PREFIX.length());
|
|
218
|
-
orgPath =
|
|
217
|
+
orgPath = ReactNativeBlobUtilUtils.normalizePath(orgPath);
|
|
219
218
|
// path starts with content://
|
|
220
|
-
if (
|
|
219
|
+
if (ReactNativeBlobUtilUtils.isAsset(orgPath)) {
|
|
221
220
|
try {
|
|
222
221
|
String assetName = orgPath.replace(ReactNativeBlobUtilConst.FILE_PREFIX_BUNDLE_ASSET, "");
|
|
223
222
|
InputStream in = ctx.getAssets().open(assetName);
|
|
@@ -228,7 +227,7 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
228
227
|
}
|
|
229
228
|
// data from normal files
|
|
230
229
|
else {
|
|
231
|
-
File file = new File(
|
|
230
|
+
File file = new File(ReactNativeBlobUtilUtils.normalizePath(orgPath));
|
|
232
231
|
if (file.exists()) {
|
|
233
232
|
FileInputStream fs = new FileInputStream(file);
|
|
234
233
|
pipeStreamToFileStream(fs, os);
|
|
@@ -282,7 +281,7 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
282
281
|
*
|
|
283
282
|
* @param stream The input stream
|
|
284
283
|
* @param sink The request body buffer sink
|
|
285
|
-
* @throws IOException
|
|
284
|
+
* @throws IOException .
|
|
286
285
|
*/
|
|
287
286
|
private void pipeStreamToSink(InputStream stream, BufferedSink sink) throws IOException {
|
|
288
287
|
byte[] chunk = new byte[10240];
|
|
@@ -332,9 +331,9 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
332
331
|
// upload from storage
|
|
333
332
|
if (data.startsWith(ReactNativeBlobUtilConst.FILE_PREFIX)) {
|
|
334
333
|
String orgPath = data.substring(ReactNativeBlobUtilConst.FILE_PREFIX.length());
|
|
335
|
-
orgPath =
|
|
334
|
+
orgPath = ReactNativeBlobUtilUtils.normalizePath(orgPath);
|
|
336
335
|
// path starts with asset://
|
|
337
|
-
if (
|
|
336
|
+
if (ReactNativeBlobUtilUtils.isAsset(orgPath)) {
|
|
338
337
|
try {
|
|
339
338
|
String assetName = orgPath.replace(ReactNativeBlobUtilConst.FILE_PREFIX_BUNDLE_ASSET, "");
|
|
340
339
|
long length = ctx.getAssets().open(assetName).available();
|
|
@@ -345,7 +344,7 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
345
344
|
}
|
|
346
345
|
// general files
|
|
347
346
|
else {
|
|
348
|
-
File file = new File(
|
|
347
|
+
File file = new File(ReactNativeBlobUtilUtils.normalizePath(orgPath));
|
|
349
348
|
total += file.length();
|
|
350
349
|
}
|
|
351
350
|
} else if (data.startsWith(ReactNativeBlobUtilConst.CONTENT_PREFIX)) {
|
|
@@ -3,6 +3,8 @@ package com.ReactNativeBlobUtil;
|
|
|
3
3
|
import com.facebook.react.bridge.ReadableArray;
|
|
4
4
|
import com.facebook.react.bridge.ReadableMap;
|
|
5
5
|
|
|
6
|
+
import java.util.Locale;
|
|
7
|
+
|
|
6
8
|
class ReactNativeBlobUtilConfig {
|
|
7
9
|
|
|
8
10
|
public Boolean fileCache;
|
|
@@ -23,17 +25,17 @@ class ReactNativeBlobUtilConfig {
|
|
|
23
25
|
ReactNativeBlobUtilConfig(ReadableMap options) {
|
|
24
26
|
if (options == null)
|
|
25
27
|
return;
|
|
26
|
-
this.fileCache = options.hasKey("fileCache")
|
|
28
|
+
this.fileCache = options.hasKey("fileCache") && options.getBoolean("fileCache");
|
|
27
29
|
this.path = options.hasKey("path") ? options.getString("path") : null;
|
|
28
30
|
this.appendExt = options.hasKey("appendExt") ? options.getString("appendExt") : "";
|
|
29
|
-
this.trusty = options.hasKey("trusty")
|
|
30
|
-
this.wifiOnly = options.hasKey("wifiOnly")
|
|
31
|
+
this.trusty = options.hasKey("trusty") && options.getBoolean("trusty");
|
|
32
|
+
this.wifiOnly = options.hasKey("wifiOnly") && options.getBoolean("wifiOnly");
|
|
31
33
|
if (options.hasKey("addAndroidDownloads")) {
|
|
32
34
|
this.addAndroidDownloads = options.getMap("addAndroidDownloads");
|
|
33
35
|
}
|
|
34
36
|
if (options.hasKey("binaryContentTypes"))
|
|
35
37
|
this.binaryContentTypes = options.getArray("binaryContentTypes");
|
|
36
|
-
if (this.path != null && path.toLowerCase().contains("?append=true")) {
|
|
38
|
+
if (this.path != null && path.toLowerCase(Locale.ROOT).contains("?append=true")) {
|
|
37
39
|
this.overwrite = false;
|
|
38
40
|
}
|
|
39
41
|
if (options.hasKey("overwrite"))
|
|
@@ -43,8 +45,8 @@ class ReactNativeBlobUtilConfig {
|
|
|
43
45
|
}
|
|
44
46
|
this.key = options.hasKey("key") ? options.getString("key") : null;
|
|
45
47
|
this.mime = options.hasKey("contentType") ? options.getString("contentType") : null;
|
|
46
|
-
this.increment = options.hasKey("increment")
|
|
47
|
-
this.auto = options.hasKey("auto")
|
|
48
|
+
this.increment = options.hasKey("increment") && options.getBoolean("increment");
|
|
49
|
+
this.auto = options.hasKey("auto") && options.getBoolean("auto");
|
|
48
50
|
if (options.hasKey("timeout")) {
|
|
49
51
|
this.timeout = options.getInt("timeout");
|
|
50
52
|
}
|