OSDN Git Service

Apollo: Make albums with the same name to use respective album-art/date/etc.
authorPrzemyslaw Kryger <pkryger@gmail.com>
Sun, 28 Jul 2013 11:03:16 +0000 (13:03 +0200)
committerDanny Baumann <dannybaumann@web.de>
Tue, 30 Jul 2013 07:41:37 +0000 (09:41 +0200)
It may happen that two (or more) albums have the same name but each of them
comes from different artist. This case was not handled correctly causing with
the same album art to be used for all albums.

This patch makes sure that the proper album data is fetched for album. It's
achieved by either adding album artist (i.e., for cached images) or using
album id (unique) where possible (not causing too much code churn).

Change-Id: I181a28d80a18207101c613cca390f18d88dd556a

14 files changed:
src/com/andrew/apollo/MusicPlaybackService.java
src/com/andrew/apollo/adapters/AlbumAdapter.java
src/com/andrew/apollo/adapters/ArtistAlbumAdapter.java
src/com/andrew/apollo/appwidgets/RecentWidgetProvider.java
src/com/andrew/apollo/appwidgets/RecentWidgetService.java
src/com/andrew/apollo/cache/ImageFetcher.java
src/com/andrew/apollo/ui/activities/ProfileActivity.java
src/com/andrew/apollo/ui/fragments/AlbumFragment.java
src/com/andrew/apollo/ui/fragments/RecentFragment.java
src/com/andrew/apollo/utils/ApolloUtils.java
src/com/andrew/apollo/utils/MusicUtils.java
src/com/andrew/apollo/utils/NavUtils.java
src/com/andrew/apollo/widgets/CarouselTab.java
src/com/andrew/apollo/widgets/ProfileTabCarousel.java

