Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit a74e071

Browse files
committed
Change Android fs normalize path function
Use a more sophisticated implementation as @timsuchanek mentioned in #90
1 parent 35973e2 commit a74e071

File tree

2 files changed

+158
-16
lines changed

2 files changed

+158
-16
lines changed

src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import android.provider.MediaStore;
1414
import android.util.Base64;
1515

16+
import com.RNFetchBlob.Utils.PathResolver;
1617
import com.facebook.react.bridge.Arguments;
1718
import com.facebook.react.bridge.Callback;
1819
import com.facebook.react.bridge.Promise;
@@ -852,28 +853,23 @@ static boolean isPathExists(String path) {
852853
}
853854

854855
public static boolean isAsset(String path) {
855-
return path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET);
856+
if(path != null)
857+
return path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET);
858+
return false;
856859
}
857860

858861
public static String normalizePath(String path) {
859-
if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
862+
if(path == null)
863+
return null;
864+
Uri uri = Uri.parse(path);
865+
if(uri.getScheme() == null) {
860866
return path;
861867
}
862-
else if (path.startsWith(RNFetchBlobConst.FILE_PREFIX_CONTENT)) {
863-
String filePath = null;
864-
Uri uri = Uri.parse(path);
865-
if (uri != null && "content".equals(uri.getScheme())) {
866-
ContentResolver resolver = RNFetchBlob.RCTContext.getContentResolver();
867-
Cursor cursor = resolver.query(uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null);
868-
cursor.moveToFirst();
869-
filePath = cursor.getString(0);
870-
cursor.close();
871-
} else {
872-
filePath = uri.getPath();
873-
}
874-
return filePath;
868+
if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
869+
return path;
875870
}
876-
return path;
871+
else
872+
return PathResolver.getRealPathFromURI(RNFetchBlob.RCTContext, uri);
877873
}
878874

879875
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package com.RNFetchBlob.Utils;
2+
3+
import android.content.Context;
4+
import android.database.Cursor;
5+
import android.net.Uri;
6+
import android.os.Build;
7+
import android.provider.DocumentsContract;
8+
import android.provider.MediaStore;
9+
import android.content.ContentUris;
10+
import android.os.Environment;
11+
12+
public class PathResolver {
13+
public static String getRealPathFromURI(final Context context, final Uri uri) {
14+
15+
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
16+
17+
// DocumentProvider
18+
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
19+
// ExternalStorageProvider
20+
if (isExternalStorageDocument(uri)) {
21+
final String docId = DocumentsContract.getDocumentId(uri);
22+
final String[] split = docId.split(":");
23+
final String type = split[0];
24+
25+
if ("primary".equalsIgnoreCase(type)) {
26+
return Environment.getExternalStorageDirectory() + "/" + split[1];
27+
}
28+
29+
// TODO handle non-primary volumes
30+
}
31+
// DownloadsProvider
32+
else if (isDownloadsDocument(uri)) {
33+
34+
final String id = DocumentsContract.getDocumentId(uri);
35+
final Uri contentUri = ContentUris.withAppendedId(
36+
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
37+
38+
return getDataColumn(context, contentUri, null, null);
39+
}
40+
// MediaProvider
41+
else if (isMediaDocument(uri)) {
42+
final String docId = DocumentsContract.getDocumentId(uri);
43+
final String[] split = docId.split(":");
44+
final String type = split[0];
45+
46+
Uri contentUri = null;
47+
if ("image".equals(type)) {
48+
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
49+
} else if ("video".equals(type)) {
50+
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
51+
} else if ("audio".equals(type)) {
52+
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
53+
}
54+
55+
final String selection = "_id=?";
56+
final String[] selectionArgs = new String[] {
57+
split[1]
58+
};
59+
60+
return getDataColumn(context, contentUri, selection, selectionArgs);
61+
}
62+
}
63+
// MediaStore (and general)
64+
else if ("content".equalsIgnoreCase(uri.getScheme())) {
65+
66+
// Return the remote address
67+
if (isGooglePhotosUri(uri))
68+
return uri.getLastPathSegment();
69+
70+
return getDataColumn(context, uri, null, null);
71+
}
72+
// File
73+
else if ("file".equalsIgnoreCase(uri.getScheme())) {
74+
return uri.getPath();
75+
}
76+
77+
return null;
78+
}
79+
80+
/**
81+
* Get the value of the data column for this Uri. This is useful for
82+
* MediaStore Uris, and other file-based ContentProviders.
83+
*
84+
* @param context The context.
85+
* @param uri The Uri to query.
86+
* @param selection (Optional) Filter used in the query.
87+
* @param selectionArgs (Optional) Selection arguments used in the query.
88+
* @return The value of the _data column, which is typically a file path.
89+
*/
90+
public static String getDataColumn(Context context, Uri uri, String selection,
91+
String[] selectionArgs) {
92+
93+
Cursor cursor = null;
94+
final String column = "_data";
95+
final String[] projection = {
96+
column
97+
};
98+
99+
try {
100+
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
101+
null);
102+
if (cursor != null && cursor.moveToFirst()) {
103+
final int index = cursor.getColumnIndexOrThrow(column);
104+
return cursor.getString(index);
105+
}
106+
} finally {
107+
if (cursor != null)
108+
cursor.close();
109+
}
110+
return null;
111+
}
112+
113+
114+
/**
115+
* @param uri The Uri to check.
116+
* @return Whether the Uri authority is ExternalStorageProvider.
117+
*/
118+
public static boolean isExternalStorageDocument(Uri uri) {
119+
return "com.android.externalstorage.documents".equals(uri.getAuthority());
120+
}
121+
122+
/**
123+
* @param uri The Uri to check.
124+
* @return Whether the Uri authority is DownloadsProvider.
125+
*/
126+
public static boolean isDownloadsDocument(Uri uri) {
127+
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
128+
}
129+
130+
/**
131+
* @param uri The Uri to check.
132+
* @return Whether the Uri authority is MediaProvider.
133+
*/
134+
public static boolean isMediaDocument(Uri uri) {
135+
return "com.android.providers.media.documents".equals(uri.getAuthority());
136+
}
137+
138+
/**
139+
* @param uri The Uri to check.
140+
* @return Whether the Uri authority is Google Photos.
141+
*/
142+
public static boolean isGooglePhotosUri(Uri uri) {
143+
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
144+
}
145+
146+
}

0 commit comments

Comments
 (0)