Parcourir la source

Change Android fs normalize path function

Use a more sophisticated implementation as @timsuchanek mentioned in
#90
Ben Hsieh il y a 8 ans
Parent
révision
a74e071b5b

+ 12
- 16
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java Voir le fichier

@@ -13,6 +13,7 @@ import android.os.Looper;
13 13
 import android.provider.MediaStore;
14 14
 import android.util.Base64;
15 15
 
16
+import com.RNFetchBlob.Utils.PathResolver;
16 17
 import com.facebook.react.bridge.Arguments;
17 18
 import com.facebook.react.bridge.Callback;
18 19
 import com.facebook.react.bridge.Promise;
@@ -852,28 +853,23 @@ public class RNFetchBlobFS {
852 853
     }
853 854
 
854 855
     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;
856 859
     }
857 860
 
858 861
     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) {
860 866
             return path;
861 867
         }
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;
875 870
         }
876
-        return path;
871
+        else
872
+            return PathResolver.getRealPathFromURI(RNFetchBlob.RCTContext, uri);
877 873
     }
878 874
 
879 875
 }

+ 146
- 0
src/android/src/main/java/com/RNFetchBlob/Utils/PathResolver.java Voir le fichier

@@ -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
+}