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