react-native-blob-util 0.22.0 → 0.22.2
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/.eslintrc.js +56 -56
- package/LICENSE +21 -21
- package/Migration.md +41 -41
- package/NuGet.config +11 -11
- package/README.md +1109 -1104
- package/android/gradle.properties +1 -1
- package/android/src/main/AndroidManifest.xml +37 -37
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +57 -57
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConst.java +20 -20
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFileTransformer.java +9 -9
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilImpl.java +431 -431
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilProgressConfig.java +39 -39
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +1014 -1014
- package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilDefaultResp.java +98 -98
- package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +166 -166
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileDescription.java +19 -19
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileProvider.java +4 -4
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/MimeType.java +70 -70
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/PathResolver.java +223 -223
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/Tls12SocketFactory.java +68 -68
- package/android/src/main/res/values/strings.xml +3 -3
- package/android/src/main/res/xml/provider_paths.xml +12 -12
- package/android.js +58 -58
- package/class/ReactNativeBlobUtilCanceledFetchError.js +9 -9
- package/class/ReactNativeBlobUtilFile.js +5 -5
- package/class/ReactNativeBlobUtilReadStream.js +84 -84
- package/class/ReactNativeBlobUtilSession.js +68 -68
- package/class/ReactNativeBlobUtilWriteStream.js +50 -50
- package/class/StatefulPromise.js +7 -7
- package/codegenSpecs/NativeBlobUtils.js +86 -86
- package/components/Fetch.onPress.js +10 -10
- package/components/Fetch.when.js +15 -15
- package/fetch.js +350 -350
- package/fs.js +480 -480
- package/index.js +64 -64
- package/index.js.flow +192 -192
- package/index.web.js +1 -1
- package/ios/PrivacyInfo.xcprivacy +28 -28
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.h +55 -55
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.mm +992 -992
- package/ios/ReactNativeBlobUtil.xcodeproj/project.pbxproj +405 -405
- package/ios/ReactNativeBlobUtilConst.h +58 -58
- package/ios/ReactNativeBlobUtilConst.mm +47 -47
- package/ios/ReactNativeBlobUtilFS.h +108 -108
- package/ios/ReactNativeBlobUtilFS.mm +1064 -1064
- package/ios/ReactNativeBlobUtilFileTransformer.h +23 -23
- package/ios/ReactNativeBlobUtilFileTransformer.mm +20 -20
- package/ios/ReactNativeBlobUtilNetwork.h +49 -49
- package/ios/ReactNativeBlobUtilNetwork.mm +159 -159
- package/ios/ReactNativeBlobUtilProgress.h +32 -32
- package/ios/ReactNativeBlobUtilProgress.mm +57 -57
- package/ios/ReactNativeBlobUtilReqBuilder.h +37 -37
- package/ios/ReactNativeBlobUtilReqBuilder.mm +292 -292
- package/ios/ReactNativeBlobUtilRequest.h +48 -48
- package/ios/ReactNativeBlobUtilRequest.mm +584 -584
- package/ios.js +61 -61
- package/json-stream.js +42 -42
- package/lib/oboe-browser.js +2703 -2703
- package/mediacollection.js +36 -36
- package/package.json +68 -68
- package/polyfill/Blob.js +362 -362
- package/polyfill/Event.js +11 -11
- package/polyfill/EventTarget.js +78 -78
- package/polyfill/Fetch.js +219 -219
- package/polyfill/File.js +27 -27
- package/polyfill/FileReader.js +91 -91
- package/polyfill/ProgressEvent.js +32 -32
- package/polyfill/XMLHttpRequest.js +466 -466
- package/polyfill/XMLHttpRequestEventTarget.js +126 -126
- package/polyfill/index.js +11 -11
- package/react-native-blob-util.podspec +48 -48
- package/types.js +69 -69
- package/utils/log.js +40 -40
- package/utils/unicode.js +7 -7
- package/utils/uri.js +33 -33
- package/utils/uuid.js +4 -4
- package/windows/ExperimentalFeatures.props +33 -33
- package/windows/README.md +2 -2
- package/windows/ReactNativeBlobUtil/PropertySheet.props +15 -15
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.cpp +1836 -1836
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.def +3 -3
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.h +372 -372
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.vcxproj +139 -139
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.vcxproj.filters +43 -43
- package/windows/ReactNativeBlobUtil/ReactPackageProvider.cpp +20 -20
- package/windows/ReactNativeBlobUtil/ReactPackageProvider.h +24 -24
- package/windows/ReactNativeBlobUtil/ReactPackageProvider.idl +9 -9
- package/windows/ReactNativeBlobUtil/codegen/.clang-format +1 -1
- package/windows/ReactNativeBlobUtil/codegen/NativeBlobUtilsDataTypes.g.h +42 -42
- package/windows/ReactNativeBlobUtil/codegen/NativeBlobUtilsSpec.g.h +353 -353
- package/windows/ReactNativeBlobUtil/packages.config +3 -3
- package/windows/ReactNativeBlobUtil/packages.lock.json +59 -59
- package/windows/ReactNativeBlobUtil/pch.cpp +1 -1
- package/windows/ReactNativeBlobUtil/pch.h +30 -30
- package/windows/ReactNativeBlobUtil/resource.h +5 -5
- package/windows/ReactNativeBlobUtil/targetver.h +8 -8
- package/windows/ReactNativeBlobUtil.sln +43 -43
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
package com.ReactNativeBlobUtil.Utils;
|
|
2
|
-
|
|
3
|
-
import android.webkit.MimeTypeMap;
|
|
4
|
-
|
|
5
|
-
import org.apache.commons.lang3.StringUtils;
|
|
6
|
-
|
|
7
|
-
public class MimeType {
|
|
8
|
-
static String UNKNOWN = "*/*";
|
|
9
|
-
static String BINARY_FILE = "application/octet-stream";
|
|
10
|
-
static String IMAGE = "image/*";
|
|
11
|
-
static String AUDIO = "audio/*";
|
|
12
|
-
static String VIDEO = "video/*";
|
|
13
|
-
static String TEXT = "text/*";
|
|
14
|
-
static String FONT = "font/*";
|
|
15
|
-
static String APPLICATION = "application/*";
|
|
16
|
-
static String CHEMICAL = "chemical/*";
|
|
17
|
-
static String MODEL = "model/*";
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* * Given `name` = `ABC` AND `mimeType` = `video/mp4`, then return `ABC.mp4`
|
|
21
|
-
* * Given `name` = `ABC` AND `mimeType` = `null`, then return `ABC`
|
|
22
|
-
* * Given `name` = `ABC.mp4` AND `mimeType` = `video/mp4`, then return `ABC.mp4`
|
|
23
|
-
*
|
|
24
|
-
* @param name can have file extension or not
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
public static String getFullFileName(String name, String mimeType) {
|
|
28
|
-
// Prior to API 29, MimeType.BINARY_FILE has no file extension
|
|
29
|
-
String ext = MimeType.getExtensionFromMimeType(mimeType);
|
|
30
|
-
if ((ext == null || ext.isEmpty()) || name.endsWith("." + ext)) return name;
|
|
31
|
-
else {
|
|
32
|
-
String fn = name + "." + ext;
|
|
33
|
-
if (fn.endsWith(".")) return StringUtils.stripEnd(fn, ".");
|
|
34
|
-
else return fn;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Some mime types return no file extension on older API levels. This function adds compatibility accross API levels.
|
|
40
|
-
*
|
|
41
|
-
* @see this.getExtensionFromMimeTypeOrFileName
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
public static String getExtensionFromMimeType(String mimeType) {
|
|
45
|
-
if (mimeType != null) {
|
|
46
|
-
if (mimeType.equals(BINARY_FILE)) return "bin";
|
|
47
|
-
else return MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
|
|
48
|
-
} else return "";
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @see this.getExtensionFromMimeType
|
|
53
|
-
*/
|
|
54
|
-
public static String getExtensionFromMimeTypeOrFileName(String mimeType, String filename) {
|
|
55
|
-
if (mimeType == null || mimeType.equals(UNKNOWN)) return StringUtils.substringAfterLast(filename, ".");
|
|
56
|
-
else return getExtensionFromMimeType(mimeType);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Some file types return no mime type on older API levels. This function adds compatibility across API levels.
|
|
61
|
-
*/
|
|
62
|
-
public static String getMimeTypeFromExtension(String fileExtension) {
|
|
63
|
-
if (fileExtension.equals("bin")) return BINARY_FILE;
|
|
64
|
-
else {
|
|
65
|
-
String mt = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
|
|
66
|
-
if (mt != null) return mt;
|
|
67
|
-
else return UNKNOWN;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
1
|
+
package com.ReactNativeBlobUtil.Utils;
|
|
2
|
+
|
|
3
|
+
import android.webkit.MimeTypeMap;
|
|
4
|
+
|
|
5
|
+
import org.apache.commons.lang3.StringUtils;
|
|
6
|
+
|
|
7
|
+
public class MimeType {
|
|
8
|
+
static String UNKNOWN = "*/*";
|
|
9
|
+
static String BINARY_FILE = "application/octet-stream";
|
|
10
|
+
static String IMAGE = "image/*";
|
|
11
|
+
static String AUDIO = "audio/*";
|
|
12
|
+
static String VIDEO = "video/*";
|
|
13
|
+
static String TEXT = "text/*";
|
|
14
|
+
static String FONT = "font/*";
|
|
15
|
+
static String APPLICATION = "application/*";
|
|
16
|
+
static String CHEMICAL = "chemical/*";
|
|
17
|
+
static String MODEL = "model/*";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* * Given `name` = `ABC` AND `mimeType` = `video/mp4`, then return `ABC.mp4`
|
|
21
|
+
* * Given `name` = `ABC` AND `mimeType` = `null`, then return `ABC`
|
|
22
|
+
* * Given `name` = `ABC.mp4` AND `mimeType` = `video/mp4`, then return `ABC.mp4`
|
|
23
|
+
*
|
|
24
|
+
* @param name can have file extension or not
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
public static String getFullFileName(String name, String mimeType) {
|
|
28
|
+
// Prior to API 29, MimeType.BINARY_FILE has no file extension
|
|
29
|
+
String ext = MimeType.getExtensionFromMimeType(mimeType);
|
|
30
|
+
if ((ext == null || ext.isEmpty()) || name.endsWith("." + ext)) return name;
|
|
31
|
+
else {
|
|
32
|
+
String fn = name + "." + ext;
|
|
33
|
+
if (fn.endsWith(".")) return StringUtils.stripEnd(fn, ".");
|
|
34
|
+
else return fn;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Some mime types return no file extension on older API levels. This function adds compatibility accross API levels.
|
|
40
|
+
*
|
|
41
|
+
* @see this.getExtensionFromMimeTypeOrFileName
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
public static String getExtensionFromMimeType(String mimeType) {
|
|
45
|
+
if (mimeType != null) {
|
|
46
|
+
if (mimeType.equals(BINARY_FILE)) return "bin";
|
|
47
|
+
else return MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
|
|
48
|
+
} else return "";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @see this.getExtensionFromMimeType
|
|
53
|
+
*/
|
|
54
|
+
public static String getExtensionFromMimeTypeOrFileName(String mimeType, String filename) {
|
|
55
|
+
if (mimeType == null || mimeType.equals(UNKNOWN)) return StringUtils.substringAfterLast(filename, ".");
|
|
56
|
+
else return getExtensionFromMimeType(mimeType);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Some file types return no mime type on older API levels. This function adds compatibility across API levels.
|
|
61
|
+
*/
|
|
62
|
+
public static String getMimeTypeFromExtension(String fileExtension) {
|
|
63
|
+
if (fileExtension.equals("bin")) return BINARY_FILE;
|
|
64
|
+
else {
|
|
65
|
+
String mt = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
|
|
66
|
+
if (mt != null) return mt;
|
|
67
|
+
else return UNKNOWN;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,223 +1,223 @@
|
|
|
1
|
-
package com.ReactNativeBlobUtil.Utils;
|
|
2
|
-
|
|
3
|
-
import android.annotation.TargetApi;
|
|
4
|
-
import android.content.Context;
|
|
5
|
-
import android.database.Cursor;
|
|
6
|
-
import android.net.Uri;
|
|
7
|
-
import android.os.Build;
|
|
8
|
-
import android.provider.DocumentsContract;
|
|
9
|
-
import android.provider.MediaStore;
|
|
10
|
-
import android.content.ContentUris;
|
|
11
|
-
import android.content.ContentResolver;
|
|
12
|
-
|
|
13
|
-
import com.ReactNativeBlobUtil.ReactNativeBlobUtilUtils;
|
|
14
|
-
|
|
15
|
-
import java.io.File;
|
|
16
|
-
import java.io.InputStream;
|
|
17
|
-
import java.io.FileOutputStream;
|
|
18
|
-
|
|
19
|
-
public class PathResolver {
|
|
20
|
-
@TargetApi(19)
|
|
21
|
-
public static String getRealPathFromURI(final Context context, final Uri uri) {
|
|
22
|
-
|
|
23
|
-
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
|
24
|
-
|
|
25
|
-
// DocumentProvider
|
|
26
|
-
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
|
27
|
-
// ExternalStorageProvider
|
|
28
|
-
if (isExternalStorageDocument(uri)) {
|
|
29
|
-
final String docId = DocumentsContract.getDocumentId(uri);
|
|
30
|
-
final String[] split = docId.split(":");
|
|
31
|
-
final String type = split[0];
|
|
32
|
-
|
|
33
|
-
if ("primary".equalsIgnoreCase(type)) {
|
|
34
|
-
File dir = context.getExternalFilesDir(null);
|
|
35
|
-
if (dir != null) return dir + "/" + split[1];
|
|
36
|
-
return "";
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// TODO handle non-primary volumes
|
|
40
|
-
}
|
|
41
|
-
// DownloadsProvider
|
|
42
|
-
else if (isDownloadsDocument(uri)) {
|
|
43
|
-
try {
|
|
44
|
-
final String id = DocumentsContract.getDocumentId(uri);
|
|
45
|
-
//Starting with Android O, this "id" is not necessarily a long (row number),
|
|
46
|
-
//but might also be a "raw:/some/file/path" URL
|
|
47
|
-
if (id != null && id.startsWith("raw:/")) {
|
|
48
|
-
Uri rawuri = Uri.parse(id);
|
|
49
|
-
String path = rawuri.getPath();
|
|
50
|
-
return path;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
Long docId = null;
|
|
54
|
-
//Since Android 10, uri can start with msf scheme like "msf:12345"
|
|
55
|
-
if (id != null && id.startsWith("msf:")) {
|
|
56
|
-
final String[] split = id.split(":");
|
|
57
|
-
docId = Long.valueOf(split[1]);
|
|
58
|
-
} else {
|
|
59
|
-
docId = Long.valueOf(id);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
final Uri contentUri = ContentUris.withAppendedId(
|
|
63
|
-
Uri.parse("content://downloads/public_downloads"), docId);
|
|
64
|
-
return getDataColumn(context, contentUri, null, null);
|
|
65
|
-
} catch (Exception ex) {
|
|
66
|
-
//something went wrong, but android should still be able to handle the original uri by returning null here (see readFile(...))
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
// MediaProvider
|
|
72
|
-
else if (isMediaDocument(uri)) {
|
|
73
|
-
final String docId = DocumentsContract.getDocumentId(uri);
|
|
74
|
-
final String[] split = docId.split(":");
|
|
75
|
-
final String type = split[0];
|
|
76
|
-
|
|
77
|
-
Uri contentUri = null;
|
|
78
|
-
if ("image".equals(type)) {
|
|
79
|
-
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
|
80
|
-
} else if ("video".equals(type)) {
|
|
81
|
-
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
|
82
|
-
} else if ("audio".equals(type)) {
|
|
83
|
-
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
final String selection = "_id=?";
|
|
87
|
-
final String[] selectionArgs = new String[]{
|
|
88
|
-
split[1]
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
return getDataColumn(context, contentUri, selection, selectionArgs);
|
|
92
|
-
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
|
93
|
-
|
|
94
|
-
// Return the remote address
|
|
95
|
-
if (isGooglePhotosUri(uri))
|
|
96
|
-
return uri.getLastPathSegment();
|
|
97
|
-
|
|
98
|
-
return getDataColumn(context, uri, null, null);
|
|
99
|
-
}
|
|
100
|
-
// Other Providers
|
|
101
|
-
else {
|
|
102
|
-
try {
|
|
103
|
-
InputStream attachment = context.getContentResolver().openInputStream(uri);
|
|
104
|
-
if (attachment != null) {
|
|
105
|
-
String filename = getContentName(context.getContentResolver(), uri);
|
|
106
|
-
if (filename != null) {
|
|
107
|
-
File file = new File(context.getCacheDir(), filename);
|
|
108
|
-
FileOutputStream tmp = new FileOutputStream(file);
|
|
109
|
-
byte[] buffer = new byte[1024];
|
|
110
|
-
while (attachment.read(buffer) > 0) {
|
|
111
|
-
tmp.write(buffer);
|
|
112
|
-
}
|
|
113
|
-
tmp.close();
|
|
114
|
-
attachment.close();
|
|
115
|
-
return file.getAbsolutePath();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
} catch (Exception e) {
|
|
119
|
-
ReactNativeBlobUtilUtils.emitWarningEvent(e.toString());
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// MediaStore (and general)
|
|
125
|
-
else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
|
126
|
-
|
|
127
|
-
// Return the remote address
|
|
128
|
-
if (isGooglePhotosUri(uri))
|
|
129
|
-
return uri.getLastPathSegment();
|
|
130
|
-
|
|
131
|
-
return getDataColumn(context, uri, null, null);
|
|
132
|
-
}
|
|
133
|
-
// File
|
|
134
|
-
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
|
135
|
-
return uri.getPath();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
private static String getContentName(ContentResolver resolver, Uri uri) {
|
|
142
|
-
Cursor cursor = resolver.query(uri, null, null, null, null);
|
|
143
|
-
cursor.moveToFirst();
|
|
144
|
-
int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
|
|
145
|
-
if (nameIndex >= 0) {
|
|
146
|
-
String name = cursor.getString(nameIndex);
|
|
147
|
-
cursor.close();
|
|
148
|
-
return name;
|
|
149
|
-
}
|
|
150
|
-
return null;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Get the value of the data column for this Uri. This is useful for
|
|
155
|
-
* MediaStore Uris, and other file-based ContentProviders.
|
|
156
|
-
*
|
|
157
|
-
* @param context The context.
|
|
158
|
-
* @param uri The Uri to query.
|
|
159
|
-
* @param selection (Optional) Filter used in the query.
|
|
160
|
-
* @param selectionArgs (Optional) Selection arguments used in the query.
|
|
161
|
-
* @return The value of the _data column, which is typically a file path.
|
|
162
|
-
*/
|
|
163
|
-
public static String getDataColumn(Context context, Uri uri, String selection,
|
|
164
|
-
String[] selectionArgs) {
|
|
165
|
-
|
|
166
|
-
Cursor cursor = null;
|
|
167
|
-
String result = null;
|
|
168
|
-
final String column = "_data";
|
|
169
|
-
final String[] projection = {
|
|
170
|
-
column
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
try {
|
|
174
|
-
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
|
175
|
-
null);
|
|
176
|
-
if (cursor != null && cursor.moveToFirst()) {
|
|
177
|
-
final int index = cursor.getColumnIndexOrThrow(column);
|
|
178
|
-
result = cursor.getString(index);
|
|
179
|
-
}
|
|
180
|
-
} catch (Exception ex) {
|
|
181
|
-
ex.printStackTrace();
|
|
182
|
-
return null;
|
|
183
|
-
} finally {
|
|
184
|
-
if (cursor != null)
|
|
185
|
-
cursor.close();
|
|
186
|
-
}
|
|
187
|
-
return result;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* @param uri The Uri to check.
|
|
193
|
-
* @return Whether the Uri authority is ExternalStorageProvider.
|
|
194
|
-
*/
|
|
195
|
-
public static boolean isExternalStorageDocument(Uri uri) {
|
|
196
|
-
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* @param uri The Uri to check.
|
|
201
|
-
* @return Whether the Uri authority is DownloadsProvider.
|
|
202
|
-
*/
|
|
203
|
-
public static boolean isDownloadsDocument(Uri uri) {
|
|
204
|
-
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* @param uri The Uri to check.
|
|
209
|
-
* @return Whether the Uri authority is MediaProvider.
|
|
210
|
-
*/
|
|
211
|
-
public static boolean isMediaDocument(Uri uri) {
|
|
212
|
-
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* @param uri The Uri to check.
|
|
217
|
-
* @return Whether the Uri authority is Google Photos.
|
|
218
|
-
*/
|
|
219
|
-
public static boolean isGooglePhotosUri(Uri uri) {
|
|
220
|
-
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
}
|
|
1
|
+
package com.ReactNativeBlobUtil.Utils;
|
|
2
|
+
|
|
3
|
+
import android.annotation.TargetApi;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.database.Cursor;
|
|
6
|
+
import android.net.Uri;
|
|
7
|
+
import android.os.Build;
|
|
8
|
+
import android.provider.DocumentsContract;
|
|
9
|
+
import android.provider.MediaStore;
|
|
10
|
+
import android.content.ContentUris;
|
|
11
|
+
import android.content.ContentResolver;
|
|
12
|
+
|
|
13
|
+
import com.ReactNativeBlobUtil.ReactNativeBlobUtilUtils;
|
|
14
|
+
|
|
15
|
+
import java.io.File;
|
|
16
|
+
import java.io.InputStream;
|
|
17
|
+
import java.io.FileOutputStream;
|
|
18
|
+
|
|
19
|
+
public class PathResolver {
|
|
20
|
+
@TargetApi(19)
|
|
21
|
+
public static String getRealPathFromURI(final Context context, final Uri uri) {
|
|
22
|
+
|
|
23
|
+
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
|
24
|
+
|
|
25
|
+
// DocumentProvider
|
|
26
|
+
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
|
27
|
+
// ExternalStorageProvider
|
|
28
|
+
if (isExternalStorageDocument(uri)) {
|
|
29
|
+
final String docId = DocumentsContract.getDocumentId(uri);
|
|
30
|
+
final String[] split = docId.split(":");
|
|
31
|
+
final String type = split[0];
|
|
32
|
+
|
|
33
|
+
if ("primary".equalsIgnoreCase(type)) {
|
|
34
|
+
File dir = context.getExternalFilesDir(null);
|
|
35
|
+
if (dir != null) return dir + "/" + split[1];
|
|
36
|
+
return "";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// TODO handle non-primary volumes
|
|
40
|
+
}
|
|
41
|
+
// DownloadsProvider
|
|
42
|
+
else if (isDownloadsDocument(uri)) {
|
|
43
|
+
try {
|
|
44
|
+
final String id = DocumentsContract.getDocumentId(uri);
|
|
45
|
+
//Starting with Android O, this "id" is not necessarily a long (row number),
|
|
46
|
+
//but might also be a "raw:/some/file/path" URL
|
|
47
|
+
if (id != null && id.startsWith("raw:/")) {
|
|
48
|
+
Uri rawuri = Uri.parse(id);
|
|
49
|
+
String path = rawuri.getPath();
|
|
50
|
+
return path;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Long docId = null;
|
|
54
|
+
//Since Android 10, uri can start with msf scheme like "msf:12345"
|
|
55
|
+
if (id != null && id.startsWith("msf:")) {
|
|
56
|
+
final String[] split = id.split(":");
|
|
57
|
+
docId = Long.valueOf(split[1]);
|
|
58
|
+
} else {
|
|
59
|
+
docId = Long.valueOf(id);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
final Uri contentUri = ContentUris.withAppendedId(
|
|
63
|
+
Uri.parse("content://downloads/public_downloads"), docId);
|
|
64
|
+
return getDataColumn(context, contentUri, null, null);
|
|
65
|
+
} catch (Exception ex) {
|
|
66
|
+
//something went wrong, but android should still be able to handle the original uri by returning null here (see readFile(...))
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
// MediaProvider
|
|
72
|
+
else if (isMediaDocument(uri)) {
|
|
73
|
+
final String docId = DocumentsContract.getDocumentId(uri);
|
|
74
|
+
final String[] split = docId.split(":");
|
|
75
|
+
final String type = split[0];
|
|
76
|
+
|
|
77
|
+
Uri contentUri = null;
|
|
78
|
+
if ("image".equals(type)) {
|
|
79
|
+
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
|
80
|
+
} else if ("video".equals(type)) {
|
|
81
|
+
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
|
82
|
+
} else if ("audio".equals(type)) {
|
|
83
|
+
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
final String selection = "_id=?";
|
|
87
|
+
final String[] selectionArgs = new String[]{
|
|
88
|
+
split[1]
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return getDataColumn(context, contentUri, selection, selectionArgs);
|
|
92
|
+
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
|
93
|
+
|
|
94
|
+
// Return the remote address
|
|
95
|
+
if (isGooglePhotosUri(uri))
|
|
96
|
+
return uri.getLastPathSegment();
|
|
97
|
+
|
|
98
|
+
return getDataColumn(context, uri, null, null);
|
|
99
|
+
}
|
|
100
|
+
// Other Providers
|
|
101
|
+
else {
|
|
102
|
+
try {
|
|
103
|
+
InputStream attachment = context.getContentResolver().openInputStream(uri);
|
|
104
|
+
if (attachment != null) {
|
|
105
|
+
String filename = getContentName(context.getContentResolver(), uri);
|
|
106
|
+
if (filename != null) {
|
|
107
|
+
File file = new File(context.getCacheDir(), filename);
|
|
108
|
+
FileOutputStream tmp = new FileOutputStream(file);
|
|
109
|
+
byte[] buffer = new byte[1024];
|
|
110
|
+
while (attachment.read(buffer) > 0) {
|
|
111
|
+
tmp.write(buffer);
|
|
112
|
+
}
|
|
113
|
+
tmp.close();
|
|
114
|
+
attachment.close();
|
|
115
|
+
return file.getAbsolutePath();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch (Exception e) {
|
|
119
|
+
ReactNativeBlobUtilUtils.emitWarningEvent(e.toString());
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// MediaStore (and general)
|
|
125
|
+
else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
|
126
|
+
|
|
127
|
+
// Return the remote address
|
|
128
|
+
if (isGooglePhotosUri(uri))
|
|
129
|
+
return uri.getLastPathSegment();
|
|
130
|
+
|
|
131
|
+
return getDataColumn(context, uri, null, null);
|
|
132
|
+
}
|
|
133
|
+
// File
|
|
134
|
+
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
|
135
|
+
return uri.getPath();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private static String getContentName(ContentResolver resolver, Uri uri) {
|
|
142
|
+
Cursor cursor = resolver.query(uri, null, null, null, null);
|
|
143
|
+
cursor.moveToFirst();
|
|
144
|
+
int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
|
|
145
|
+
if (nameIndex >= 0) {
|
|
146
|
+
String name = cursor.getString(nameIndex);
|
|
147
|
+
cursor.close();
|
|
148
|
+
return name;
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get the value of the data column for this Uri. This is useful for
|
|
155
|
+
* MediaStore Uris, and other file-based ContentProviders.
|
|
156
|
+
*
|
|
157
|
+
* @param context The context.
|
|
158
|
+
* @param uri The Uri to query.
|
|
159
|
+
* @param selection (Optional) Filter used in the query.
|
|
160
|
+
* @param selectionArgs (Optional) Selection arguments used in the query.
|
|
161
|
+
* @return The value of the _data column, which is typically a file path.
|
|
162
|
+
*/
|
|
163
|
+
public static String getDataColumn(Context context, Uri uri, String selection,
|
|
164
|
+
String[] selectionArgs) {
|
|
165
|
+
|
|
166
|
+
Cursor cursor = null;
|
|
167
|
+
String result = null;
|
|
168
|
+
final String column = "_data";
|
|
169
|
+
final String[] projection = {
|
|
170
|
+
column
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
|
175
|
+
null);
|
|
176
|
+
if (cursor != null && cursor.moveToFirst()) {
|
|
177
|
+
final int index = cursor.getColumnIndexOrThrow(column);
|
|
178
|
+
result = cursor.getString(index);
|
|
179
|
+
}
|
|
180
|
+
} catch (Exception ex) {
|
|
181
|
+
ex.printStackTrace();
|
|
182
|
+
return null;
|
|
183
|
+
} finally {
|
|
184
|
+
if (cursor != null)
|
|
185
|
+
cursor.close();
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @param uri The Uri to check.
|
|
193
|
+
* @return Whether the Uri authority is ExternalStorageProvider.
|
|
194
|
+
*/
|
|
195
|
+
public static boolean isExternalStorageDocument(Uri uri) {
|
|
196
|
+
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @param uri The Uri to check.
|
|
201
|
+
* @return Whether the Uri authority is DownloadsProvider.
|
|
202
|
+
*/
|
|
203
|
+
public static boolean isDownloadsDocument(Uri uri) {
|
|
204
|
+
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @param uri The Uri to check.
|
|
209
|
+
* @return Whether the Uri authority is MediaProvider.
|
|
210
|
+
*/
|
|
211
|
+
public static boolean isMediaDocument(Uri uri) {
|
|
212
|
+
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @param uri The Uri to check.
|
|
217
|
+
* @return Whether the Uri authority is Google Photos.
|
|
218
|
+
*/
|
|
219
|
+
public static boolean isGooglePhotosUri(Uri uri) {
|
|
220
|
+
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
}
|