diff options
author | Sam Judd <judds@google.com> | 2014-06-23 12:39:19 -0700 |
---|---|---|
committer | Sam Judd <judds@google.com> | 2014-06-23 17:17:27 -0700 |
commit | eba30dc89f6138cf85e1adf0fd1d23a87849c9e6 (patch) | |
tree | 056d9272c8c0fc56375c7c6fa647eb281eb62c5b /library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java | |
parent | 669b218b9c2b3fe75607df5947e2d75a91c8d12f (diff) | |
download | glide-eba30dc89f6138cf85e1adf0fd1d23a87849c9e6.tar.gz |
Add support for media store thumbnails.
Diffstat (limited to 'library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java')
-rw-r--r-- | library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java b/library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java new file mode 100644 index 00000000..888f46a9 --- /dev/null +++ b/library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java @@ -0,0 +1,181 @@ +package com.bumptech.glide.load.data; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.provider.MediaStore; +import android.text.TextUtils; +import com.bumptech.glide.Priority; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +public class MediaStoreThumbFetcher implements DataFetcher<InputStream> { + private static final int MINI_WIDTH = 512; + private static final int MINI_HEIGHT = 384; + private static final ThumbnailStreamOpenerFactory DEFAULT_FACTORY = new ThumbnailStreamOpenerFactory(); + + private final Context context; + private final Uri mediaStoreUri; + private final DataFetcher<InputStream> defaultFetcher; + private final int width; + private final int height; + private final ThumbnailStreamOpenerFactory factory; + private InputStream inputStream; + + public MediaStoreThumbFetcher(Context context, Uri mediaStoreUri, DataFetcher<InputStream> defaultFetcher, + int width, int height) { + this(context, mediaStoreUri, defaultFetcher, width, height, DEFAULT_FACTORY); + } + + MediaStoreThumbFetcher(Context context, Uri mediaStoreUri, DataFetcher<InputStream> defaultFetcher, int width, + int height, ThumbnailStreamOpenerFactory factory) { + this.context = context; + this.mediaStoreUri = mediaStoreUri; + this.defaultFetcher = defaultFetcher; + this.width = width; + this.height = height; + this.factory = factory; + } + + @Override + public InputStream loadData(Priority priority) throws Exception { + ThumbnailStreamOpener fetcher = factory.build(mediaStoreUri, width, height); + + if (fetcher != null) { + inputStream = fetcher.open(context, mediaStoreUri); + } + + if (inputStream != null) { + return inputStream; + } else { + return defaultFetcher.loadData(priority); + } + } + + @Override + public void cleanup() { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + // Do nothing. + } + } + defaultFetcher.cleanup(); + } + + @Override + public void cancel() { + // Do nothing. + } + + private static boolean isMediaStoreUri(Uri uri) { + return uri != null + && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) + && MediaStore.AUTHORITY.equals(uri.getAuthority()); + } + + private static boolean isMediaStoreVideo(Uri uri) { + return isMediaStoreUri(uri) && uri.getPathSegments().contains("video"); + } + + static class FileService { + public boolean exists(File file) { + return file.exists(); + } + + public long length(File file) { + return file.length(); + } + + public File get(String path) { + return new File(path); + } + } + + interface ThumbnailQuery { + public Cursor query(Context context, Uri uri); + } + + static class ThumbnailStreamOpener { + private static final FileService DEFAULT_SERVICE = new FileService(); + private final FileService service; + private ThumbnailQuery query; + + public ThumbnailStreamOpener(ThumbnailQuery query) { + this(DEFAULT_SERVICE, query); + } + + public ThumbnailStreamOpener(FileService service, ThumbnailQuery query) { + this.service = service; + this.query = query; + } + + public InputStream open(Context context, Uri uri) throws FileNotFoundException { + Uri thumbnailUri = null; + InputStream inputStream = null; + + final Cursor cursor = query.query(context, uri); + try { + if (cursor != null && cursor.moveToFirst()) { + String path = cursor.getString(0); + if (!TextUtils.isEmpty(path)) { + File file = service.get(path); + if (service.exists(file) && service.length(file) > 0) { + thumbnailUri = Uri.fromFile(file); + } + } + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + if (thumbnailUri != null) { + inputStream = context.getContentResolver().openInputStream(thumbnailUri); + } + return inputStream; + } + } + + static class ImageThumbnailQuery implements ThumbnailQuery { + + @Override + public Cursor query(Context context, Uri uri) { + String id = uri.getLastPathSegment(); + return context.getContentResolver().query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, new String[] { + MediaStore.Images.Thumbnails.DATA + }, MediaStore.Images.Thumbnails.IMAGE_ID + " = ? AND " + MediaStore.Images.Thumbnails.KIND + " = ?", + new String[] { id, String.valueOf(MediaStore.Images.Thumbnails.MINI_KIND) }, null); + } + } + + static class VideoThumbnailQuery implements ThumbnailQuery { + + @Override + public Cursor query(Context context, Uri uri) { + String id = uri.getLastPathSegment(); + return context.getContentResolver().query(MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, new String[] { + MediaStore.Video.Thumbnails.DATA + }, MediaStore.Video.Thumbnails.VIDEO_ID + " = ? AND " + MediaStore.Video.Thumbnails.KIND + " = ?", + new String[] { id, String.valueOf(MediaStore.Video.Thumbnails.MINI_KIND) }, null); + } + } + + static class ThumbnailStreamOpenerFactory { + + public ThumbnailStreamOpener build(Uri uri, int width, int height) { + if (!isMediaStoreUri(uri) || width > MINI_WIDTH || height > MINI_HEIGHT) { + return null; + } else if (isMediaStoreVideo(uri)) { + return new ThumbnailStreamOpener(new VideoThumbnailQuery()); + } else { + return new ThumbnailStreamOpener(new ImageThumbnailQuery()); + } + } + } +} |