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