diff --git a/src/org/kreed/vanilla/CoverBitmap.java b/src/org/kreed/vanilla/CoverBitmap.java index e698dc1b..52332de0 100644 --- a/src/org/kreed/vanilla/CoverBitmap.java +++ b/src/org/kreed/vanilla/CoverBitmap.java @@ -22,6 +22,7 @@ package org.kreed.vanilla; +import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; @@ -30,8 +31,12 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; +import android.net.Uri; +import android.os.ParcelFileDescriptor; import android.util.DisplayMetrics; +import android.util.Log; import android.util.TypedValue; +import java.io.FileDescriptor; /** * Class containing utility functions to create Bitmaps display song info and @@ -145,9 +150,9 @@ public final class CoverBitmap { case STYLE_INFO_BELOW: return createSeparatedBitmap(context, song, width, height, bitmap); case STYLE_NO_INFO: - return createScaledBitmap(song.getCover(context), width, height, bitmap); + return createScaledBitmap(getCover(context, song), width, height, bitmap); case STYLE_NO_INFO_ZOOMED: - return createZoomedBitmap(song.getCover(context), width, height, bitmap); + return createZoomedBitmap(getCover(context, song), width, height, bitmap); default: throw new IllegalArgumentException("Invalid bitmap type given: " + style); } @@ -167,7 +172,7 @@ public final class CoverBitmap { String title = song.title == null ? "" : song.title; String album = song.album == null ? "" : song.album; String artist = song.artist == null ? "" : song.artist; - Bitmap cover = song.getCover(context); + Bitmap cover = getCover(context, song); int titleSize = TEXT_SIZE_BIG; int subSize = TEXT_SIZE; @@ -219,6 +224,7 @@ public final class CoverBitmap { int y = (bitmapHeight - coverHeight) / 2; Rect rect = new Rect(x, y, x + coverWidth, y + coverHeight); canvas.drawBitmap(cover, null, rect, paint); + cover.recycle(); } int left = (bitmapWidth - boxWidth) / 2; @@ -265,7 +271,7 @@ public final class CoverBitmap { String title = song.title == null ? "" : song.title; String album = song.album == null ? "" : song.album; String artist = song.artist == null ? "" : song.artist; - Bitmap cover = song.getCover(context); + Bitmap cover = getCover(context, song); int textSize = TEXT_SIZE; int padding = PADDING; @@ -319,6 +325,7 @@ public final class CoverBitmap { int y = horizontal ? (bitmapHeight - coverHeight) / 2 : 0; Rect rect = new Rect(x, y, x + coverWidth, y + coverHeight); canvas.drawBitmap(cover, null, rect, paint); + cover.recycle(); } int top; @@ -354,7 +361,7 @@ public final class CoverBitmap { * ratio is preserved, thus, parts of the image will be cut off if the * aspect ratio of the rectangle does not match that of the source bitmap. * - * @param source The source bitmap. + * @param source The source bitmap. Will be recycled. * @param width Width of the result * @param height Height of the result * @param reuse A bitmap to store the result in if possible @@ -390,6 +397,7 @@ public final class CoverBitmap { Rect src = new Rect(xOffset, yOffset, sourceWidth - xOffset, sourceHeight - yOffset); Rect dest = new Rect(0, 0, width, height); canvas.drawBitmap(source, src, dest, null); + source.recycle(); return bitmap; } @@ -399,7 +407,7 @@ public final class CoverBitmap { * preserved. At least one dimension of the result will match the provided * dimension exactly. * - * @param source The source bitmap. + * @param source The source bitmap. Will be recycled. * @param width Maximum width of image * @param height Maximum height of image * @param reuse A bitmap that will simply be recycled. (This method does not @@ -419,6 +427,47 @@ public final class CoverBitmap { float scale = Math.min((float)width / sourceWidth, (float)height / sourceHeight); sourceWidth *= scale; sourceHeight *= scale; - return Bitmap.createScaledBitmap(source, sourceWidth, sourceHeight, false); + Bitmap result = Bitmap.createScaledBitmap(source, sourceWidth, sourceHeight, false); + source.recycle(); + return result; + } + + + private static final BitmapFactory.Options BITMAP_OPTIONS = new BitmapFactory.Options(); + + static { + BITMAP_OPTIONS.inPreferredConfig = Bitmap.Config.RGB_565; + BITMAP_OPTIONS.inDither = false; + } + + /** + * Query the album art the given song. + * + * @param context A context to use. + * @param song The song to query the cover art for. + * @return The album art or null if no album art could be found + */ + public static Bitmap getCover(Context context, Song song) + { + if (song == null || song.id == -1 || Song.mDisableCoverArt) + return null; + + Uri uri = song.getCoverUri(); + if (uri == null) + return null; + + ContentResolver res = context.getContentResolver(); + + try { + ParcelFileDescriptor parcelFileDescriptor = res.openFileDescriptor(uri, "r"); + if (parcelFileDescriptor != null) { + FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); + return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, BITMAP_OPTIONS); + } + } catch (Exception e) { + Log.d("VanillaMusic", "Failed to load cover art for " + song.path, e); + } + + return null; } } diff --git a/src/org/kreed/vanilla/LibraryActivity.java b/src/org/kreed/vanilla/LibraryActivity.java index 18bbfda1..00f5734a 100644 --- a/src/org/kreed/vanilla/LibraryActivity.java +++ b/src/org/kreed/vanilla/LibraryActivity.java @@ -28,7 +28,6 @@ import android.content.res.Resources; import android.content.SharedPreferences; import android.database.ContentObserver; import android.database.Cursor; -import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.PaintDrawable; import android.net.Uri; @@ -798,7 +797,7 @@ public class LibraryActivity extends PlaybackActivity implements AdapterView.OnI super.onSongChange(song); if (mStatusText != null) { - Bitmap cover = null; + Uri cover = null; if (song == null) { mStatusText.setText(R.string.none); @@ -807,7 +806,7 @@ public class LibraryActivity extends PlaybackActivity implements AdapterView.OnI String title = song.title == null ? res.getString(R.string.unknown) : song.title; String artist = song.artist == null ? res.getString(R.string.unknown) : song.artist; mStatusText.setText(res.getString(R.string.title_by_artist, title, artist)); - cover = song.getCover(this); + cover = song.getCoverUri(); } if (Song.mDisableCoverArt) @@ -815,7 +814,7 @@ public class LibraryActivity extends PlaybackActivity implements AdapterView.OnI else if (cover == null) mCover.setImageResource(R.drawable.albumart_mp_unknown_list); else - mCover.setImageBitmap(cover); + mCover.setImageURI(cover); } } diff --git a/src/org/kreed/vanilla/Song.java b/src/org/kreed/vanilla/Song.java index f6a84cee..b5983ac8 100644 --- a/src/org/kreed/vanilla/Song.java +++ b/src/org/kreed/vanilla/Song.java @@ -22,16 +22,9 @@ package org.kreed.vanilla; -import android.content.ContentResolver; -import android.content.Context; import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.net.Uri; -import android.os.ParcelFileDescriptor; import android.provider.MediaStore; -import android.util.Log; -import java.io.FileDescriptor; /** * Represents a Song backed by the MediaStore. Includes basic metadata and @@ -79,11 +72,6 @@ public class Song implements Comparable { MediaStore.Audio.Media.TRACK, }; - /** - * A cache of covers that have been loaded with getCover(). - */ - private static final Cache mCoverCache = new Cache(10); - /** * If true, will not attempt to load any cover art in getCover() */ @@ -192,48 +180,6 @@ public class Song implements Comparable { return song.id; } - private static final BitmapFactory.Options BITMAP_OPTIONS = new BitmapFactory.Options(); - - static { - BITMAP_OPTIONS.inPreferredConfig = Bitmap.Config.RGB_565; - BITMAP_OPTIONS.inDither = false; - } - - /** - * Query the album art for this song. - * - * @param context A context to use. - * @return The album art or null if no album art could be found - */ - public Bitmap getCover(Context context) - { - if (id == -1 || mDisableCoverArt) - return null; - - // Query the cache for the cover - Bitmap cover = mCoverCache.get(id); - if (cover != null) - return cover; - - ContentResolver res = context.getContentResolver(); - - try { - ParcelFileDescriptor parcelFileDescriptor = res.openFileDescriptor(getCoverUri(), "r"); - if (parcelFileDescriptor != null) { - FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); - cover = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, BITMAP_OPTIONS); - } - } catch (Exception e) { - Log.d("VanillaMusic", "Failed to load cover art for " + path, e); - } - - Bitmap deletedCover = mCoverCache.put(id, cover); - if (deletedCover != null) - deletedCover.recycle(); - - return cover; - } - /** * Return a URI describing where the cover art is stored, or null if this * song has not been populated.