react-native-blob-util 0.14.0 → 0.14.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.
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +4 -5
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +69 -1
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java +107 -86
- package/package.json +1 -1
|
@@ -432,29 +432,29 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
432
432
|
if (mt == null) promise.reject("ReactNativeBlobUtil.createMediaFile", "invalid mediatype");
|
|
433
433
|
|
|
434
434
|
FileDescription file = new FileDescription(filedata.getString("name"), filedata.getString("mimeType"), filedata.getString("parentFolder"));
|
|
435
|
-
Uri res = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt));
|
|
435
|
+
Uri res = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt), this.getReactApplicationContext());
|
|
436
436
|
if (res != null) promise.resolve(res.toString());
|
|
437
437
|
else promise.reject("ReactNativeBlobUtil.createMediaFile", "File could not be created");
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
-
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
441
440
|
@ReactMethod
|
|
442
441
|
public void writeToMediaFile(String fileUri, String path, Promise promise) {
|
|
443
442
|
boolean res = ReactNativeBlobUtilMediaCollection.writeToMediaFile(Uri.parse(fileUri), path, promise);
|
|
444
443
|
if(res) promise.resolve("Success");
|
|
445
444
|
}
|
|
446
445
|
|
|
446
|
+
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
447
447
|
@ReactMethod
|
|
448
448
|
public void copyToInternal(String contentUri, String destpath, Promise promise) {
|
|
449
449
|
ReactNativeBlobUtilMediaCollection.copyToInternal(Uri.parse(contentUri), destpath, promise);
|
|
450
450
|
}
|
|
451
451
|
|
|
452
|
+
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
452
453
|
@ReactMethod
|
|
453
454
|
public void getBlob(String contentUri, String encoding, Promise promise) {
|
|
454
455
|
ReactNativeBlobUtilMediaCollection.getBlob(Uri.parse(contentUri), encoding, promise);
|
|
455
456
|
}
|
|
456
457
|
|
|
457
|
-
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
458
458
|
@ReactMethod
|
|
459
459
|
public void copyToMediaStore(ReadableMap filedata, String mt, String path, Promise promise) {
|
|
460
460
|
if (!(filedata.hasKey("name") && filedata.hasKey("parentFolder") && filedata.hasKey("mimeType"))) {
|
|
@@ -471,7 +471,7 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
FileDescription file = new FileDescription(filedata.getString("name"), filedata.getString("mimeType"), filedata.getString("parentFolder"));
|
|
474
|
-
Uri fileuri = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt));
|
|
474
|
+
Uri fileuri = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt), this.getReactApplicationContext());
|
|
475
475
|
|
|
476
476
|
if (fileuri == null) {
|
|
477
477
|
promise.reject("ReactNativeBlobUtil.createMediaFile", "File could not be created");
|
|
@@ -479,7 +479,6 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
479
479
|
}
|
|
480
480
|
|
|
481
481
|
boolean res = ReactNativeBlobUtilMediaCollection.writeToMediaFile(fileuri, path, promise);
|
|
482
|
-
|
|
483
482
|
if(res) promise.resolve(fileuri.toString());
|
|
484
483
|
}
|
|
485
484
|
|
|
@@ -44,6 +44,75 @@ class ReactNativeBlobUtilFS {
|
|
|
44
44
|
this.emitter = ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Write string with encoding to file (used for mediastore)
|
|
49
|
+
*
|
|
50
|
+
* @param path Destination file path.
|
|
51
|
+
* @param encoding Encoding of the string.
|
|
52
|
+
* @param data Array passed from JS context.
|
|
53
|
+
*/
|
|
54
|
+
static boolean writeFile(String path, String encoding, String data, final boolean append) {
|
|
55
|
+
try {
|
|
56
|
+
int written;
|
|
57
|
+
File f = new File(path);
|
|
58
|
+
File dir = f.getParentFile();
|
|
59
|
+
if (!f.exists()) {
|
|
60
|
+
if (dir != null && !dir.exists()) {
|
|
61
|
+
if (!dir.mkdirs() && !dir.exists()) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!f.createNewFile()) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// write data from a file
|
|
71
|
+
if (encoding.equalsIgnoreCase(ReactNativeBlobUtilConst.DATA_ENCODE_URI)) {
|
|
72
|
+
String normalizedData = ReactNativeBlobUtilUtils.normalizePath(data);
|
|
73
|
+
File src = new File(normalizedData);
|
|
74
|
+
if (!src.exists()) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
byte[] buffer = new byte[10240];
|
|
78
|
+
int read;
|
|
79
|
+
written = 0;
|
|
80
|
+
FileInputStream fin = null;
|
|
81
|
+
FileOutputStream fout = null;
|
|
82
|
+
try {
|
|
83
|
+
fin = new FileInputStream(src);
|
|
84
|
+
fout = new FileOutputStream(f, append);
|
|
85
|
+
while ((read = fin.read(buffer)) > 0) {
|
|
86
|
+
fout.write(buffer, 0, read);
|
|
87
|
+
written += read;
|
|
88
|
+
}
|
|
89
|
+
} finally {
|
|
90
|
+
if (fin != null) {
|
|
91
|
+
fin.close();
|
|
92
|
+
}
|
|
93
|
+
if (fout != null) {
|
|
94
|
+
fout.close();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
byte[] bytes = ReactNativeBlobUtilUtils.stringToBytes(data, encoding);
|
|
99
|
+
FileOutputStream fout = new FileOutputStream(f, append);
|
|
100
|
+
try {
|
|
101
|
+
fout.write(bytes);
|
|
102
|
+
written = bytes.length;
|
|
103
|
+
} finally {
|
|
104
|
+
fout.close();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
} catch (FileNotFoundException e) {
|
|
109
|
+
// According to https://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html
|
|
110
|
+
return false;
|
|
111
|
+
} catch (Exception e) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
47
116
|
/**
|
|
48
117
|
* Write string with encoding to file
|
|
49
118
|
*
|
|
@@ -57,7 +126,6 @@ class ReactNativeBlobUtilFS {
|
|
|
57
126
|
int written;
|
|
58
127
|
File f = new File(path);
|
|
59
128
|
File dir = f.getParentFile();
|
|
60
|
-
|
|
61
129
|
if (!f.exists()) {
|
|
62
130
|
if (dir != null && !dir.exists()) {
|
|
63
131
|
if (!dir.mkdirs() && !dir.exists()) {
|
package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java
CHANGED
|
@@ -10,11 +10,10 @@ import android.os.ParcelFileDescriptor;
|
|
|
10
10
|
import android.provider.MediaStore;
|
|
11
11
|
import android.util.Base64;
|
|
12
12
|
|
|
13
|
-
import androidx.annotation.RequiresApi;
|
|
14
|
-
|
|
15
13
|
import com.ReactNativeBlobUtil.Utils.FileDescription;
|
|
16
14
|
import com.facebook.react.bridge.Arguments;
|
|
17
15
|
import com.facebook.react.bridge.Promise;
|
|
16
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
18
17
|
import com.facebook.react.bridge.WritableArray;
|
|
19
18
|
|
|
20
19
|
import java.io.File;
|
|
@@ -62,21 +61,29 @@ public class ReactNativeBlobUtilMediaCollection {
|
|
|
62
61
|
return res;
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
private static String getRelativePath(MediaType mt) {
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
private static String getRelativePath(MediaType mt, ReactApplicationContext ctx) {
|
|
65
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
66
|
+
if (mt == MediaType.Audio) return Environment.DIRECTORY_MUSIC;
|
|
67
|
+
if (mt == MediaType.Video) return Environment.DIRECTORY_MOVIES;
|
|
68
|
+
if (mt == MediaType.Image) return Environment.DIRECTORY_PICTURES;
|
|
69
|
+
if (mt == MediaType.Download) return Environment.DIRECTORY_DOWNLOADS;
|
|
70
|
+
return Environment.DIRECTORY_DOWNLOADS;
|
|
71
|
+
} else {
|
|
72
|
+
if (mt == MediaType.Audio) return ReactNativeBlobUtilFS.getExternalFilesDirPath(ctx, Environment.DIRECTORY_MUSIC);
|
|
73
|
+
if (mt == MediaType.Video) return ReactNativeBlobUtilFS.getExternalFilesDirPath(ctx, Environment.DIRECTORY_MOVIES);
|
|
74
|
+
if (mt == MediaType.Image) return ReactNativeBlobUtilFS.getExternalFilesDirPath(ctx, Environment.DIRECTORY_PICTURES);
|
|
75
|
+
if (mt == MediaType.Download) return ReactNativeBlobUtilFS.getExternalFilesDirPath(ctx, Environment.DIRECTORY_DOWNLOADS);
|
|
76
|
+
return ReactNativeBlobUtilFS.getExternalFilesDirPath(ctx, Environment.DIRECTORY_DOWNLOADS);
|
|
77
|
+
}
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
public static Uri createNewMediaFile(FileDescription file, MediaType mt) {
|
|
80
|
+
public static Uri createNewMediaFile(FileDescription file, MediaType mt, ReactApplicationContext ctx) {
|
|
74
81
|
// Add a specific media item.
|
|
75
82
|
Context appCtx = ReactNativeBlobUtil.RCTContext.getApplicationContext();
|
|
76
83
|
ContentResolver resolver = appCtx.getContentResolver();
|
|
77
84
|
|
|
78
85
|
ContentValues fileDetails = new ContentValues();
|
|
79
|
-
String relativePath = getRelativePath(mt);
|
|
86
|
+
String relativePath = getRelativePath(mt, ctx);
|
|
80
87
|
String mimeType = file.mimeType;
|
|
81
88
|
|
|
82
89
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
@@ -91,12 +98,24 @@ public class ReactNativeBlobUtilMediaCollection {
|
|
|
91
98
|
// Keeps a handle to the new file's URI in case we need to modify it later.
|
|
92
99
|
return resolver.insert(mediauri, fileDetails);
|
|
93
100
|
} else {
|
|
94
|
-
File
|
|
95
|
-
if (
|
|
96
|
-
File f = new File(relativePath + '/' + file.getFullPath());
|
|
101
|
+
File f = new File(relativePath + file.getFullPath());
|
|
102
|
+
if (true) {
|
|
97
103
|
if (!f.exists()) {
|
|
98
|
-
|
|
99
|
-
if (
|
|
104
|
+
File parent = f.getParentFile();
|
|
105
|
+
if (parent != null && !parent.exists() && !parent.mkdirs()) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
if (f.createNewFile()) ;
|
|
110
|
+
{
|
|
111
|
+
return Uri.fromFile(f);
|
|
112
|
+
}
|
|
113
|
+
} catch (IOException ioException) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
} else {
|
|
118
|
+
return Uri.fromFile(f);
|
|
100
119
|
}
|
|
101
120
|
|
|
102
121
|
}
|
|
@@ -105,83 +124,84 @@ public class ReactNativeBlobUtilMediaCollection {
|
|
|
105
124
|
return null;
|
|
106
125
|
}
|
|
107
126
|
|
|
108
|
-
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
109
127
|
public static boolean writeToMediaFile(Uri fileUri, String data, Promise promise) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
128
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
129
|
+
try {
|
|
130
|
+
Context appCtx = ReactNativeBlobUtil.RCTContext.getApplicationContext();
|
|
131
|
+
ContentResolver resolver = appCtx.getContentResolver();
|
|
113
132
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
133
|
+
// set pending doesn't work right now. We would have to requery for the item
|
|
134
|
+
//ContentValues contentValues = new ContentValues();
|
|
135
|
+
//contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1);
|
|
136
|
+
//resolver.update(fileUri, contentValues, null, null);
|
|
118
137
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
138
|
+
// write data
|
|
139
|
+
OutputStream stream = null;
|
|
140
|
+
Uri uri = null;
|
|
122
141
|
|
|
123
|
-
try {
|
|
124
|
-
ParcelFileDescriptor descr;
|
|
125
142
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
143
|
+
ParcelFileDescriptor descr;
|
|
144
|
+
try {
|
|
145
|
+
assert fileUri != null;
|
|
146
|
+
descr = appCtx.getContentResolver().openFileDescriptor(fileUri, "w");
|
|
147
|
+
assert descr != null;
|
|
148
|
+
String normalizedData = ReactNativeBlobUtilUtils.normalizePath(data);
|
|
149
|
+
File src = new File(normalizedData);
|
|
150
|
+
if (!src.exists()) {
|
|
151
|
+
promise.reject("ENOENT", "No such file ('" + normalizedData + "')");
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
byte[] buf = new byte[10240];
|
|
155
|
+
int read;
|
|
156
|
+
|
|
157
|
+
FileInputStream fin = new FileInputStream(src);
|
|
158
|
+
FileOutputStream out = new FileOutputStream(descr.getFileDescriptor());
|
|
159
|
+
|
|
160
|
+
while ((read = fin.read(buf)) > 0) {
|
|
161
|
+
out.write(buf, 0, read);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
fin.close();
|
|
165
|
+
out.close();
|
|
166
|
+
descr.close();
|
|
167
|
+
} catch (Exception e) {
|
|
168
|
+
e.printStackTrace();
|
|
169
|
+
promise.reject(new IOException("Failed to get output stream."));
|
|
133
170
|
return false;
|
|
134
171
|
}
|
|
135
|
-
byte[] buf = new byte[10240];
|
|
136
|
-
int read;
|
|
137
|
-
int written = 0;
|
|
138
|
-
|
|
139
|
-
FileInputStream fin = new FileInputStream(src);
|
|
140
|
-
FileOutputStream out = new FileOutputStream(descr.getFileDescriptor());
|
|
141
172
|
|
|
142
|
-
|
|
143
|
-
|
|
173
|
+
//contentValues.clear();
|
|
174
|
+
//contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
|
|
175
|
+
//appCtx.getContentResolver().update(fileUri, contentValues, null, null);
|
|
176
|
+
stream = resolver.openOutputStream(fileUri);
|
|
177
|
+
if (stream == null) {
|
|
178
|
+
promise.reject(new IOException("Failed to get output stream."));
|
|
179
|
+
return false;
|
|
144
180
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
} catch (Exception e) {
|
|
150
|
-
e.printStackTrace();
|
|
151
|
-
promise.reject(new IOException("Failed to get output stream."));
|
|
181
|
+
} catch (IOException e) {
|
|
182
|
+
// Don't leave an orphan entry in the MediaStore
|
|
183
|
+
resolver.delete(uri, null, null);
|
|
184
|
+
promise.reject(e);
|
|
152
185
|
return false;
|
|
186
|
+
} finally {
|
|
187
|
+
if (stream != null) {
|
|
188
|
+
stream.close();
|
|
189
|
+
}
|
|
153
190
|
}
|
|
154
191
|
|
|
155
|
-
|
|
156
|
-
contentValues
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
promise.reject(new IOException("Failed to get output stream."));
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
192
|
+
// remove pending
|
|
193
|
+
//contentValues = new ContentValues();
|
|
194
|
+
//contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
|
|
195
|
+
//resolver.update(fileUri, contentValues, null, null);
|
|
196
|
+
|
|
163
197
|
} catch (IOException e) {
|
|
164
|
-
|
|
165
|
-
resolver.delete(uri, null, null);
|
|
166
|
-
promise.reject(e);
|
|
198
|
+
promise.reject("ReactNativeBlobUtil.createMediaFile", "Cannot write to file, file might not exist");
|
|
167
199
|
return false;
|
|
168
|
-
} finally {
|
|
169
|
-
if (stream != null) {
|
|
170
|
-
stream.close();
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
173
200
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
|
|
178
|
-
resolver.update(fileUri, contentValues, null, null);
|
|
179
|
-
|
|
180
|
-
} catch (IOException e) {
|
|
181
|
-
promise.reject("ReactNativeBlobUtil.createMediaFile", "Cannot write to file, file might not exist");
|
|
182
|
-
return false;
|
|
201
|
+
return true;
|
|
202
|
+
} else {
|
|
203
|
+
return ReactNativeBlobUtilFS.writeFile(ReactNativeBlobUtilUtils.normalizePath(fileUri.toString()), ReactNativeBlobUtilConst.DATA_ENCODE_URI, data, false);
|
|
183
204
|
}
|
|
184
|
-
return true;
|
|
185
205
|
}
|
|
186
206
|
|
|
187
207
|
public static void copyToInternal(Uri contenturi, String destpath, Promise promise) {
|
|
@@ -190,10 +210,16 @@ public class ReactNativeBlobUtilMediaCollection {
|
|
|
190
210
|
|
|
191
211
|
InputStream in = null;
|
|
192
212
|
OutputStream out = null;
|
|
213
|
+
File f = new File((destpath));
|
|
193
214
|
|
|
194
|
-
if (!
|
|
215
|
+
if (!f.exists()) {
|
|
195
216
|
try {
|
|
196
|
-
|
|
217
|
+
File parent = f.getParentFile();
|
|
218
|
+
if (parent != null && !parent.exists() && !parent.mkdirs()) {
|
|
219
|
+
promise.reject("ReactNativeBlobUtil.copyToInternal: Cannot create parent folders<'" + destpath);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
boolean result = f.createNewFile();
|
|
197
223
|
if (!result) {
|
|
198
224
|
promise.reject("ReactNativeBlobUtil.copyToInternal: Destination file at '" + destpath + "' already exists");
|
|
199
225
|
return;
|
|
@@ -240,9 +266,7 @@ public class ReactNativeBlobUtilMediaCollection {
|
|
|
240
266
|
ContentResolver resolver = appCtx.getContentResolver();
|
|
241
267
|
try {
|
|
242
268
|
InputStream in = resolver.openInputStream(contentUri);
|
|
243
|
-
int length =
|
|
244
|
-
|
|
245
|
-
length = in.available();
|
|
269
|
+
int length = in.available();
|
|
246
270
|
|
|
247
271
|
byte[] bytes = new byte[length];
|
|
248
272
|
int bytesRead = in.read(bytes);
|
|
@@ -260,14 +284,11 @@ public class ReactNativeBlobUtilMediaCollection {
|
|
|
260
284
|
case "ascii":
|
|
261
285
|
WritableArray asciiResult = Arguments.createArray();
|
|
262
286
|
for (byte b : bytes) {
|
|
263
|
-
asciiResult.pushInt(
|
|
287
|
+
asciiResult.pushInt(b);
|
|
264
288
|
}
|
|
265
289
|
promise.resolve(asciiResult);
|
|
266
290
|
break;
|
|
267
|
-
|
|
268
|
-
promise.resolve(new String(bytes));
|
|
269
|
-
break;
|
|
270
|
-
default:
|
|
291
|
+
default: // covers utf-8
|
|
271
292
|
promise.resolve(new String(bytes));
|
|
272
293
|
break;
|
|
273
294
|
}
|
package/package.json
CHANGED