From 9d5ea5a894b5b2ee4f99d9f3a775cbf777015616 Mon Sep 17 00:00:00 2001 From: hjow Date: Mon, 25 May 2015 18:37:54 +0100 Subject: [PATCH] Kitkat document fix --- .../com/soundcloud/android/crop/CropUtil.java | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/lib/src/main/java/com/soundcloud/android/crop/CropUtil.java b/lib/src/main/java/com/soundcloud/android/crop/CropUtil.java index 04e83224..6e3f4cc4 100644 --- a/lib/src/main/java/com/soundcloud/android/crop/CropUtil.java +++ b/lib/src/main/java/com/soundcloud/android/crop/CropUtil.java @@ -16,14 +16,19 @@ package com.soundcloud.android.crop; +import android.annotation.TargetApi; import android.app.ProgressDialog; import android.content.ContentResolver; +import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.media.ExifInterface; import android.net.Uri; +import android.os.Build; +import android.os.Environment; import android.os.Handler; import android.os.ParcelFileDescriptor; +import android.provider.DocumentsContract; import android.provider.MediaStore; import android.support.annotation.Nullable; import android.text.TextUtils; @@ -89,10 +94,13 @@ public static boolean copyExifRotation(File sourceFile, File destFile) { @Nullable public static File getFromMediaUri(Context context, ContentResolver resolver, Uri uri) { + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; if (uri == null) return null; if (SCHEME_FILE.equals(uri.getScheme())) { return new File(uri.getPath()); + } else if (isKitKat) { + return getFromKitKatMediaUri(context,resolver,uri); } else if (SCHEME_CONTENT.equals(uri.getScheme())) { final String[] filePathColumn = { MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME }; Cursor cursor = null; @@ -122,6 +130,135 @@ public static File getFromMediaUri(Context context, ContentResolver resolver, Ur return null; } + @TargetApi(19) + public static File getFromKitKatMediaUri(Context context, ContentResolver resolver, Uri uri) { + if (DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return new File(Environment.getExternalStorageDirectory() + "/" + split[1]); + } + + // TODO handle non-primary volumes + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + return new File(getDataColumn(context, contentUri, null, null)); + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{ + split[1] + }; + + return new File(getDataColumn(context, contentUri, selection, selectionArgs)); + } else if (SCHEME_CONTENT.equals(uri.getScheme())) { + final String[] filePathColumn = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME}; + Cursor cursor = null; + try { + cursor = resolver.query(uri, filePathColumn, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + final int columnIndex = (uri.toString().startsWith("content://com.google.android.gallery3d")) ? + cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME) : + cursor.getColumnIndex(MediaStore.MediaColumns.DATA); + // Picasa images on API 13+ + if (columnIndex != -1) { + String filePath = cursor.getString(columnIndex); + if (!TextUtils.isEmpty(filePath)) { + return new File(filePath); + } + } + } + } catch (IllegalArgumentException e) { + // Google Drive images + return getFromMediaUriPfd(context, resolver, uri); + } catch (SecurityException ignored) { + // Nothing we can do + } finally { + if (cursor != null) cursor.close(); + } + } + } + return null ; + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + public static String getDataColumn(Context context, Uri uri, String selection, + String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { + column + }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + final int index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(index); + } + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + private static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + private static String getTempFilename(Context context) throws IOException { File outputDir = context.getCacheDir(); File outputFile = File.createTempFile("image", "tmp", outputDir);