diff --git a/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/LocalContentUriFetchProducer.java b/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/LocalContentUriFetchProducer.java index 4a11d1cbf3..8090f5cc67 100644 --- a/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/LocalContentUriFetchProducer.java +++ b/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/LocalContentUriFetchProducer.java @@ -9,18 +9,24 @@ package com.facebook.imagepipeline.producers; -import java.io.IOException; -import java.io.InputStream; -import java.util.concurrent.Executor; - import android.content.ContentResolver; +import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; +import android.provider.MediaStore; import com.facebook.common.internal.VisibleForTesting; import com.facebook.imagepipeline.memory.PooledByteBufferFactory; import com.facebook.imagepipeline.request.ImageRequest; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.Executor; + +import javax.annotation.Nullable; + /** * Represents a local content Uri fetch producer. */ @@ -28,6 +34,7 @@ public class LocalContentUriFetchProducer extends LocalFetchProducer { @VisibleForTesting static final String PRODUCER_NAME = "LocalContentUriFetchProducer"; private static final String DISPLAY_PHOTO_PATH = Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "display_photo").getPath(); + private static final String[] PROJECTION = new String[] { MediaStore.Images.ImageColumns.DATA }; private final ContentResolver mContentResolver; @@ -46,6 +53,14 @@ protected InputStream getInputStream(ImageRequest imageRequest) throws IOExcepti // If a Contact URI is provided, use the special helper to open that contact's photo. return ContactsContract.Contacts.openContactPhotoInputStream(mContentResolver, uri); } + + if (isCameraUri(uri)) { + String pathname = getCameraPath(uri); + if (pathname != null) { + return new FileInputStream(pathname); + } + } + return mContentResolver.openInputStream(uri); } @@ -54,14 +69,39 @@ protected InputStream getInputStream(ImageRequest imageRequest) throws IOExcepti * @param uri the URI to check * @return true if the uri is a a Contact URI, and is not already specifying a display photo. */ - private boolean isContactUri(Uri uri) { + private static boolean isContactUri(Uri uri) { return ContactsContract.AUTHORITY.equals(uri.getAuthority()) && !uri.getPath().startsWith(DISPLAY_PHOTO_PATH); } + private static boolean isCameraUri(Uri uri) { + String uriString = uri.toString(); + return uriString.startsWith(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString()) || + uriString.startsWith(MediaStore.Images.Media.INTERNAL_CONTENT_URI.toString()); + } + + private @Nullable String getCameraPath(Uri uri) { + Cursor cursor = mContentResolver.query(uri, PROJECTION, null, null, null); + if (cursor == null) { + return null; + } + try { + cursor.moveToFirst(); + return cursor.getString(0); + } finally { + cursor.close(); + } + } + @Override protected int getLength(ImageRequest imageRequest) { - return -1; + Uri uri = imageRequest.getSourceUri(); + if (isCameraUri(uri)) { + String pathname = getCameraPath(uri); + return pathname == null ? -1 : (int) new File(pathname).length(); + } else { + return -1; + } } @Override