From 7a9ce9a16de9e8ad187ba402ad085b20a4895c6f Mon Sep 17 00:00:00 2001 From: Iwo Banas Date: Sun, 16 Sep 2012 13:15:36 +0100 Subject: [PATCH] Rewrite image fetching and caching MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Rewrite of artist and album images fetching and caching functionality. The main objectives of this rewrite are to: reduce images flickering when scrolling, ensure that correct images are displayed next to corresponding artist and to simplify the code so that it’s easier to extend. The image downloading logic, which was previously scattered throughout the application, got replaced with the call to ImageUtils.setArtistImage() static function which delegates the the task to the ImageProvider singleton. To prevent image flickering bitmaps cached in memory are applied to ImageViews synchronously on the UI thread. Images requiring disc or network access are processed in AsyncTasks. Conflicts: src/com/andrew/apollo/service/ApolloService.java Change-Id: Icba3939b87df72986f56e2305cbc59df9feb20f9 --- res/values/config.xml | 3 + src/com/andrew/apollo/AudioPlayerFragment.java | 30 +---- src/com/andrew/apollo/Constants.java | 3 +- src/com/andrew/apollo/IApolloService.aidl | 1 + src/com/andrew/apollo/activities/MusicLibrary.java | 4 + .../andrew/apollo/activities/TracksBrowser.java | 56 +--------- src/com/andrew/apollo/adapters/AlbumAdapter.java | 27 +---- src/com/andrew/apollo/adapters/ArtistAdapter.java | 26 +---- .../andrew/apollo/adapters/ArtistAlbumAdapter.java | 26 +---- .../andrew/apollo/adapters/QuickQueueAdapter.java | 43 +------ .../apollo/adapters/RecentlyAddedAdapter.java | 26 +---- src/com/andrew/apollo/app/widgets/AppWidget11.java | 8 +- src/com/andrew/apollo/app/widgets/AppWidget41.java | 8 +- src/com/andrew/apollo/app/widgets/AppWidget42.java | 8 +- .../apollo/grid/fragments/AlbumsFragment.java | 29 +---- .../apollo/grid/fragments/ArtistsFragment.java | 34 +----- .../list/fragments/ArtistAlbumsFragment.java | 29 +---- .../andrew/apollo/preferences/SettingsHolder.java | 8 +- src/com/andrew/apollo/service/ApolloService.java | 65 +++++++++-- src/com/andrew/apollo/tasks/BitmapFromURL.java | 43 ------- src/com/andrew/apollo/tasks/FetchAlbumImages.java | 123 --------------------- src/com/andrew/apollo/tasks/FetchArtistImages.java | 87 --------------- src/com/andrew/apollo/tasks/GetAlbumImageTask.java | 56 ++++++++++ .../andrew/apollo/tasks/GetArtistImageTask.java | 55 +++++++++ src/com/andrew/apollo/tasks/GetBitmapTask.java | 123 +++++++++++++++++++++ src/com/andrew/apollo/tasks/GetCachedImages.java | 73 ------------ .../andrew/apollo/tasks/LastfmGetAlbumImages.java | 78 ------------- .../andrew/apollo/tasks/LastfmGetArtistImages.java | 67 ----------- .../tasks/LastfmGetArtistImagesOriginal.java | 80 -------------- .../andrew/apollo/tasks/ViewHolderQueueTask.java | 83 -------------- src/com/andrew/apollo/tasks/ViewHolderTask.java | 95 ---------------- .../andrew/apollo/ui/widgets/BottomActionBar.java | 7 +- .../apollo/ui/widgets/BottomActionBarItem.java | 6 - src/com/andrew/apollo/utils/ApolloUtils.java | 110 ++++++++---------- src/com/andrew/apollo/utils/ImageCache.java | 22 ++++ src/com/andrew/apollo/utils/ImageProvider.java | 112 +++++++++++++++++++ src/com/andrew/apollo/utils/ImageUtils.java | 24 ++++ src/com/andrew/apollo/views/ViewHolderGrid.java | 2 - src/com/andrew/apollo/views/ViewHolderList.java | 2 - src/com/andrew/apollo/views/ViewHolderQueue.java | 2 - 40 files changed, 549 insertions(+), 1135 deletions(-) delete mode 100644 src/com/andrew/apollo/tasks/BitmapFromURL.java delete mode 100644 src/com/andrew/apollo/tasks/FetchAlbumImages.java delete mode 100644 src/com/andrew/apollo/tasks/FetchArtistImages.java create mode 100644 src/com/andrew/apollo/tasks/GetAlbumImageTask.java create mode 100644 src/com/andrew/apollo/tasks/GetArtistImageTask.java create mode 100644 src/com/andrew/apollo/tasks/GetBitmapTask.java delete mode 100644 src/com/andrew/apollo/tasks/GetCachedImages.java delete mode 100644 src/com/andrew/apollo/tasks/LastfmGetAlbumImages.java delete mode 100644 src/com/andrew/apollo/tasks/LastfmGetArtistImages.java delete mode 100644 src/com/andrew/apollo/tasks/LastfmGetArtistImagesOriginal.java delete mode 100644 src/com/andrew/apollo/tasks/ViewHolderQueueTask.java delete mode 100644 src/com/andrew/apollo/tasks/ViewHolderTask.java create mode 100644 src/com/andrew/apollo/utils/ImageCache.java create mode 100644 src/com/andrew/apollo/utils/ImageProvider.java create mode 100644 src/com/andrew/apollo/utils/ImageUtils.java diff --git a/res/values/config.xml b/res/values/config.xml index c3e8295..d907f3c 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -17,4 +17,7 @@ 16 32 + + 300 + \ No newline at end of file diff --git a/src/com/andrew/apollo/AudioPlayerFragment.java b/src/com/andrew/apollo/AudioPlayerFragment.java index 88517c8..ee4bf6b 100644 --- a/src/com/andrew/apollo/AudioPlayerFragment.java +++ b/src/com/andrew/apollo/AudioPlayerFragment.java @@ -8,12 +8,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.RemoteException; -import android.os.SystemClock; +import android.os.*; import android.provider.BaseColumns; import android.provider.MediaStore.Audio; import android.support.v4.app.Fragment; @@ -21,27 +16,17 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.SeekBar; +import android.widget.*; import android.widget.SeekBar.OnSeekBarChangeListener; -import android.widget.TextView; -import android.widget.Toast; - import com.andrew.apollo.activities.TracksBrowser; import com.andrew.apollo.service.ApolloService; -import com.andrew.apollo.tasks.GetCachedImages; -import com.andrew.apollo.tasks.LastfmGetAlbumImages; import com.andrew.apollo.ui.widgets.RepeatingImageButton; import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; import com.andrew.apollo.utils.ThemeUtils; -import static com.andrew.apollo.Constants.ALBUM_KEY; -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.ARTIST_ID; -import static com.andrew.apollo.Constants.ARTIST_KEY; -import static com.andrew.apollo.Constants.MIME_TYPE; +import static com.andrew.apollo.Constants.*; /** * @author Andrew Neal @@ -584,12 +569,7 @@ public class AudioPlayerFragment extends Fragment { mDuration = MusicUtils.getDuration(); mTotalTime.setText(MusicUtils.makeTimeString(getActivity(), mDuration / 1000)); - if (ApolloUtils.getImageURL(albumName, ALBUM_IMAGE, getActivity()) == null) - new LastfmGetAlbumImages(getActivity(), mAlbumArt, 1).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName, albumName); - - new GetCachedImages(getActivity(), 1, mAlbumArt).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, albumName); + ImageUtils.setAlbumImage(mAlbumArt, artistName, albumName); // Theme chooser ThemeUtils.setTextColor(getActivity(), mTrackName, "audio_player_text_color"); diff --git a/src/com/andrew/apollo/Constants.java b/src/com/andrew/apollo/Constants.java index 5491019..6ca5541 100644 --- a/src/com/andrew/apollo/Constants.java +++ b/src/com/andrew/apollo/Constants.java @@ -14,8 +14,7 @@ public final class Constants { // SharedPreferences public final static String APOLLO = "Apollo", APOLLO_PREFERENCES = "apollopreferences", - ARTIST_IMAGE = "artistimage", ARTIST_IMAGE_ORIGINAL = "artistimageoriginal", - ALBUM_IMAGE = "albumimage", ARTIST_KEY = "artist", ALBUM_KEY = "album", + ARTIST_KEY = "artist", ALBUM_KEY = "album", GENRE_KEY = "genres", ARTIST_ID = "artistid", NUMWEEKS = "numweeks", PLAYLIST_NAME_FAVORITES = "Favorites", PLAYLIST_NAME = "playlist", THEME_PACKAGE_NAME = "themePackageName", THEME_DESCRIPTION = "themeDescription", diff --git a/src/com/andrew/apollo/IApolloService.aidl b/src/com/andrew/apollo/IApolloService.aidl index b3a9b39..9e6ea1d 100644 --- a/src/com/andrew/apollo/IApolloService.aidl +++ b/src/com/andrew/apollo/IApolloService.aidl @@ -20,6 +20,7 @@ interface IApolloService String getTrackName(); String getAlbumName(); long getAlbumId(); + Bitmap getAlbumBitmap(); String getArtistName(); long getArtistId(); void enqueue(in long [] list, int action); diff --git a/src/com/andrew/apollo/activities/MusicLibrary.java b/src/com/andrew/apollo/activities/MusicLibrary.java index e86ebd8..8dcf018 100644 --- a/src/com/andrew/apollo/activities/MusicLibrary.java +++ b/src/com/andrew/apollo/activities/MusicLibrary.java @@ -33,6 +33,7 @@ import com.andrew.apollo.service.ApolloService; import com.andrew.apollo.service.ServiceToken; import com.andrew.apollo.ui.widgets.ScrollableTabView; import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageCache; import com.andrew.apollo.utils.MusicUtils; import com.andrew.apollo.utils.ThemeUtils; @@ -99,6 +100,9 @@ public class MusicLibrary extends FragmentActivity implements ServiceConnection // Unbind if (MusicUtils.mService != null) MusicUtils.unbindFromService(mToken); + + //TODO: clear image cache + super.onStop(); } diff --git a/src/com/andrew/apollo/activities/TracksBrowser.java b/src/com/andrew/apollo/activities/TracksBrowser.java index 714f074..bdf257d 100644 --- a/src/com/andrew/apollo/activities/TracksBrowser.java +++ b/src/com/andrew/apollo/activities/TracksBrowser.java @@ -4,19 +4,13 @@ package com.andrew.apollo.activities; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.ServiceConnection; +import android.content.*; import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.AnimationDrawable; import android.media.AudioManager; -import android.os.AsyncTask; import android.os.Bundle; import android.os.IBinder; import android.os.SystemClock; @@ -31,7 +25,6 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; - import com.andrew.apollo.BottomActionBarControlsFragment; import com.andrew.apollo.BottomActionBarFragment; import com.andrew.apollo.IApolloService; @@ -41,26 +34,12 @@ import com.andrew.apollo.list.fragments.ArtistAlbumsFragment; import com.andrew.apollo.list.fragments.TracksFragment; import com.andrew.apollo.service.ApolloService; import com.andrew.apollo.service.ServiceToken; -import com.andrew.apollo.tasks.GetCachedImages; -import com.andrew.apollo.tasks.LastfmGetAlbumImages; -import com.andrew.apollo.tasks.LastfmGetArtistImagesOriginal; import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; import com.andrew.apollo.utils.ThemeUtils; -import static com.andrew.apollo.Constants.ALBUM_KEY; -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.ARTIST_KEY; -import static com.andrew.apollo.Constants.ARTIST_ID; -import static com.andrew.apollo.Constants.ARTIST_IMAGE_ORIGINAL; -import static com.andrew.apollo.Constants.GENRE_KEY; -import static com.andrew.apollo.Constants.INTENT_ACTION; -import static com.andrew.apollo.Constants.MIME_TYPE; -import static com.andrew.apollo.Constants.PLAYLIST_NAME; -import static com.andrew.apollo.Constants.PLAYLIST_QUEUE; -import static com.andrew.apollo.Constants.PLAYLIST_FAVORITES; -import static com.andrew.apollo.Constants.THEME_ITEM_BACKGROUND; -import static com.andrew.apollo.Constants.UP_STARTS_ALBUM_ACTIVITY; +import static com.andrew.apollo.Constants.*; /** * @author Andrew Neal @@ -352,19 +331,7 @@ public class TracksBrowser extends FragmentActivity implements ServiceConnection // Artist image & Genre image final ImageView mFirstHalfImage = (ImageView)findViewById(R.id.half_artist_image); - - mFirstHalfImage.post(new Runnable() { - @Override - public void run() { - // Only download images we don't already have - if (ApolloUtils.getImageURL(getArtist(), ARTIST_IMAGE_ORIGINAL, TracksBrowser.this) == null) - new LastfmGetArtistImagesOriginal(TracksBrowser.this, mFirstHalfImage) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getArtist()); - // Get and set cached image - new GetCachedImages(TracksBrowser.this, 0, mFirstHalfImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, getArtist()); - } - }); + ImageUtils.setArtistImage(mFirstHalfImage, getArtist()); mFirstHalfImage.setOnClickListener(new OnClickListener() { @@ -388,20 +355,7 @@ public class TracksBrowser extends FragmentActivity implements ServiceConnection // Album image final ImageView mSecondHalfImage = (ImageView)findViewById(R.id.half_album_image); - - mSecondHalfImage.post(new Runnable() { - @Override - public void run() { - // Only download images we don't already have - if (ApolloUtils.getImageURL(getAlbum(), ALBUM_IMAGE, TracksBrowser.this) == null) - new LastfmGetAlbumImages(TracksBrowser.this, mSecondHalfImage, 1) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getArtist(), - getAlbum()); - // Get and set cached image - new GetCachedImages(TracksBrowser.this, 1, mSecondHalfImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, getAlbum()); - } - }); + ImageUtils.setAlbumImage(mSecondHalfImage, getArtist(), getAlbum()); } /** diff --git a/src/com/andrew/apollo/adapters/AlbumAdapter.java b/src/com/andrew/apollo/adapters/AlbumAdapter.java index b7f22b1..07b0f58 100644 --- a/src/com/andrew/apollo/adapters/AlbumAdapter.java +++ b/src/com/andrew/apollo/adapters/AlbumAdapter.java @@ -1,27 +1,21 @@ package com.andrew.apollo.adapters; -import java.lang.ref.WeakReference; - import android.content.Context; import android.database.Cursor; import android.graphics.drawable.AnimationDrawable; -import android.os.AsyncTask; import android.os.RemoteException; import android.support.v4.widget.SimpleCursorAdapter; import android.view.View; import android.view.ViewGroup; - import com.andrew.apollo.R; import com.andrew.apollo.grid.fragments.AlbumsFragment; -import com.andrew.apollo.tasks.LastfmGetAlbumImages; -import com.andrew.apollo.tasks.ViewHolderTask; -import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; import com.andrew.apollo.views.ViewHolderGrid; import com.androidquery.AQuery; -import static com.andrew.apollo.Constants.ALBUM_IMAGE; +import java.lang.ref.WeakReference; /** * @author Andrew Neal @@ -63,21 +57,8 @@ public class AlbumAdapter extends SimpleCursorAdapter { String artistName = mCursor.getString(AlbumsFragment.mArtistNameIndex); holderReference.get().mViewHolderLineTwo.setText(artistName); - // Match positions - holderReference.get().position = position; - if (aq.shouldDelay(position, view, parent, "")) { - holderReference.get().mViewHolderImage.setImageDrawable(null); - } else { - // Check for missing album images and cache them - if (ApolloUtils.getImageURL(albumName, ALBUM_IMAGE, mContext) == null) { - new LastfmGetAlbumImages(mContext, null, 0).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName, albumName); - } else { - new ViewHolderTask(null, holderReference.get(), position, mContext, 1, 1, - holderReference.get().mViewHolderImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, albumName); - } - } + ImageUtils.setAlbumImage(viewholder.mViewHolderImage, artistName, albumName); + // Now playing indicator long currentalbumid = MusicUtils.getCurrentAlbumId(); long albumid = mCursor.getLong(AlbumsFragment.mAlbumIdIndex); diff --git a/src/com/andrew/apollo/adapters/ArtistAdapter.java b/src/com/andrew/apollo/adapters/ArtistAdapter.java index ceb2974..bd269e8 100644 --- a/src/com/andrew/apollo/adapters/ArtistAdapter.java +++ b/src/com/andrew/apollo/adapters/ArtistAdapter.java @@ -1,28 +1,22 @@ package com.andrew.apollo.adapters; -import java.lang.ref.WeakReference; - import android.content.Context; import android.database.Cursor; import android.graphics.drawable.AnimationDrawable; -import android.os.AsyncTask; import android.os.RemoteException; import android.provider.MediaStore; import android.support.v4.widget.SimpleCursorAdapter; import android.view.View; import android.view.ViewGroup; - import com.andrew.apollo.R; import com.andrew.apollo.grid.fragments.ArtistsFragment; -import com.andrew.apollo.tasks.LastfmGetArtistImages; -import com.andrew.apollo.tasks.ViewHolderTask; -import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; import com.andrew.apollo.views.ViewHolderGrid; import com.androidquery.AQuery; -import static com.andrew.apollo.Constants.ARTIST_IMAGE; +import java.lang.ref.WeakReference; /** * @author Andrew Neal @@ -66,20 +60,8 @@ public class ArtistAdapter extends SimpleCursorAdapter { String numAlbums = MusicUtils.makeAlbumsLabel(mContext, albums_plural, 0, unknown); holderReference.get().mViewHolderLineTwo.setText(numAlbums); - holderReference.get().position = position; - if (aq.shouldDelay(position, view, parent, "")) { - holderReference.get().mViewHolderImage.setImageDrawable(null); - } else { - // Check for missing artist images and cache them - if (ApolloUtils.getImageURL(artistName, ARTIST_IMAGE, mContext) == null) { - new LastfmGetArtistImages(mContext).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName); - } else { - new ViewHolderTask(null, holderReference.get(), position, mContext, 0, 1, - holderReference.get().mViewHolderImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName); - } - } + ImageUtils.setArtistImage(viewholder.mViewHolderImage, artistName); + // Now playing indicator long currentartistid = MusicUtils.getCurrentArtistId(); long artistid = mCursor.getLong(ArtistsFragment.mArtistIdIndex); diff --git a/src/com/andrew/apollo/adapters/ArtistAlbumAdapter.java b/src/com/andrew/apollo/adapters/ArtistAlbumAdapter.java index 4faef37..2751d1f 100644 --- a/src/com/andrew/apollo/adapters/ArtistAlbumAdapter.java +++ b/src/com/andrew/apollo/adapters/ArtistAlbumAdapter.java @@ -1,27 +1,21 @@ package com.andrew.apollo.adapters; -import java.lang.ref.WeakReference; - import android.content.Context; import android.database.Cursor; import android.graphics.drawable.AnimationDrawable; -import android.os.AsyncTask; import android.os.RemoteException; import android.support.v4.widget.SimpleCursorAdapter; import android.view.View; import android.view.ViewGroup; - import com.andrew.apollo.R; import com.andrew.apollo.list.fragments.ArtistAlbumsFragment; -import com.andrew.apollo.tasks.LastfmGetAlbumImages; -import com.andrew.apollo.tasks.ViewHolderTask; -import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; import com.andrew.apollo.views.ViewHolderList; import com.androidquery.AQuery; -import static com.andrew.apollo.Constants.ALBUM_IMAGE; +import java.lang.ref.WeakReference; /** * @author Andrew Neal @@ -78,21 +72,7 @@ public class ArtistAlbumAdapter extends SimpleCursorAdapter { String numSongs = MusicUtils.makeAlbumsLabel(mContext, 0, songs_plural, true); holderReference.get().mViewHolderLineTwo.setText(numSongs); - // Match positions - holderReference.get().position = position; - if (aq.shouldDelay(position, view, parent, "")) { - holderReference.get().mViewHolderImage.setImageDrawable(null); - } else { - // Check for missing album images and cache them - if (ApolloUtils.getImageURL(albumName, ALBUM_IMAGE, mContext) == null) { - new LastfmGetAlbumImages(mContext, null, 0).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName, albumName); - } else { - new ViewHolderTask(holderReference.get(), null, position, mContext, 1, 0, - holderReference.get().mViewHolderImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, albumName); - } - } + ImageUtils.setAlbumImage(viewholder.mViewHolderImage, artistName, albumName); holderReference.get().mQuickContext.setOnClickListener(showContextMenu); diff --git a/src/com/andrew/apollo/adapters/QuickQueueAdapter.java b/src/com/andrew/apollo/adapters/QuickQueueAdapter.java index 5c50740..2757439 100644 --- a/src/com/andrew/apollo/adapters/QuickQueueAdapter.java +++ b/src/com/andrew/apollo/adapters/QuickQueueAdapter.java @@ -1,25 +1,17 @@ package com.andrew.apollo.adapters; -import java.lang.ref.WeakReference; - import android.content.Context; import android.database.Cursor; -import android.os.AsyncTask; import android.support.v4.widget.SimpleCursorAdapter; import android.view.View; import android.view.ViewGroup; - import com.andrew.apollo.grid.fragments.QuickQueueFragment; -import com.andrew.apollo.tasks.LastfmGetAlbumImages; -import com.andrew.apollo.tasks.LastfmGetArtistImages; -import com.andrew.apollo.tasks.ViewHolderQueueTask; -import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.views.ViewHolderQueue; import com.androidquery.AQuery; -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.ARTIST_IMAGE; +import java.lang.ref.WeakReference; /** * @author Andrew Neal @@ -62,36 +54,9 @@ public class QuickQueueAdapter extends SimpleCursorAdapter { String trackName = mCursor.getString(QuickQueueFragment.mTitleIndex); holderReference.get().mTrackName.setText(trackName); - holderReference.get().position = position; - // Artist Image - if (aq.shouldDelay(position, view, parent, "")) { - holderReference.get().mArtistImage.setImageDrawable(null); - } else { - // Check for missing artist images and cache them - if (ApolloUtils.getImageURL(artistName, ARTIST_IMAGE, mContext) == null) { - new LastfmGetArtistImages(mContext).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName); - } else { - new ViewHolderQueueTask(holderReference.get(), position, mContext, 0, 0, - holderReference.get().mArtistImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName); - } - } + ImageUtils.setArtistImage(viewholder.mArtistImage, artistName); + ImageUtils.setAlbumImage(viewholder.mAlbumArt, artistName, albumName); - // Album Image - if (aq.shouldDelay(position, view, parent, "")) { - holderReference.get().mAlbumArt.setImageDrawable(null); - } else { - // Check for missing album images and cache them - if (ApolloUtils.getImageURL(albumName, ALBUM_IMAGE, mContext) == null) { - new LastfmGetAlbumImages(mContext, null, 0).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName, albumName); - } else { - new ViewHolderQueueTask(holderReference.get(), position, mContext, 1, 1, - holderReference.get().mAlbumArt).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, albumName); - } - } return view; } } diff --git a/src/com/andrew/apollo/adapters/RecentlyAddedAdapter.java b/src/com/andrew/apollo/adapters/RecentlyAddedAdapter.java index 8efa2eb..bc9f80b 100644 --- a/src/com/andrew/apollo/adapters/RecentlyAddedAdapter.java +++ b/src/com/andrew/apollo/adapters/RecentlyAddedAdapter.java @@ -1,27 +1,21 @@ package com.andrew.apollo.adapters; -import java.lang.ref.WeakReference; - import android.content.Context; import android.database.Cursor; import android.graphics.drawable.AnimationDrawable; -import android.os.AsyncTask; import android.os.RemoteException; import android.support.v4.widget.SimpleCursorAdapter; import android.view.View; import android.view.ViewGroup; - import com.andrew.apollo.R; import com.andrew.apollo.list.fragments.RecentlyAddedFragment; -import com.andrew.apollo.tasks.LastfmGetAlbumImages; -import com.andrew.apollo.tasks.ViewHolderTask; -import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; import com.andrew.apollo.views.ViewHolderList; import com.androidquery.AQuery; -import static com.andrew.apollo.Constants.ALBUM_IMAGE; +import java.lang.ref.WeakReference; /** * @author Andrew Neal @@ -66,21 +60,7 @@ public class RecentlyAddedAdapter extends SimpleCursorAdapter { // Album name String albumName = mCursor.getString(RecentlyAddedFragment.mAlbumIndex); - // Match positions - holderReference.get().position = position; - if (aq.shouldDelay(position, view, parent, "")) { - holderReference.get().mViewHolderImage.setImageDrawable(null); - } else { - // Check for missing artwork and cache then cache it - if (ApolloUtils.getImageURL(albumName, ALBUM_IMAGE, mContext) == null) { - new LastfmGetAlbumImages(mContext, null, 0).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName, albumName); - } else { - new ViewHolderTask(holderReference.get(), null, position, mContext, 1, 0, - holderReference.get().mViewHolderImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, albumName); - } - } + ImageUtils.setAlbumImage(viewholder.mViewHolderImage, artistName, albumName); holderReference.get().mQuickContext.setVisibility(View.GONE); diff --git a/src/com/andrew/apollo/app/widgets/AppWidget11.java b/src/com/andrew/apollo/app/widgets/AppWidget11.java index c730a2c..465e4f4 100644 --- a/src/com/andrew/apollo/app/widgets/AppWidget11.java +++ b/src/com/andrew/apollo/app/widgets/AppWidget11.java @@ -13,10 +13,6 @@ import android.widget.RemoteViews; import com.andrew.apollo.R; import com.andrew.apollo.service.ApolloService; -import com.andrew.apollo.utils.ApolloUtils; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ALBUM_IMAGE; /** * Simple widget to show currently playing album art along with play/pause and @@ -105,9 +101,7 @@ public class AppWidget11 extends AppWidgetProvider { R.layout.onebyone_app_widget); // Set album art - AQuery aq = new AQuery(service); - Bitmap bitmap = aq.getCachedImage(ApolloUtils.getImageURL(service.getAlbumName(), - ALBUM_IMAGE, service)); + Bitmap bitmap = service.getAlbumBitmap(); if (bitmap != null) { views.setViewVisibility(R.id.one_by_one_albumart, View.VISIBLE); views.setImageViewBitmap(R.id.one_by_one_albumart, bitmap); diff --git a/src/com/andrew/apollo/app/widgets/AppWidget41.java b/src/com/andrew/apollo/app/widgets/AppWidget41.java index b34e1cf..627948f 100644 --- a/src/com/andrew/apollo/app/widgets/AppWidget41.java +++ b/src/com/andrew/apollo/app/widgets/AppWidget41.java @@ -30,10 +30,6 @@ import com.andrew.apollo.R; import com.andrew.apollo.activities.AudioPlayerHolder; import com.andrew.apollo.activities.MusicLibrary; import com.andrew.apollo.service.ApolloService; -import com.andrew.apollo.utils.ApolloUtils; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ALBUM_IMAGE; /** * Simple widget to show currently playing album art along with play/pause and @@ -125,9 +121,7 @@ public class AppWidget41 extends AppWidgetProvider { views.setTextViewText(R.id.four_by_one_title, titleName); views.setTextViewText(R.id.four_by_one_artist, artistName); // Set album art - AQuery aq = new AQuery(service); - Bitmap bitmap = aq.getCachedImage(ApolloUtils.getImageURL(service.getAlbumName(), - ALBUM_IMAGE, service)); + Bitmap bitmap = service.getAlbumBitmap(); if (bitmap != null) { views.setViewVisibility(R.id.four_by_one_albumart, View.VISIBLE); views.setViewVisibility(R.id.four_by_one_control_prev, View.GONE); diff --git a/src/com/andrew/apollo/app/widgets/AppWidget42.java b/src/com/andrew/apollo/app/widgets/AppWidget42.java index 61edeec..b5f486a 100644 --- a/src/com/andrew/apollo/app/widgets/AppWidget42.java +++ b/src/com/andrew/apollo/app/widgets/AppWidget42.java @@ -30,10 +30,6 @@ import com.andrew.apollo.R; import com.andrew.apollo.activities.AudioPlayerHolder; import com.andrew.apollo.activities.MusicLibrary; import com.andrew.apollo.service.ApolloService; -import com.andrew.apollo.utils.ApolloUtils; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ALBUM_IMAGE; /** * Simple widget to show currently playing album art along with play/pause and @@ -128,9 +124,7 @@ public class AppWidget42 extends AppWidgetProvider { views.setTextViewText(R.id.four_by_two_trackname, trackName); // Set album art - AQuery aq = new AQuery(service); - Bitmap bitmap = aq.getCachedImage(ApolloUtils.getImageURL(service.getAlbumName(), - ALBUM_IMAGE, service)); + Bitmap bitmap = service.getAlbumBitmap(); if (bitmap != null) { views.setViewVisibility(R.id.four_by_two_albumart, View.VISIBLE); views.setImageViewBitmap(R.id.four_by_two_albumart, bitmap); diff --git a/src/com/andrew/apollo/grid/fragments/AlbumsFragment.java b/src/com/andrew/apollo/grid/fragments/AlbumsFragment.java index 1cc7d78..8b12cd3 100644 --- a/src/com/andrew/apollo/grid/fragments/AlbumsFragment.java +++ b/src/com/andrew/apollo/grid/fragments/AlbumsFragment.java @@ -10,7 +10,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.net.Uri; -import android.os.AsyncTask; import android.os.Bundle; import android.provider.BaseColumns; import android.provider.MediaStore.Audio; @@ -19,34 +18,21 @@ import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; -import android.view.ContextMenu; +import android.view.*; import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView; - import com.andrew.apollo.R; import com.andrew.apollo.activities.TracksBrowser; import com.andrew.apollo.adapters.AlbumAdapter; import com.andrew.apollo.service.ApolloService; -import com.andrew.apollo.tasks.GetCachedImages; -import com.andrew.apollo.tasks.LastfmGetAlbumImages; -import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.ALBUM_KEY; -import static com.andrew.apollo.Constants.ARTIST_KEY; -import static com.andrew.apollo.Constants.INTENT_ADD_TO_PLAYLIST; -import static com.andrew.apollo.Constants.INTENT_PLAYLIST_LIST; -import static com.andrew.apollo.Constants.MIME_TYPE; -import static com.andrew.apollo.Constants.UP_STARTS_ALBUM_ACTIVITY; +import static com.andrew.apollo.Constants.*; /** * @author Andrew Neal @@ -253,14 +239,7 @@ public class AlbumsFragment extends Fragment implements LoaderCallbacks, // Artist image ImageView headerImage = (ImageView)header.findViewById(R.id.header_image); - // Only download images we don't already have - if (ApolloUtils.getImageURL(albumName, ALBUM_IMAGE, getActivity()) == null) - new LastfmGetAlbumImages(getActivity(), null, 0).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName, albumName); - - // Get and set cached image - new GetCachedImages(getActivity(), 1, headerImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, albumName); + ImageUtils.setAlbumImage(headerImage, artistName, albumName); // Set artist name TextView headerText = (TextView)header.findViewById(R.id.header_text); diff --git a/src/com/andrew/apollo/grid/fragments/ArtistsFragment.java b/src/com/andrew/apollo/grid/fragments/ArtistsFragment.java index f35290b..4c0a09d 100644 --- a/src/com/andrew/apollo/grid/fragments/ArtistsFragment.java +++ b/src/com/andrew/apollo/grid/fragments/ArtistsFragment.java @@ -10,7 +10,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.net.Uri; -import android.os.AsyncTask; import android.os.Bundle; import android.provider.BaseColumns; import android.provider.MediaStore.Audio; @@ -19,33 +18,22 @@ import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; -import android.view.ContextMenu; +import android.view.*; import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView; - import com.andrew.apollo.R; import com.andrew.apollo.activities.TracksBrowser; import com.andrew.apollo.adapters.ArtistAdapter; import com.andrew.apollo.service.ApolloService; -import com.andrew.apollo.tasks.GetCachedImages; -import com.andrew.apollo.tasks.LastfmGetArtistImagesOriginal; import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; -import static com.andrew.apollo.Constants.ARTIST_ID; -import static com.andrew.apollo.Constants.ARTIST_IMAGE_ORIGINAL; -import static com.andrew.apollo.Constants.ARTIST_KEY; -import static com.andrew.apollo.Constants.INTENT_ADD_TO_PLAYLIST; -import static com.andrew.apollo.Constants.INTENT_PLAYLIST_LIST; -import static com.andrew.apollo.Constants.MIME_TYPE; +import static com.andrew.apollo.Constants.*; /** * @author Andrew Neal @@ -253,21 +241,7 @@ public class ArtistsFragment extends Fragment implements LoaderCallbacks // Artist image final ImageView mHanderImage = (ImageView)header.findViewById(R.id.header_image); - - mHanderImage.post(new Runnable() { - - @Override - public void run() { - // Only download images we don't already have - if (ApolloUtils.getImageURL(artistName, ARTIST_IMAGE_ORIGINAL, getActivity()) == null) - new LastfmGetArtistImagesOriginal(getActivity(), mHanderImage) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, artistName); - - // Get and set cached image - new GetCachedImages(getActivity(), 0, mHanderImage).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, artistName); - } - }); + ImageUtils.setArtistImage(mHanderImage, artistName); // Set artist name TextView headerText = (TextView)header.findViewById(R.id.header_text); diff --git a/src/com/andrew/apollo/list/fragments/ArtistAlbumsFragment.java b/src/com/andrew/apollo/list/fragments/ArtistAlbumsFragment.java index c4d4b4d..f86e422 100644 --- a/src/com/andrew/apollo/list/fragments/ArtistAlbumsFragment.java +++ b/src/com/andrew/apollo/list/fragments/ArtistAlbumsFragment.java @@ -10,7 +10,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.net.Uri; -import android.os.AsyncTask; import android.os.Bundle; import android.provider.BaseColumns; import android.provider.MediaStore.Audio; @@ -19,34 +18,22 @@ import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; -import android.view.ContextMenu; +import android.view.*; import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; - import com.andrew.apollo.R; import com.andrew.apollo.activities.TracksBrowser; import com.andrew.apollo.adapters.ArtistAlbumAdapter; import com.andrew.apollo.service.ApolloService; -import com.andrew.apollo.tasks.GetCachedImages; -import com.andrew.apollo.tasks.LastfmGetAlbumImages; import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.ALBUM_KEY; -import static com.andrew.apollo.Constants.ARTIST_KEY; -import static com.andrew.apollo.Constants.EXTERNAL; -import static com.andrew.apollo.Constants.INTENT_ADD_TO_PLAYLIST; -import static com.andrew.apollo.Constants.INTENT_PLAYLIST_LIST; -import static com.andrew.apollo.Constants.MIME_TYPE; +import static com.andrew.apollo.Constants.*; /** * @author Andrew Neal @@ -262,15 +249,7 @@ public class ArtistAlbumsFragment extends Fragment implements LoaderCallbacks { - - private final WeakReference imageViewReference; - - private final ImageView mImageView; - - private WeakReference bitmapReference; - - public BitmapFromURL(ImageView iv) { - imageViewReference = new WeakReference(iv); - mImageView = imageViewReference.get(); - } - - @Override - protected Bitmap doInBackground(String... params) { - bitmapReference = new WeakReference(ApolloUtils.getBitmapFromURL(params[0])); - return bitmapReference.get(); - } - - @Override - protected void onPostExecute(Bitmap result) { - if (result != null && mImageView != null) - ApolloUtils.runnableBackground(mImageView, result); - super.onPostExecute(result); - } -} diff --git a/src/com/andrew/apollo/tasks/FetchAlbumImages.java b/src/com/andrew/apollo/tasks/FetchAlbumImages.java deleted file mode 100644 index 7bd8b10..0000000 --- a/src/com/andrew/apollo/tasks/FetchAlbumImages.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * - */ - -package com.andrew.apollo.tasks; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; - -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.AsyncTask; -import android.provider.BaseColumns; -import android.provider.MediaStore.Audio; -import android.provider.MediaStore.Audio.AlbumColumns; - -import com.andrew.apollo.utils.ApolloUtils; - -import static com.andrew.apollo.Constants.ALBUM_IMAGE; - -/** - * @author Andrew Neal - * @returns A String[] of all the artists and albums on a device in default - * album order that are then fed into the Last.fm API - */ -public class FetchAlbumImages { - - private final Context mContext; - - private final WeakReference contextReference; - - private final int choice; - - public FetchAlbumImages(Context context, int opt) { - contextReference = new WeakReference(context); - mContext = contextReference.get(); - choice = opt; - } - - /** - * @return album names in default album sort order - */ - public String[] getAlbumArtists() { - String[] projection = new String[] { - BaseColumns._ID, AlbumColumns.ARTIST - }; - String sortOrder = Audio.Albums.DEFAULT_SORT_ORDER; - Uri uri = Audio.Albums.EXTERNAL_CONTENT_URI; - Cursor c = mContext.getContentResolver().query(uri, projection, null, null, sortOrder); - ArrayList artistIds = new ArrayList(); - if (c != null) { - int count = c.getCount(); - if (count > 0) { - final int ARTIST_IDX = c.getColumnIndex(AlbumColumns.ARTIST); - for (int i = 0; i < count; i++) { - c.moveToPosition(i); - artistIds.add(c.getString(ARTIST_IDX)); - } - } - c.close(); - c = null; - } - return artistIds.toArray(new String[artistIds.size()]); - } - - /** - * @author Andrew Neal - * @returns artist names in default album sort order that are then fed into - * the Last.fm API along with @getAlbumArtists() - */ - public class getAlbums extends AsyncTask { - - @Override - protected String[] doInBackground(Void... params) { - String[] projection = new String[] { - BaseColumns._ID, AlbumColumns.ALBUM - }; - String sortOrder = Audio.Albums.DEFAULT_SORT_ORDER; - Uri uri = Audio.Albums.EXTERNAL_CONTENT_URI; - Cursor c = mContext.getContentResolver().query(uri, projection, null, null, sortOrder); - ArrayList artistIds = new ArrayList(); - if (c != null) { - int count = c.getCount(); - if (count > 0) { - final int ARTIST_IDX = c.getColumnIndex(AlbumColumns.ALBUM); - for (int i = 0; i < count; i++) { - c.moveToPosition(i); - artistIds.add(c.getString(ARTIST_IDX)); - } - } - c.close(); - c = null; - } - return artistIds.toArray(new String[artistIds.size()]); - } - - @Override - protected void onPostExecute(String[] result) { - for (int i = 0; i < result.length; i++) { - // Only download images we don't already have - if (choice == 0 && result != null) { - if (ApolloUtils.getImageURL(result[i], ALBUM_IMAGE, mContext) == null) { - new LastfmGetAlbumImages(mContext, null, 0).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, getAlbumArtists()[i], result[i]); - } - } else if (choice == 1 && result != null) { - // Unless the user wants to grab new images - new LastfmGetAlbumImages(mContext, null, 0).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, getAlbumArtists()[i], result[i]); - } - } - super.onPostExecute(result); - } - } - - /** - * Fetch album art - */ - public void runTask() { - new getAlbums().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); - } -} diff --git a/src/com/andrew/apollo/tasks/FetchArtistImages.java b/src/com/andrew/apollo/tasks/FetchArtistImages.java deleted file mode 100644 index dcd03fa..0000000 --- a/src/com/andrew/apollo/tasks/FetchArtistImages.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * - */ - -package com.andrew.apollo.tasks; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; - -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.AsyncTask; -import android.provider.BaseColumns; -import android.provider.MediaStore.Audio; -import android.provider.MediaStore.Audio.ArtistColumns; - -import com.andrew.apollo.utils.ApolloUtils; - -import static com.andrew.apollo.Constants.ARTIST_IMAGE; - -/** - * @author Andrew Neal - * @returns A String[] of all the artists on a device in default artist order - * that are then fed into the Last.fm API - */ -public class FetchArtistImages extends AsyncTask { - - private final WeakReference contextReference; - - private final int choice; - - public FetchArtistImages(Context context, int opt) { - contextReference = new WeakReference(context); - choice = opt; - } - - @Override - protected String[] doInBackground(Void... params) { - String[] projection = new String[] { - BaseColumns._ID, ArtistColumns.ARTIST - }; - String sortOrder = Audio.Artists.DEFAULT_SORT_ORDER; - Uri uri = Audio.Artists.EXTERNAL_CONTENT_URI; - Cursor c = contextReference.get().getContentResolver() - .query(uri, projection, null, null, sortOrder); - ArrayList artistIds = new ArrayList(); - if (c != null) { - int count = c.getCount(); - if (count > 0) { - final int ARTIST_IDX = c.getColumnIndex(ArtistColumns.ARTIST); - for (int i = 0; i < count; i++) { - c.moveToPosition(i); - artistIds.add(c.getString(ARTIST_IDX)); - } - } - c.close(); - c = null; - } - return artistIds.toArray(new String[artistIds.size()]); - } - - @Override - protected void onPostExecute(String[] result) { - for (int i = 0; i < result.length; i++) { - // Only download images we don't already have - if (choice == 0 && result != null) { - if (ApolloUtils.getImageURL(result[i], ARTIST_IMAGE, contextReference.get()) == null) { - new LastfmGetArtistImages(contextReference.get()).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, result[i]); - } - } else if (choice == 1 && result != null) { - // Unless the user wants to grab new images - new LastfmGetArtistImages(contextReference.get()).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, result[i]); - } - } - super.onPostExecute(result); - } - - /** - * Fetch artist images - */ - public void runTask() { - executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); - } -} diff --git a/src/com/andrew/apollo/tasks/GetAlbumImageTask.java b/src/com/andrew/apollo/tasks/GetAlbumImageTask.java new file mode 100644 index 0000000..dfc2118 --- /dev/null +++ b/src/com/andrew/apollo/tasks/GetAlbumImageTask.java @@ -0,0 +1,56 @@ +package com.andrew.apollo.tasks; + +import android.content.Context; +import android.graphics.Bitmap; +import android.util.Log; +import com.andrew.apollo.lastfm.api.Album; +import com.andrew.apollo.lastfm.api.ImageSize; +import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; + +import java.io.File; + +import static com.andrew.apollo.Constants.LASTFM_API_KEY; + +public class GetAlbumImageTask extends GetBitmapTask { + + private final String TAG = "GetArtistImageTask"; + + private String mArtist; + + private String mAlbum; + + public GetAlbumImageTask(String artist, String album, OnBitmapReadyListener listener, String tag, Context context) { + super(listener, tag, context); + mArtist = artist; + mAlbum = album; + } + + @Override + protected File getFile(Context context, String extension) { + String albumPart = ApolloUtils.escapeForFileSystem(mAlbum); + String artistPart = ApolloUtils.escapeForFileSystem(mArtist); + + if (albumPart == null || artistPart == null) { + Log.e(TAG, "Can't create file name for: " + mAlbum + " " + mArtist); + return null; + } + + return new File(context.getExternalFilesDir(null), artistPart + " - " + albumPart + extension); + } + + @Override + protected String getImageUrl() { + try { + Album album = Album.getInfo(mArtist, this.mAlbum, LASTFM_API_KEY); + if (album == null) { + if (ImageUtils.DEBUG) Log.w(TAG, "Album not found: " + mArtist + " - " + this.mAlbum); + return null; + } + return album.getImageURL(ImageSize.LARGE); //TODO: ensure that there is an image available in the specified size + } catch (Exception e) { + if (ImageUtils.DEBUG) Log.w(TAG, "Error when retrieving album image url", e); + return null; + } + } +} diff --git a/src/com/andrew/apollo/tasks/GetArtistImageTask.java b/src/com/andrew/apollo/tasks/GetArtistImageTask.java new file mode 100644 index 0000000..ee785da --- /dev/null +++ b/src/com/andrew/apollo/tasks/GetArtistImageTask.java @@ -0,0 +1,55 @@ +package com.andrew.apollo.tasks; + +import android.content.Context; +import android.graphics.Bitmap; +import android.util.Log; +import com.andrew.apollo.lastfm.api.Artist; +import com.andrew.apollo.lastfm.api.Image; +import com.andrew.apollo.lastfm.api.ImageSize; +import com.andrew.apollo.lastfm.api.PaginatedResult; +import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; + +import java.io.File; +import java.util.Iterator; + +import static com.andrew.apollo.Constants.LASTFM_API_KEY; + +public class GetArtistImageTask extends GetBitmapTask { + + private final String TAG = "GetArtistImageTask"; + + private String mArtist; + + public GetArtistImageTask(String artist, OnBitmapReadyListener listener, String tag, Context context) { + super(listener, tag, context); + mArtist = artist; + } + + @Override + protected File getFile(Context context, String extension) { + String fileName = ApolloUtils.escapeForFileSystem(mArtist); + if (fileName == null) { + Log.e(TAG, "Can't create file name for: " + mArtist); + return null; + } + return new File(context.getExternalFilesDir(null), fileName + extension); + } + + @Override + protected String getImageUrl() { + try { + PaginatedResult images = Artist.getImages(this.mArtist, 2, 1, LASTFM_API_KEY); + Iterator iterator = images.getPageResults().iterator(); + if (!iterator.hasNext()) { + if (ImageUtils.DEBUG) Log.w(TAG, "Error when retrieving artist image url for \"" + mArtist + "\" - empty result"); + return null; + } + Image image = iterator.next(); + return image.getImageURL(ImageSize.LARGESQUARE); //TODO: ensure that there is an image available in the specified size + } catch (Exception e) { + if (ImageUtils.DEBUG) Log.w(TAG, "Error when retrieving artist image url for \"" + mArtist + "\"", e); + return null; + } + } +} diff --git a/src/com/andrew/apollo/tasks/GetBitmapTask.java b/src/com/andrew/apollo/tasks/GetBitmapTask.java new file mode 100644 index 0000000..400fb08 --- /dev/null +++ b/src/com/andrew/apollo/tasks/GetBitmapTask.java @@ -0,0 +1,123 @@ +package com.andrew.apollo.tasks; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.util.Log; +import com.andrew.apollo.utils.ApolloUtils; +import com.andrew.apollo.utils.ImageUtils; + +import java.io.File; +import java.lang.ref.WeakReference; + +public abstract class GetBitmapTask extends AsyncTask { + + private static final String TAG = "GetBitmapTask"; + + private static final String EXTENSION_JPG = ".jpg"; + private static final String EXTENSION_PNG = ".png"; + private static final String EXTENSION_GIF = ".gif"; + + private static final String[] IMAGE_EXTENSIONS = new String[]{EXTENSION_JPG, EXTENSION_PNG, EXTENSION_GIF}; + + private WeakReference mListenerReference; + + private WeakReference mContextReference; + + private String mTag; + + public GetBitmapTask(OnBitmapReadyListener listener, String tag, Context context) { + mListenerReference = new WeakReference(listener); + mContextReference = new WeakReference(context); + mTag = tag; + } + + @Override + protected Bitmap doInBackground(String... ignored) { + Context context = mContextReference.get(); + if (context == null) { + return null; + } + + if (ImageUtils.DEBUG) Log.v(TAG, "Get image for: " + mTag); + + File file = findCachedFile(context); + + if (file == null) { + file = downloadImage(context); + } + + if (file == null) { + return null; + } + + Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); + + if (bitmap == null) { + if (ImageUtils.DEBUG) Log.w(TAG, "Error decoding bitmap: " + file.getAbsolutePath()); + return null; + } + + if (ImageUtils.DEBUG) Log.d(TAG, "Bitmap decoded: " + mTag + " size:" + bitmap.getWidth() + "x" + bitmap.getHeight()); + return bitmap; + } + + protected abstract String getImageUrl(); + + protected abstract File getFile(Context context, String extension); + + private File findCachedFile(Context context) { + for (String extension : IMAGE_EXTENSIONS) { + File file = getFile(context, extension); + if (file == null) { + return null; + } + if (file.exists()) { + if (ImageUtils.DEBUG) Log.d(TAG, "Cached file found: " + file.getAbsolutePath()); + return file; + } + } + return null; + } + + private File downloadImage(Context context) { + String url = getImageUrl(); + if (url == null || url.isEmpty()) { + if (ImageUtils.DEBUG) Log.w(TAG, "No URL received for: " + mTag); + return null; + } + File file = getFile(context, getExtension(url)); + if (ImageUtils.DEBUG) Log.v(TAG, "Downloading " + url + " to " + file.getAbsolutePath()); + ApolloUtils.downloadFile(url, file); + if (file.exists()) { + if (ImageUtils.DEBUG) Log.v(TAG, "Image downloaded: " + mTag); + return file; + } + if (ImageUtils.DEBUG) Log.w(TAG, "Error downloading a " + url + " to " + file.getAbsolutePath()); + return null; + } + + protected String getExtension(String url) { + for (String extension : IMAGE_EXTENSIONS) { + if (url.endsWith(extension)) + return extension; + } + return EXTENSION_JPG; + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + super.onPostExecute(bitmap); + OnBitmapReadyListener listener = mListenerReference.get(); + if (bitmap != null) { + if (listener != null) { + listener.bitmapReady(bitmap, mTag); + } + } + } + + public static interface OnBitmapReadyListener { + public void bitmapReady(Bitmap bitmap, String tag); + } +} diff --git a/src/com/andrew/apollo/tasks/GetCachedImages.java b/src/com/andrew/apollo/tasks/GetCachedImages.java deleted file mode 100644 index 7bd2b46..0000000 --- a/src/com/andrew/apollo/tasks/GetCachedImages.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * - */ - -package com.andrew.apollo.tasks; - -import java.lang.ref.WeakReference; - -import android.content.Context; -import android.graphics.Bitmap; -import android.os.AsyncTask; -import android.widget.ImageView; - -import com.andrew.apollo.R; -import com.andrew.apollo.utils.ApolloUtils; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.ARTIST_IMAGE_ORIGINAL; - -/** - * @author Andrew Neal Returns a cached image for @TracksBrowser - */ -public class GetCachedImages extends AsyncTask { - - private final Context mContext; - - private final int choice; - - private final WeakReference imageViewReference; - - private final AQuery aquery; - - private final ImageView mImageView; - - private String url; - - private WeakReference bitmapReference; - - private final WeakReference contextReference; - - public GetCachedImages(Context c, int opt, ImageView iv) { - contextReference = new WeakReference(c); - mContext = contextReference.get(); - choice = opt; - imageViewReference = new WeakReference(iv); - mImageView = imageViewReference.get(); - - // AQuery - aquery = new AQuery(mContext); - } - - @Override - protected Bitmap doInBackground(String... args) { - if (choice == 0) - url = ApolloUtils.getImageURL(args[0], ARTIST_IMAGE_ORIGINAL, mContext); - if (choice == 1) - url = ApolloUtils.getImageURL(args[0], ALBUM_IMAGE, mContext); - bitmapReference = new WeakReference(aquery.getCachedImage(url, 300)); - return bitmapReference.get(); - } - - @Override - protected void onPostExecute(Bitmap result) { - if (imageViewReference != null && result != null) { - ApolloUtils.runnableBackground(mImageView, result); - } else { - result = aquery.getCachedImage(R.drawable.promo); - ApolloUtils.runnableBackground(mImageView, result); - } - super.onPostExecute(result); - } -} diff --git a/src/com/andrew/apollo/tasks/LastfmGetAlbumImages.java b/src/com/andrew/apollo/tasks/LastfmGetAlbumImages.java deleted file mode 100644 index ae8d74a..0000000 --- a/src/com/andrew/apollo/tasks/LastfmGetAlbumImages.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * - */ - -package com.andrew.apollo.tasks; - -import java.lang.ref.WeakReference; - -import android.app.Activity; -import android.content.Context; -import android.os.AsyncTask; -import android.widget.ImageView; - -import com.andrew.apollo.lastfm.api.Album; -import com.andrew.apollo.lastfm.api.ImageSize; -import com.andrew.apollo.utils.ApolloUtils; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.LASTFM_API_KEY; - -/** - * @author Andrew Neal - * @returns A convenient image size that's perfect for a GridView. - */ -public class LastfmGetAlbumImages extends AsyncTask { - - // URL to cache - private String url = null; - - // AQuery - private final AQuery aq; - - private final WeakReference contextReference; - - private final WeakReference imageviewReference; - - private final ImageView mImageView; - - private final int choice; - - private Album album; - - public LastfmGetAlbumImages(Context context, ImageView iv, int opt) { - contextReference = new WeakReference(context); - imageviewReference = new WeakReference(iv); - mImageView = imageviewReference.get(); - choice = opt; - - // Initiate AQuery - aq = new AQuery((Activity)contextReference.get(), iv); - } - - @Override - protected String doInBackground(String... name) { - if (ApolloUtils.isOnline(contextReference.get()) && name[0] != null && name[1] != null) { - try { - album = Album.getInfo(name[0], name[1], LASTFM_API_KEY); - url = album.getImageURL(ImageSize.LARGE); - aq.cache(url, 0); - ApolloUtils.setImageURL(name[1], url, ALBUM_IMAGE, contextReference.get()); - return url; - } catch (Exception e) { - return null; - } - } else { - url = ApolloUtils.getImageURL(name[1], ALBUM_IMAGE, contextReference.get()); - } - return url; - } - - @Override - protected void onPostExecute(String result) { - if (result != null && mImageView != null && choice == 1) - new BitmapFromURL(mImageView).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, result); - super.onPostExecute(result); - } -} diff --git a/src/com/andrew/apollo/tasks/LastfmGetArtistImages.java b/src/com/andrew/apollo/tasks/LastfmGetArtistImages.java deleted file mode 100644 index 2110fe5..0000000 --- a/src/com/andrew/apollo/tasks/LastfmGetArtistImages.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * - */ - -package com.andrew.apollo.tasks; - -import java.lang.ref.WeakReference; -import java.util.Iterator; - -import android.content.Context; -import android.os.AsyncTask; - -import com.andrew.apollo.lastfm.api.Artist; -import com.andrew.apollo.lastfm.api.Image; -import com.andrew.apollo.lastfm.api.ImageSize; -import com.andrew.apollo.lastfm.api.PaginatedResult; -import com.andrew.apollo.utils.ApolloUtils; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ARTIST_IMAGE; -import static com.andrew.apollo.Constants.LASTFM_API_KEY; - -/** - * @author Andrew Neal - * @returns A convenient image size that's perfect for a GridView. - */ -public class LastfmGetArtistImages extends AsyncTask { - - // URL to cache - private String url = null; - - private PaginatedResult artist; - - // AQuery - private final AQuery aq; - - private final WeakReference contextReference; - - public LastfmGetArtistImages(Context context) { - contextReference = new WeakReference(context); - - // Initiate AQuery - aq = new AQuery(contextReference.get()); - } - - @Override - protected String doInBackground(String... artistname) { - if (ApolloUtils.isOnline(contextReference.get()) && artistname[0] != null) { - try { - artist = Artist.getImages(artistname[0], 1, 1, LASTFM_API_KEY); - Iterator iterator = artist.getPageResults().iterator(); - while (iterator.hasNext()) { - Image mTemp = iterator.next(); - url = mTemp.getImageURL(ImageSize.LARGESQUARE); - } - aq.cache(url, 0); - ApolloUtils.setImageURL(artistname[0], url, ARTIST_IMAGE, contextReference.get()); - return url; - } catch (Exception e) { - return null; - } - } else { - url = ApolloUtils.getImageURL(artistname[0], ARTIST_IMAGE, contextReference.get()); - } - return url; - } -} diff --git a/src/com/andrew/apollo/tasks/LastfmGetArtistImagesOriginal.java b/src/com/andrew/apollo/tasks/LastfmGetArtistImagesOriginal.java deleted file mode 100644 index 8e38af4..0000000 --- a/src/com/andrew/apollo/tasks/LastfmGetArtistImagesOriginal.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * - */ - -package com.andrew.apollo.tasks; - -import java.lang.ref.WeakReference; -import java.util.Iterator; - -import android.content.Context; -import android.os.AsyncTask; -import android.widget.ImageView; - -import com.andrew.apollo.lastfm.api.Artist; -import com.andrew.apollo.lastfm.api.Image; -import com.andrew.apollo.lastfm.api.ImageSize; -import com.andrew.apollo.lastfm.api.PaginatedResult; -import com.andrew.apollo.utils.ApolloUtils; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ARTIST_IMAGE_ORIGINAL; -import static com.andrew.apollo.Constants.LASTFM_API_KEY; - -/** - * @author Andrew Neal - * @Note This is used to display artist images in @TracksBrowser - */ -public class LastfmGetArtistImagesOriginal extends AsyncTask { - - // URL to cache - private String url = null; - - private final ImageView mImageView; - - private final WeakReference imageviewReference; - - // AQuery - private final AQuery aq; - - // Context - private final Context mContext; - - private final WeakReference contextReference; - - public LastfmGetArtistImagesOriginal(Context context, ImageView iv) { - contextReference = new WeakReference(context); - mContext = contextReference.get(); - imageviewReference = new WeakReference(iv); - mImageView = imageviewReference.get(); - - // Initiate AQuery - aq = new AQuery(mContext); - } - - @Override - protected String doInBackground(String... artistname) { - if (ApolloUtils.isOnline(mContext)) { - PaginatedResult artist = Artist.getImages(artistname[0], 1, 1, LASTFM_API_KEY); - Iterator iterator = artist.getPageResults().iterator(); - while (iterator.hasNext()) { - Image mTemp = iterator.next(); - url = mTemp.getImageURL(ImageSize.ORIGINAL); - } - aq.cache(url, 0); - ApolloUtils.setImageURL(artistname[0], url, ARTIST_IMAGE_ORIGINAL, mContext); - return url; - } else { - url = ApolloUtils.getImageURL(artistname[0], ARTIST_IMAGE_ORIGINAL, mContext); - } - return url; - } - - @Override - protected void onPostExecute(String result) { - if (result != null && mImageView != null) { - new BitmapFromURL(mImageView).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, result); - } - super.onPostExecute(result); - } -} diff --git a/src/com/andrew/apollo/tasks/ViewHolderQueueTask.java b/src/com/andrew/apollo/tasks/ViewHolderQueueTask.java deleted file mode 100644 index 0357258..0000000 --- a/src/com/andrew/apollo/tasks/ViewHolderQueueTask.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * - */ - -package com.andrew.apollo.tasks; - -import java.lang.ref.WeakReference; - -import android.content.Context; -import android.graphics.Bitmap; -import android.os.AsyncTask; -import android.widget.ImageView; - -import com.andrew.apollo.utils.ApolloUtils; -import com.andrew.apollo.views.ViewHolderQueue; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.ARTIST_IMAGE; - -/** - * @author Andrew Neal - */ -public class ViewHolderQueueTask extends AsyncTask { - - private final ViewHolderQueue mViewHolderQueue; - - private final WeakReference imageViewReference; - - private final Context mContext; - - private final int mPosition; - - private final int choice; - - private final int holderChoice; - - private final AQuery aquery; - - private final ImageView mImageView; - - private String url; - - private WeakReference bitmapReference; - - private final WeakReference contextReference; - - public ViewHolderQueueTask(ViewHolderQueue vh, int position, Context c, int opt, int holderOpt, - ImageView iv) { - mViewHolderQueue = vh; - mPosition = position; - contextReference = new WeakReference(c); - mContext = contextReference.get(); - choice = opt; - holderChoice = holderOpt; - imageViewReference = new WeakReference(iv); - mImageView = imageViewReference.get(); - - // AQuery - aquery = new AQuery(mContext); - } - - @Override - protected Bitmap doInBackground(String... args) { - if (choice == 0) - url = ApolloUtils.getImageURL(args[0], ARTIST_IMAGE, mContext); - if (choice == 1) - url = ApolloUtils.getImageURL(args[0], ALBUM_IMAGE, mContext); - bitmapReference = new WeakReference(aquery.getCachedImage(url)); - return bitmapReference.get(); - } - - @Override - protected void onPostExecute(Bitmap result) { - if (imageViewReference != null && holderChoice == 0 - && mViewHolderQueue.position == mPosition && mViewHolderQueue != null) - aquery.id(mImageView).image(result); - if (imageViewReference != null && holderChoice == 1 - && mViewHolderQueue.position == mPosition && mViewHolderQueue != null) - aquery.id(mImageView).image(result); - super.onPostExecute(result); - } -} diff --git a/src/com/andrew/apollo/tasks/ViewHolderTask.java b/src/com/andrew/apollo/tasks/ViewHolderTask.java deleted file mode 100644 index 5468fc2..0000000 --- a/src/com/andrew/apollo/tasks/ViewHolderTask.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * - */ - -package com.andrew.apollo.tasks; - -import java.lang.ref.WeakReference; - -import android.content.Context; -import android.graphics.Bitmap; -import android.os.AsyncTask; -import android.widget.ImageView; - -import com.andrew.apollo.R; -import com.andrew.apollo.utils.ApolloUtils; -import com.andrew.apollo.views.ViewHolderGrid; -import com.andrew.apollo.views.ViewHolderList; -import com.androidquery.AQuery; - -import static com.andrew.apollo.Constants.ALBUM_IMAGE; -import static com.andrew.apollo.Constants.ARTIST_IMAGE; - -/** - * @author Andrew Neal - */ -public class ViewHolderTask extends AsyncTask { - - private final ViewHolderList mViewHolderList; - - private final ViewHolderGrid mViewHolderGrid; - - private final WeakReference imageViewReference; - - private final Context mContext; - - private final int mPosition; - - private final int choice; - - private final int holderChoice; - - private final AQuery aquery; - - private final ImageView mImageView; - - private final int albumart; - - private final WeakReference contextReference; - - private String url; - - private WeakReference bitmapReference; - - public ViewHolderTask(ViewHolderList vh, ViewHolderGrid vhg, int position, Context c, int opt, - int holderOpt, ImageView iv) { - mViewHolderList = vh; - mViewHolderGrid = vhg; - mPosition = position; - contextReference = new WeakReference(c); - mContext = contextReference.get(); - choice = opt; - holderChoice = holderOpt; - imageViewReference = new WeakReference(iv); - mImageView = imageViewReference.get(); - aquery = new AQuery(mContext); - - albumart = mContext.getResources().getInteger(R.integer.listview_album_art); - } - - @Override - protected Bitmap doInBackground(String... args) { - if (choice == 0) - url = ApolloUtils.getImageURL(args[0], ARTIST_IMAGE, mContext); - if (choice == 1) - url = ApolloUtils.getImageURL(args[0], ALBUM_IMAGE, mContext); - bitmapReference = new WeakReference(aquery.getCachedImage(url)); - if (holderChoice == 0) { - return ApolloUtils.getResizedBitmap(bitmapReference.get(), albumart, albumart); - } else if (holderChoice == 1) { - return bitmapReference.get(); - } - return null; - } - - @Override - protected void onPostExecute(Bitmap result) { - if (result != null && imageViewReference != null && holderChoice == 0 - && mViewHolderList.position == mPosition && mViewHolderList != null) - mImageView.setImageBitmap(result); - if (result != null && imageViewReference != null && holderChoice == 1 - && mViewHolderGrid.position == mPosition && mViewHolderGrid != null) - mImageView.setImageBitmap(result); - super.onPostExecute(result); - } -} diff --git a/src/com/andrew/apollo/ui/widgets/BottomActionBar.java b/src/com/andrew/apollo/ui/widgets/BottomActionBar.java index 991c2fd..76c904c 100644 --- a/src/com/andrew/apollo/ui/widgets/BottomActionBar.java +++ b/src/com/andrew/apollo/ui/widgets/BottomActionBar.java @@ -7,7 +7,6 @@ package com.andrew.apollo.ui.widgets; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.os.AsyncTask; import android.os.RemoteException; import android.util.AttributeSet; import android.view.View; @@ -21,7 +20,7 @@ import android.widget.TextView; import com.andrew.apollo.R; import com.andrew.apollo.activities.AudioPlayerHolder; import com.andrew.apollo.activities.QuickQueue; -import com.andrew.apollo.tasks.GetCachedImages; +import com.andrew.apollo.utils.ImageUtils; import com.andrew.apollo.utils.MusicUtils; import com.andrew.apollo.utils.ThemeUtils; @@ -71,9 +70,7 @@ public class BottomActionBar extends LinearLayout implements OnClickListener, On // Album art ImageView mAlbumArt = (ImageView)bottomActionBar .findViewById(R.id.bottom_action_bar_album_art); - - new GetCachedImages(activity, 1, mAlbumArt).executeOnExecutor( - AsyncTask.THREAD_POOL_EXECUTOR, MusicUtils.getAlbumName()); + ImageUtils.setAlbumImage(mAlbumArt, MusicUtils.getArtistName(), MusicUtils.getAlbumName()); // Favorite image ImageButton mFavorite = (ImageButton)bottomActionBar diff --git a/src/com/andrew/apollo/ui/widgets/BottomActionBarItem.java b/src/com/andrew/apollo/ui/widgets/BottomActionBarItem.java index dd02758..00da5b0 100644 --- a/src/com/andrew/apollo/ui/widgets/BottomActionBarItem.java +++ b/src/com/andrew/apollo/ui/widgets/BottomActionBarItem.java @@ -25,8 +25,6 @@ import android.widget.Toast; import com.andrew.apollo.R; import com.andrew.apollo.preferences.SettingsHolder; -import com.andrew.apollo.tasks.FetchAlbumImages; -import com.andrew.apollo.tasks.FetchArtistImages; import com.andrew.apollo.utils.MusicUtils; /** @@ -122,16 +120,12 @@ public class BottomActionBarItem extends ImageButton implements OnLongClickListe * something went wrong the first time around. */ public void initArtistImages() { - FetchArtistImages getArtistImages = new FetchArtistImages(mContext, 1); - getArtistImages.runTask(); } /** * Manually fetch all of the album art. */ public void initAlbumImages() { - FetchAlbumImages getAlbumImages = new FetchAlbumImages(mContext, 1); - getAlbumImages.runTask(); } /** diff --git a/src/com/andrew/apollo/utils/ApolloUtils.java b/src/com/andrew/apollo/utils/ApolloUtils.java index d992cc5..92830c2 100644 --- a/src/com/andrew/apollo/utils/ApolloUtils.java +++ b/src/com/andrew/apollo/utils/ApolloUtils.java @@ -4,8 +4,7 @@ package com.andrew.apollo.utils; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.net.HttpURLConnection; import java.net.URL; @@ -121,32 +120,6 @@ public class ApolloUtils { } /** - * Sets cached image URLs - * - * @param artistName - * @param url - * @param key - * @param context - */ - public static void setImageURL(String name, String url, String key, Context context) { - SharedPreferences settings = context.getSharedPreferences(key, 0); - SharedPreferences.Editor editor = settings.edit(); - editor.putString(name, url); - editor.commit(); - } - - /** - * @param name - * @param key - * @param context - * @return cached image URLs - */ - public static String getImageURL(String name, String key, Context context) { - SharedPreferences settings = context.getSharedPreferences(key, 0); - return settings.getString(name, null); - } - - /** * @param context * @return if a Tablet is the device being used */ @@ -166,28 +139,6 @@ public class ApolloUtils { } /** - * @param bitmap - * @param newHeight - * @param newWidth - * @return a scaled Bitmap - */ - public static Bitmap getResizedBitmap(Bitmap bitmap, int newHeight, int newWidth) { - - if (bitmap == null) { - return null; - } - - int width = bitmap.getWidth(); - int height = bitmap.getHeight(); - float scaleWidth = ((float)newWidth) / width; - float scaleHeight = ((float)newHeight) / height; - Matrix matrix = new Matrix(); - matrix.postScale(scaleWidth, scaleHeight); - Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false); - return resizedBitmap; - } - - /** * Header used in the track browser * * @param fragment @@ -280,22 +231,55 @@ public class ApolloUtils { } /** - * @param src - * @return Bitmap fro URL + * Replace the characters not allowed in file names with underscore + * @param name + * @return */ - public static Bitmap getBitmapFromURL(String src) { + public static String escapeForFileSystem(String name) { + return name.replaceAll("[\\\\/:*?\"<>|]+", "_"); + } + + /** + * Static utility function to download the file from the specified URL to the specified file. + * @param urlString + * @param outFile + * @return true if the download succeeded false otherwise + */ + public static boolean downloadFile(String urlString, File outFile) { + HttpURLConnection urlConnection = null; + BufferedOutputStream out = null; + try { - URL url = new URL(src); - HttpURLConnection connection = (HttpURLConnection)url.openConnection(); - connection.setDoInput(true); - connection.connect(); - InputStream input = connection.getInputStream(); - Bitmap myBitmap = BitmapFactory.decodeStream(input); - return myBitmap; - } catch (IOException e) { - e.printStackTrace(); - return null; + File dir = outFile.getParentFile(); + if (!dir.exists() && !dir.mkdirs()) + return false; + + final URL url = new URL(urlString); + urlConnection = (HttpURLConnection) url.openConnection(); + final InputStream in = + new BufferedInputStream(urlConnection.getInputStream()); + out = new BufferedOutputStream(new FileOutputStream(outFile)); + + int b; + while ((b = in.read()) != -1) { + out.write(b); + } + + } catch (final IOException e) { + return false; + } finally { + if (urlConnection != null) { + urlConnection.disconnect(); + } + if (out != null) { + try { + out.close(); + } catch (final IOException e) { + return false; + } + } } + return true; } /** diff --git a/src/com/andrew/apollo/utils/ImageCache.java b/src/com/andrew/apollo/utils/ImageCache.java new file mode 100644 index 0000000..31ee9d4 --- /dev/null +++ b/src/com/andrew/apollo/utils/ImageCache.java @@ -0,0 +1,22 @@ +package com.andrew.apollo.utils; + +import android.graphics.Bitmap; +import android.util.LruCache; + +public class ImageCache extends LruCache { + + public final static int DEFAULT_SIZE = 1024 * 1024 * 16; + + public ImageCache(int maxSize) { + super(maxSize); + } + + /** + * Measure item size in bytes rather than units which is more practical for a bitmap + * cache + */ + @Override + protected int sizeOf(String key, Bitmap bitmap) { + return bitmap.getByteCount(); + } +} diff --git a/src/com/andrew/apollo/utils/ImageProvider.java b/src/com/andrew/apollo/utils/ImageProvider.java new file mode 100644 index 0000000..656043c --- /dev/null +++ b/src/com/andrew/apollo/utils/ImageProvider.java @@ -0,0 +1,112 @@ +package com.andrew.apollo.utils; + +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.TransitionDrawable; +import android.os.AsyncTask; +import android.widget.ImageView; +import com.andrew.apollo.R; +import com.andrew.apollo.tasks.GetAlbumImageTask; +import com.andrew.apollo.tasks.GetArtistImageTask; +import com.andrew.apollo.tasks.GetBitmapTask; + +import java.util.*; + +public class ImageProvider implements GetBitmapTask.OnBitmapReadyListener { + + private ImageCache memCache = new ImageCache(ImageCache.DEFAULT_SIZE); + + private Map> pendingImagesMap = new HashMap>(); + + private Set unavailable = new HashSet(); + + public ImageProvider() { + + } + + public void setArtistImage(ImageView imageView, String artist) { + String tag = getArtistTag(artist); + if (!setCachedBitmap(imageView, tag)) { + asyncLoad(tag, imageView, new GetArtistImageTask(artist, this, tag, imageView.getContext())); + } + } + + public void setAlbumImage(ImageView imageView, String artist, String album) { + String tag = getAlbumTag(artist, album); + if (!setCachedBitmap(imageView, tag)) { + asyncLoad(tag, imageView, new GetAlbumImageTask(artist, album, this, tag, imageView.getContext())); + } + } + + private boolean setCachedBitmap(ImageView imageView, String tag) { + if (unavailable.contains(tag)) { + handleBitmapUnavailable(imageView, tag); + return true; + } + Bitmap bitmap = memCache.get(tag); + if (bitmap == null) + return false; + imageView.setTag(tag); + imageView.setImageBitmap(bitmap); + return true; + } + + private void handleBitmapUnavailable(ImageView imageView, String tag) { + imageView.setTag(tag); + imageView.setImageDrawable(null); + } + + private void setLoadedBitmap(ImageView imageView, Bitmap bitmap, String tag) { + if (!tag.equals(imageView.getTag())) + return; + + final TransitionDrawable transition = new TransitionDrawable(new Drawable[]{ + new ColorDrawable(android.R.color.transparent), + new BitmapDrawable(imageView.getResources(), bitmap) + }); + + imageView.setImageDrawable(transition); + final int duration = imageView.getResources().getInteger(R.integer.image_fade_in_duration); + transition.startTransition(duration); + } + + private void asyncLoad(String tag, ImageView imageView, GetBitmapTask task) { + Set pendingImages = pendingImagesMap.get(tag); + if (pendingImages == null) { + pendingImages = Collections.newSetFromMap(new WeakHashMap()); // create weak set + pendingImagesMap.put(tag, pendingImages); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + pendingImages.add(imageView); + imageView.setTag(tag); + imageView.setImageDrawable(null); + } + + private String getArtistTag(String artist) { + return artist; + } + + private String getAlbumTag(String artist, String album) { + return artist + " - " + album; + } + + @Override + public void bitmapReady(Bitmap bitmap, String tag) { + if (bitmap == null) { + unavailable.add(tag); + } + else + { + memCache.put(tag, bitmap); + } + Set pendingImages = pendingImagesMap.get(tag); + if (pendingImages != null) { + pendingImagesMap.remove(tag); + for (ImageView imageView : pendingImages) { + setLoadedBitmap(imageView, bitmap, tag); + } + } + } +} diff --git a/src/com/andrew/apollo/utils/ImageUtils.java b/src/com/andrew/apollo/utils/ImageUtils.java new file mode 100644 index 0000000..bc81736 --- /dev/null +++ b/src/com/andrew/apollo/utils/ImageUtils.java @@ -0,0 +1,24 @@ +package com.andrew.apollo.utils; + +import android.widget.ImageView; + +public class ImageUtils { + + private static ImageProvider imageProvider; + + public static final boolean DEBUG = true; + + public static void setArtistImage(ImageView imageView, String artist) { + getImageProvider().setArtistImage(imageView, artist); + } + + public static void setAlbumImage(ImageView imageView, String artist, String album) { + getImageProvider().setAlbumImage(imageView, artist, album); + } + + private static ImageProvider getImageProvider() { + if (imageProvider == null) + imageProvider = new ImageProvider(); + return imageProvider; + } +} diff --git a/src/com/andrew/apollo/views/ViewHolderGrid.java b/src/com/andrew/apollo/views/ViewHolderGrid.java index cce2fc6..335e6b9 100644 --- a/src/com/andrew/apollo/views/ViewHolderGrid.java +++ b/src/com/andrew/apollo/views/ViewHolderGrid.java @@ -22,8 +22,6 @@ public class ViewHolderGrid { public final TextView mViewHolderLineTwo; - public int position; - public final LinearLayout mInfoHolder; public ViewHolderGrid(View view) { diff --git a/src/com/andrew/apollo/views/ViewHolderList.java b/src/com/andrew/apollo/views/ViewHolderList.java index 5ceb08a..444d7e8 100644 --- a/src/com/andrew/apollo/views/ViewHolderList.java +++ b/src/com/andrew/apollo/views/ViewHolderList.java @@ -24,8 +24,6 @@ public class ViewHolderList { public final TextView mViewHolderLineTwo; - public int position; - public final FrameLayout mQuickContext; public ViewHolderList(View view) { diff --git a/src/com/andrew/apollo/views/ViewHolderQueue.java b/src/com/andrew/apollo/views/ViewHolderQueue.java index f998553..54cde13 100644 --- a/src/com/andrew/apollo/views/ViewHolderQueue.java +++ b/src/com/andrew/apollo/views/ViewHolderQueue.java @@ -21,8 +21,6 @@ public class ViewHolderQueue { public final TextView mTrackName; - public int position; - public ViewHolderQueue(View view) { mArtistImage = (ImageView)view.findViewById(R.id.queue_artist_image); mAlbumArt = (ImageView)view.findViewById(R.id.queue_album_art); -- 2.11.0