index db1b8a7..ec1df5a 100644 (file)
@@ -1250,8 +1250,8 @@ public class MusicPlaybackService extends Service {
             }
             // Add the track to the recently played list.
             mRecentsCache.addAlbumId(getAlbumId(), getAlbumName(), getArtistName(),
-                    MusicUtils.getSongCountForAlbum(this, getAlbumName()),
-                    MusicUtils.getReleaseDateForAlbum(this, getAlbumName()));
+                    MusicUtils.getSongCountForAlbum(this, getAlbumId()),
+                    MusicUtils.getReleaseDateForAlbum(this, getAlbumId()));
         } else if (what.equals(QUEUE_CHANGED)) {
             saveQueue(true);
         } else {
index e69b529..4ff270d 100644 (file)
@@ -213,7 +213,8 @@ public class AlbumAdapter extends ArrayAdapter<Album> {
      */
     public void removeFromCache(final Album album) {
         if (mImageFetcher != null) {
-            mImageFetcher.removeFromCache(album.mAlbumName + Config.ALBUM_ART_SUFFIX);
+            mImageFetcher.removeFromCache(
+                    ImageFetcher.generateAlbumCacheKey(album.mAlbumName, album.mArtistName));
         }
     }
 
index 3274635..e6606c0 100644 (file)
@@ -226,7 +226,8 @@ public class ArtistAlbumAdapter extends ArrayAdapter<Album> {
      */
     public void removeFromCache(final Album album) {
         if (mImageFetcher != null) {
-            mImageFetcher.removeFromCache(album.mAlbumName + Config.ALBUM_ART_SUFFIX);
+            mImageFetcher.removeFromCache(
+                     ImageFetcher.generateAlbumCacheKey(album.mAlbumName, album.mArtistName));
         }
     }
 
index 3762f48..d437562 100644 (file)
@@ -149,7 +149,7 @@ public class RecentWidgetProvider extends AppWidgetBase {
                 bundle.putString(Config.NAME, albumName);
                 bundle.putString(Config.ARTIST_NAME, intent.getStringExtra(Config.ARTIST_NAME));
                 bundle.putString(Config.ALBUM_YEAR,
-                        MusicUtils.getReleaseDateForAlbum(context, albumName));
+                        MusicUtils.getReleaseDateForAlbum(context, albumId));
                 bundle.putLong(Config.ID, albumId);
 
                 // Open the album profile
index fed7be5..08e1a31 100644 (file)
@@ -141,11 +141,7 @@ public class RecentWidgetService extends RemoteViewsService {
             // Set the artist names
             mViews.setTextViewText(R.id.app_widget_recents_line_two, artist);
             // Set the album art
-            Bitmap bitmap = mFetcher.getCachedBitmap(albumName);
-
-            if (bitmap == null) {
-                bitmap = mFetcher.getCachedArtwork(albumName);
-            }
+            Bitmap bitmap = mFetcher.getCachedArtwork(albumName, artist, id);
             if (bitmap != null) {
                 mViews.setImageViewBitmap(R.id.app_widget_recents_base_image, bitmap);
             } else {
index 2a5fc45..e86234d 100644 (file)
@@ -148,7 +148,7 @@ public class ImageFetcher extends ImageWorker {
      */
     public void loadAlbumImage(final String artistName, final String albumName, final long albumId,
             final ImageView imageView) {
-        loadImage(albumName + Config.ALBUM_ART_SUFFIX, artistName, albumName, albumId, imageView,
+        loadImage(generateAlbumCacheKey(albumName, artistName), artistName, albumName, albumId, imageView,
                 ImageType.ALBUM);
     }
 
@@ -156,8 +156,8 @@ public class ImageFetcher extends ImageWorker {
      * Used to fetch the current artwork.
      */
     public void loadCurrentArtwork(final ImageView imageView) {
-        loadImage(MusicUtils.getAlbumName() + Config.ALBUM_ART_SUFFIX, MusicUtils.getArtistName(),
-                MusicUtils.getAlbumName(), MusicUtils.getCurrentAlbumId(),
+        loadImage(generateAlbumCacheKey(MusicUtils.getAlbumName(), MusicUtils.getArtistName()),
+                MusicUtils.getArtistName(), MusicUtils.getAlbumName(), MusicUtils.getCurrentAlbumId(),
                 imageView, ImageType.ALBUM);
     }
 
@@ -214,12 +214,25 @@ public class ImageFetcher extends ImageWorker {
     }
 
     /**
-     * @param key The key used to find the album art to return
+     * @param keyAlbum The key (album name) used to find the album art to return
+     * @param keyArtist The key (artist name) used to find the album art to return
      */
-    public Bitmap getCachedArtwork(final String key) {
+    public Bitmap getCachedArtwork(final String keyAlbum, final String keyArtist) {
+        return getCachedArtwork(keyAlbum, keyArtist,
+                MusicUtils.getIdForAlbum(mContext, keyAlbum, keyArtist));
+    }
+
+    /**
+     * @param keyAlbum The key (album name) used to find the album art to return
+     * @param keyArtist The key (artist name) used to find the album art to return
+     * @param keyId The key (album id) used to find the album art to return
+     */
+    public Bitmap getCachedArtwork(final String keyAlbum, final String keyArtist,
+            final long keyId) {
         if (mImageCache != null) {
-            return mImageCache.getCachedArtwork(mContext, key + Config.ALBUM_ART_SUFFIX,
-                    MusicUtils.getIdForAlbum(mContext, key));
+            return mImageCache.getCachedArtwork(mContext,
+                    generateAlbumCacheKey(keyAlbum, keyArtist),
+                    keyId);
         }
         return getDefaultArtwork();
     }
@@ -239,7 +252,8 @@ public class ImageFetcher extends ImageWorker {
         Bitmap artwork = null;
 
         if (artwork == null && albumName != null && mImageCache != null) {
-            artwork = mImageCache.getBitmapFromDiskCache(albumName + Config.ALBUM_ART_SUFFIX);
+            artwork = mImageCache.getBitmapFromDiskCache(
+                    generateAlbumCacheKey(albumName, artistName));
         }
         if (artwork == null && albumId >= 0 && mImageCache != null) {
             // Check for local artwork
@@ -383,4 +397,25 @@ public class ImageFetcher extends ImageWorker {
         }
         return inSampleSize;
     }
+
+    /**
+     * Generates key used by album art cache. It needs both album name and artist name
+     * to let to select correct image for the case when there are two albums with the
+     * same artist.
+     *
+     * @param albumName The album name the cache key needs to be generated.
+     * @param artistName The artist name the cache key needs to be generated.
+     * @return
+     */
+    public static String generateAlbumCacheKey(final String albumName, final String artistName) {
+        if (albumName == null || artistName == null) {
+            return null;
+        }
+        return new StringBuilder(albumName)
+                .append("_")
+                .append(artistName)
+                .append("_")
+                .append(Config.ALBUM_ART_SUFFIX)
+                .toString();
+    }
 }
index fc8b2ad..719f1b5 100644 (file)
@@ -313,7 +313,7 @@ public class ProfileActivity extends BaseActivity implements OnPageChangeListene
                 // screen. Definitely one of my favorite features.
                 final String name = isArtist() ? mArtistName : mProfileName;
                 final Long id = mArguments.getLong(Config.ID);
-                ApolloUtils.createShortcutIntent(name, id, mType, this);
+                ApolloUtils.createShortcutIntent(name, mArtistName, id, mType, this);
                 return true;
             }
             case R.id.menu_shuffle: {
@@ -518,7 +518,7 @@ public class ProfileActivity extends BaseActivity implements OnPageChangeListene
                     if (isArtist()) {
                         key = mArtistName;
                     } else if (isAlbum()) {
-                        key = mProfileName + Config.ALBUM_ART_SUFFIX;
+                        key = ImageFetcher.generateAlbumCacheKey(mProfileName, mArtistName);
                     }
 
                     final Bitmap bitmap = ImageFetcher.decodeSampledBitmapFromFile(picturePath);
@@ -573,7 +573,7 @@ public class ProfileActivity extends BaseActivity implements OnPageChangeListene
         // First remove the old image
         removeFromCache();
         // Fetch for the artwork
-        mTabCarousel.fetchAlbumPhoto(this, mProfileName);
+        mTabCarousel.fetchAlbumPhoto(this, mProfileName, mArtistName);
     }
 
     /**
@@ -599,7 +599,7 @@ public class ProfileActivity extends BaseActivity implements OnPageChangeListene
         if (isArtist()) {
             key = mArtistName;
         } else if (isAlbum()) {
-            key = mProfileName + Config.ALBUM_ART_SUFFIX;
+            key = ImageFetcher.generateAlbumCacheKey(mProfileName, mArtistName);
         }
         mImageFetcher.removeFromCache(key);
         // Give the disk cache a little time before requesting a new image.
index 685d19e..ae45dec 100644 (file)
@@ -41,6 +41,7 @@ import com.andrew.apollo.Config;
 import com.andrew.apollo.MusicStateListener;
 import com.andrew.apollo.R;
 import com.andrew.apollo.adapters.AlbumAdapter;
+import com.andrew.apollo.cache.ImageFetcher;
 import com.andrew.apollo.loaders.AlbumLoader;
 import com.andrew.apollo.menu.CreateNewPlaylist;
 import com.andrew.apollo.menu.DeleteDialog;
@@ -244,7 +245,8 @@ public class AlbumFragment extends Fragment implements LoaderCallbacks<List<Albu
                 case FragmentMenuItems.DELETE:
                     mShouldRefresh = true;
                     final String album = mAlbum.mAlbumName;
-                    DeleteDialog.newInstance(album, mAlbumList, album + Config.ALBUM_ART_SUFFIX)
+                    DeleteDialog.newInstance(album, mAlbumList,
+                            ImageFetcher.generateAlbumCacheKey(album,mAlbum.mArtistName))
                             .show(getFragmentManager(), "DeleteDialog");
                     return true;
                 default:
index f564327..faff0a0 100644 (file)
@@ -39,6 +39,7 @@ import com.andrew.apollo.Config;
 import com.andrew.apollo.MusicStateListener;
 import com.andrew.apollo.R;
 import com.andrew.apollo.adapters.AlbumAdapter;
+import com.andrew.apollo.cache.ImageFetcher;
 import com.andrew.apollo.loaders.RecentLoader;
 import com.andrew.apollo.menu.CreateNewPlaylist;
 import com.andrew.apollo.menu.DeleteDialog;
@@ -252,7 +253,8 @@ public class RecentFragment extends Fragment implements LoaderCallbacks<List<Alb
                 case FragmentMenuItems.DELETE:
                     mShouldRefresh = true;
                     final String album = mAlbum.mAlbumName;
-                    DeleteDialog.newInstance(album, mAlbumList, album + Config.ALBUM_ART_SUFFIX)
+                    DeleteDialog.newInstance(album, mAlbumList,
+                            ImageFetcher.generateAlbumCacheKey(album, mAlbum.mArtistName))
                             .show(getFragmentManager(), "DeleteDialog");
                     return true;
                 default:
index dc9bcbb..707967b 100644 (file)
@@ -276,13 +276,14 @@ public final class ApolloUtils {
      * @param mimeType The MIME type of the shortcut
      * @param context The {@link Context} to use to
      */
-    public static void createShortcutIntent(final String displayName, final Long id,
-            final String mimeType, final Activity context) {
+    public static void createShortcutIntent(final String displayName, final String artistName,
+            final Long id, final String mimeType, final Activity context) {
         try {
             final ImageFetcher fetcher = getImageFetcher(context);
             Bitmap bitmap = null;
             if (mimeType.equals(MediaStore.Audio.Albums.CONTENT_TYPE)) {
-                bitmap = fetcher.getCachedBitmap(displayName + Config.ALBUM_ART_SUFFIX);
+                bitmap = fetcher.getCachedBitmap(
+                        ImageFetcher.generateAlbumCacheKey(displayName, artistName));
             } else {
                 bitmap = fetcher.getCachedBitmap(displayName);
             }
index 65bd1f4..b947ec1 100644 (file)
@@ -727,15 +727,17 @@ public final class MusicUtils {
      * Returns the ID for an album.
      *
      * @param context The {@link Context} to use.
-     * @param name The name of the album.
+     * @param albumName The name of the album.
+     * @param artistName The name of the artist
      * @return The ID for an album.
      */
-    public static final long getIdForAlbum(final Context context, final String name) {
+    public static final long getIdForAlbum(final Context context, final String albumName,
+            final String artistName) {
         Cursor cursor = context.getContentResolver().query(
                 MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, new String[] {
                     BaseColumns._ID
-                }, AlbumColumns.ALBUM + "=?", new String[] {
-                    name
+                }, AlbumColumns.ALBUM + "=? AND " + AlbumColumns.ARTIST + "=?", new String[] {
+                    albumName, artistName
                 }, AlbumColumns.ALBUM);
         int id = -1;
         if (cursor != null) {
@@ -749,32 +751,6 @@ public final class MusicUtils {
         return id;
     }
 
-    /**
-     * Returns the artist name for a album.
-     *
-     * @param context The {@link Context} to use.
-     * @param name The name of the album.
-     * @return The artist for an album.
-     */
-    public static final String getAlbumArtist(final Context context, final String name) {
-        Cursor cursor = context.getContentResolver().query(
-                MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, new String[] {
-                    AlbumColumns.ARTIST
-                }, AlbumColumns.ALBUM + "=?", new String[] {
-                    name
-                }, AlbumColumns.ALBUM);
-        String artistName = null;
-        if (cursor != null) {
-            cursor.moveToFirst();
-            if (!cursor.isAfterLast()) {
-                artistName = cursor.getString(0);
-            }
-            cursor.close();
-            cursor = null;
-        }
-        return artistName;
-    }
-
     /*  */
     public static void makeInsertItems(final long[] ids, final int offset, int len, final int base) {
         if (offset + len > ids.length) {
@@ -917,19 +893,17 @@ public final class MusicUtils {
 
     /**
      * @param context The {@link Context} to use.
-     * @param name The name of the album.
+     * @param id The id of the album.
      * @return The song count for an album.
      */
-    public static final String getSongCountForAlbum(final Context context, final String name) {
-        if (name == null) {
+    public static final String getSongCountForAlbum(final Context context, final long id) {
+        if (id == -1) {
             return null;
         }
-        Cursor cursor = context.getContentResolver().query(
-                MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, new String[] {
+        Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, id);
+        Cursor cursor = context.getContentResolver().query(uri, new String[] {
                     AlbumColumns.NUMBER_OF_SONGS
-                }, AlbumColumns.ALBUM + "=?", new String[] {
-                    name
-                }, AlbumColumns.ALBUM);
+                }, null, null, null);
         String songCount = null;
         if (cursor != null) {
             cursor.moveToFirst();
@@ -944,19 +918,17 @@ public final class MusicUtils {
 
     /**
      * @param context The {@link Context} to use.
-     * @param name The name of the album.
+     * @param id The id of the album.
      * @return The release date for an album.
      */
-    public static final String getReleaseDateForAlbum(final Context context, final String name) {
-        if (name == null) {
+    public static final String getReleaseDateForAlbum(final Context context, final long id) {
+        if (id == -1) {
             return null;
         }
-        Cursor cursor = context.getContentResolver().query(
-                MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, new String[] {
+        Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, id);
+        Cursor cursor = context.getContentResolver().query(uri, new String[] {
                     AlbumColumns.FIRST_YEAR
-                }, AlbumColumns.ALBUM + "=?", new String[] {
-                    name
-                }, AlbumColumns.ALBUM);
+                }, null, null, null);
         String releaseDate = null;
         if (cursor != null) {
             cursor.moveToFirst();
index 2fae7f7..37f63ce 100644 (file)
@@ -70,7 +70,7 @@ public final class NavUtils {
 
         // Create a new bundle to transfer the album info
         final Bundle bundle = new Bundle();
-        bundle.putString(Config.ALBUM_YEAR, MusicUtils.getReleaseDateForAlbum(context, albumName));
+        bundle.putString(Config.ALBUM_YEAR, MusicUtils.getReleaseDateForAlbum(context, albumId));
         bundle.putString(Config.ARTIST_NAME, artistName);
         bundle.putString(Config.MIME_TYPE, MediaStore.Audio.Albums.CONTENT_TYPE);
         bundle.putLong(Config.ID, albumId);
index 66d3b4f..2cf97ae 100644 (file)
@@ -114,7 +114,7 @@ public class CarouselTab extends FrameLayoutWithOverlay {
         Bitmap artistImage = mFetcher.getCachedBitmap(artist);
         // Second check for cached artwork
         if (artistImage == null) {
-            artistImage = mFetcher.getCachedArtwork(album);
+            artistImage = mFetcher.getCachedArtwork(album, artist);
         }
         // If all else, use the default image
         if (artistImage == null) {
@@ -130,11 +130,11 @@ public class CarouselTab extends FrameLayoutWithOverlay {
      * @param context The {@link Context} to use.
      * @param album The name of the album in the profile the user is viewing.
      */
-    public void setAlbumPhoto(final Activity context, final String album) {
+    public void setAlbumPhoto(final Activity context, final String album, final String artist) {
         if (!TextUtils.isEmpty(album)) {
             mAlbumArt.setVisibility(View.VISIBLE);
-            mFetcher.loadAlbumImage(MusicUtils.getAlbumArtist(context, album), album,
-                    MusicUtils.getIdForAlbum(context, album), mAlbumArt);
+            mFetcher.loadAlbumImage(artist, album,
+                    MusicUtils.getIdForAlbum(context, album, artist), mAlbumArt);
         } else {
             setDefault(context);
         }
@@ -145,12 +145,12 @@ public class CarouselTab extends FrameLayoutWithOverlay {
      * 
      * @param context The {@link Context} to use.
      * @param album The name of the album in the profile the user is viewing.
+     * @param artist The name of the album artist in the profile the user is viewing
      */
-    public void fetchAlbumPhoto(final Activity context, final String album) {
+    public void fetchAlbumPhoto(final Activity context, final String album, final String artist) {
         if (!TextUtils.isEmpty(album)) {
-            mFetcher.removeFromCache(album + Config.ALBUM_ART_SUFFIX);
-            mFetcher.loadAlbumImage(MusicUtils.getAlbumArtist(context, album), album, -1,
-                    mAlbumArt);
+            mFetcher.removeFromCache(ImageFetcher.generateAlbumCacheKey(album, artist));
+            mFetcher.loadAlbumImage(artist, album, -1, mAlbumArt);
         } else {
             setDefault(context);
         }
@@ -167,14 +167,14 @@ public class CarouselTab extends FrameLayoutWithOverlay {
         if (!TextUtils.isEmpty(lastAlbum)) {
             // Set the last album the artist played
             mFetcher.loadAlbumImage(artist, lastAlbum,
-                    MusicUtils.getIdForAlbum(context, lastAlbum), mPhoto);
+                    MusicUtils.getIdForAlbum(context, lastAlbum, artist), mPhoto);
             // Play the album
             mPhoto.setOnClickListener(new OnClickListener() {
 
                 @Override
                 public void onClick(final View v) {
                     final long[] albumList = MusicUtils.getSongListForAlbum(getContext(),
-                            MusicUtils.getIdForAlbum(context, lastAlbum));
+                            MusicUtils.getIdForAlbum(context, lastAlbum, artist));
                     MusicUtils.playAll(getContext(), albumList, 0, false);
                 }
             });
index 1320f78..b396a3f 100644 (file)
@@ -462,7 +462,7 @@ public class ProfileTabCarousel extends HorizontalScrollView implements OnTouchL
     public void setAlbumProfileHeader(final Activity context,
             final String albumName, final String artistName) {
         mFirstTab.setLabel(getResources().getString(R.string.page_songs));
-        mFirstTab.setAlbumPhoto(context, albumName);
+        mFirstTab.setAlbumPhoto(context, albumName, artistName);
         mFirstTab.blurPhoto(context, artistName, albumName);
         mSecondTab.setVisibility(View.GONE);
         mEnableSwipe = false;
@@ -488,10 +488,12 @@ public class ProfileTabCarousel extends HorizontalScrollView implements OnTouchL
      * Used to fetch for the album art via Last.fm.
      * 
      * @param context The {@link Context} to use.
-     * @param album The name of the album in the profile the user is viewing.
+     * @param albumName The name of the album in the profile the user is viewing.
+     * @param artistName The name of the album artist in the profile the user is viewing.
      */
-    public void fetchAlbumPhoto(final Activity context, final String albumName) {
-        mFirstTab.fetchAlbumPhoto(context, albumName);
+    public void fetchAlbumPhoto(final Activity context, final String albumName,
+            final String artistName) {
+        mFirstTab.fetchAlbumPhoto(context, albumName, artistName);
     }
 
     /**