diff --git a/app/build.gradle b/app/build.gradle index 38327316..2129df26 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -125,7 +125,6 @@ dependencies { compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' compile 'com.squareup.okhttp:okhttp:2.7.0' - compile 'com.github.kabouzeid:Android-Universal-Image-Loader:1.9.5' compile 'com.jakewharton:butterknife:7.0.1' compile 'org.solovyev.android.views:linear-layout-manager:0.5@aar' //noinspection GradleDynamicVersion diff --git a/app/src/main/java/com/kabouzeid/gramophone/App.java b/app/src/main/java/com/kabouzeid/gramophone/App.java index 5ad41ca9..79133741 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/App.java +++ b/app/src/main/java/com/kabouzeid/gramophone/App.java @@ -3,11 +3,6 @@ package com.kabouzeid.gramophone; import android.app.Application; import com.crashlytics.android.Crashlytics; -import com.kabouzeid.gramophone.imageloader.PhonographExecutor; -import com.kabouzeid.gramophone.imageloader.PhonographImageDownloader; -import com.nostra13.universalimageloader.core.ImageLoader; -import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; -import com.nostra13.universalimageloader.utils.L; import io.fabric.sdk.android.Fabric; @@ -24,12 +19,5 @@ public class App extends Application { super.onCreate(); if (!BuildConfig.DEBUG) Fabric.with(this, new Crashlytics()); - - ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this) - .imageDownloader(new PhonographImageDownloader(this)) - .taskExecutor(new PhonographExecutor()) - .build(); - ImageLoader.getInstance().init(config); - L.writeLogs(false); // turns off UILs annoying LogCat output } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/album/AlbumAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/album/AlbumAdapter.java index 123e1666..ca966afa 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/album/AlbumAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/album/AlbumAdapter.java @@ -1,5 +1,6 @@ package com.kabouzeid.gramophone.adapter.album; +import android.graphics.drawable.Drawable; import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -89,9 +90,6 @@ public class AlbumAdapter extends AbsMultiSelectAdapter implements MaterialCab.Callback { - private static final int FADE_IN_TIME = 500; - @Nullable private final CabHolder cabHolder; private MaterialCab cab; @@ -77,16 +74,12 @@ public class ArtistSongAdapter extends ArrayAdapter implements MaterialCab songTitle.setText(song.title); songInfo.setText(song.albumName); - ImageLoader.getInstance().displayImage( - MusicUtil.getSongImageLoaderString(song), - albumArt, - new DisplayImageOptions.Builder() - .cacheInMemory(true) - .showImageOnFail(R.drawable.default_album_art) - .resetViewBeforeLoading(true) - .displayer(new FadeInBitmapDisplayer(FADE_IN_TIME, true, true, false)) - .build() - ); + Glide.with(activity) + .loadFromMediaStore(MusicUtil.getAlbumArtUri(song.albumId)) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .error(R.drawable.default_album_art) + .animate(android.R.anim.fade_in) + .into(albumArt); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { albumArt.setTransitionName(activity.getString(R.string.transition_album_art)); diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/song/SongAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/song/SongAdapter.java index ab4acc0b..8ba31987 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/song/SongAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/song/SongAdapter.java @@ -1,5 +1,6 @@ package com.kabouzeid.gramophone.adapter.song; +import android.graphics.drawable.Drawable; import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -89,8 +90,6 @@ public class SongAdapter extends AbsMultiSelectAdapter target; - @Override - public void onLoadingFailed(String imageUri, View view, FailReason failReason) { - if (currentAlbumArtUri.equals(imageUri)) { - setAlbumArt(context, null); - } - } - }); + private static void loadAlbumCover(@NonNull final Context context, @Nullable final Song song) { + if (song == null) return; + + if (uiThreadHandler == null) { + uiThreadHandler = new Handler(Looper.getMainLooper()); } + if (target == null) { + int widgetImageSize = context.getResources().getDimensionPixelSize(R.dimen.widget_medium_image_size); + target = new SimpleTarget(widgetImageSize, widgetImageSize) { + @Override + public void onLoadFailed(Exception e, Drawable errorDrawable) { + super.onLoadFailed(e, errorDrawable); + setAlbumCover(context, null); + } + + @Override + public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) { + setAlbumCover(context, resource); + } + }; + } + + uiThreadHandler.post(new Runnable() { + @Override + public void run() { + Glide.with(context) + .loadFromMediaStore(MusicUtil.getAlbumArtUri(song.albumId)) + .asBitmap() + .diskCacheStrategy(DiskCacheStrategy.NONE) + .into(target); + } + }); } - private static void setAlbumArt(@NonNull final Context context, @Nullable final Bitmap albumArt) { + private static void setAlbumCover(@NonNull final Context context, @Nullable final Bitmap albumArt) { if (albumArt != null) { widgetLayout.setImageViewBitmap(R.id.image, albumArt); } else { diff --git a/app/src/main/java/com/kabouzeid/gramophone/glide/PhonographColoredTarget.java b/app/src/main/java/com/kabouzeid/gramophone/glide/PhonographColoredTarget.java index 77c7bec2..09d8040d 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/glide/PhonographColoredTarget.java +++ b/app/src/main/java/com/kabouzeid/gramophone/glide/PhonographColoredTarget.java @@ -26,7 +26,7 @@ public abstract class PhonographColoredTarget extends BitmapPaletteTarget { onColorReady(ColorUtil.getColor(resource.getPalette(), getDefaultBarColor())); } - private int getDefaultBarColor() { + protected int getDefaultBarColor() { return ColorUtil.resolveColor(getView().getContext(), R.attr.default_bar_color); } diff --git a/app/src/main/java/com/kabouzeid/gramophone/helper/PlayingNotificationHelper.java b/app/src/main/java/com/kabouzeid/gramophone/helper/PlayingNotificationHelper.java index 58375130..0d99f0d9 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/helper/PlayingNotificationHelper.java +++ b/app/src/main/java/com/kabouzeid/gramophone/helper/PlayingNotificationHelper.java @@ -86,8 +86,8 @@ public class PlayingNotificationHelper { service.stopForeground(true); return; } - this.isColored = isColored; currentSong = song; + this.isColored = isColored; this.isPlaying = service.isPlaying(); notificationLayout = new RemoteViews(service.getPackageName(), R.layout.notification); @@ -179,19 +179,15 @@ public class PlayingNotificationHelper { } private void setUpCollapsedLayout() { - if (currentSong != null) { - notificationLayout.setTextViewText(R.id.title, currentSong.title); - notificationLayout.setTextViewText(R.id.text, currentSong.artistName); - notificationLayout.setTextViewText(R.id.text2, currentSong.albumName); - } + notificationLayout.setTextViewText(R.id.title, currentSong.title); + notificationLayout.setTextViewText(R.id.text, currentSong.artistName); + notificationLayout.setTextViewText(R.id.text2, currentSong.albumName); } private void setUpExpandedLayout() { - if (currentSong != null) { - notificationLayoutBig.setTextViewText(R.id.title, currentSong.title); - notificationLayoutBig.setTextViewText(R.id.text, currentSong.artistName); - notificationLayoutBig.setTextViewText(R.id.text2, currentSong.albumName); - } + notificationLayoutBig.setTextViewText(R.id.title, currentSong.title); + notificationLayoutBig.setTextViewText(R.id.text, currentSong.artistName); + notificationLayoutBig.setTextViewText(R.id.text2, currentSong.albumName); } private void loadAlbumArt() { @@ -203,7 +199,6 @@ public class PlayingNotificationHelper { .asBitmap() .transcode(new BitmapPaletteTranscoder(service), BitmapPaletteWrapper.class) .diskCacheStrategy(DiskCacheStrategy.NONE) - .error(R.drawable.default_album_art) .into(target); } }); diff --git a/app/src/main/java/com/kabouzeid/gramophone/imageloader/BlurProcessor.java b/app/src/main/java/com/kabouzeid/gramophone/imageloader/BlurProcessor.java deleted file mode 100644 index 93139ed3..00000000 --- a/app/src/main/java/com/kabouzeid/gramophone/imageloader/BlurProcessor.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.kabouzeid.gramophone.imageloader; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.os.Build; -import android.renderscript.Allocation; -import android.renderscript.Element; -import android.renderscript.RSRuntimeException; -import android.renderscript.RenderScript; -import android.renderscript.ScriptIntrinsicBlur; -import android.support.annotation.FloatRange; -import android.support.annotation.NonNull; - -import com.kabouzeid.gramophone.BuildConfig; -import com.kabouzeid.gramophone.helper.StackBlur; -import com.kabouzeid.gramophone.util.ImageUtil; -import com.nostra13.universalimageloader.core.process.BitmapProcessor; - -/** - * @author Karim Abou Zeid (kabouzeid) - */ -public class BlurProcessor implements BitmapProcessor { - public static final float DEFAULT_BLUR_RADIUS = 5f; - - private Context context; - private final float blurRadius; - private final int sampling; - - private BlurProcessor(Builder builder) { - this.context = builder.context; - this.blurRadius = builder.blurRadius; - this.sampling = builder.sampling; - } - - // Something here seems to cause a memory leak... Go into LeakCanary for more details. - @Override - public Bitmap process(Bitmap bitmap) { - int sampling; - if (this.sampling == 0) { - sampling = ImageUtil.calculateInSampleSize(bitmap.getWidth(), bitmap.getHeight(), 100); - } else { - sampling = this.sampling; - } - - int width = bitmap.getWidth(); - int height = bitmap.getHeight(); - int scaledWidth = width / sampling; - int scaledHeight = height / sampling; - - Bitmap out = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888); - - Canvas canvas = new Canvas(out); - canvas.scale(1 / (float) sampling, 1 / (float) sampling); - Paint paint = new Paint(); - paint.setFlags(Paint.FILTER_BITMAP_FLAG); - canvas.drawBitmap(bitmap, 0, 0, paint); - - if (Build.VERSION.SDK_INT > 16) { - try { - final RenderScript rs = RenderScript.create(context.getApplicationContext()); - final Allocation input = Allocation.createFromBitmap(rs, out, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); - final Allocation output = Allocation.createTyped(rs, input.getType()); - final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); - - script.setRadius(blurRadius); - script.setInput(input); - script.forEach(output); - - output.copyTo(out); - - rs.destroy(); - - return out; - - } catch (RSRuntimeException e) { - // on some devices RenderScript.create() throws: android.support.v8.renderscript.RSRuntimeException: Error loading libRSSupport library - if (BuildConfig.DEBUG) e.printStackTrace(); - } - } - - return StackBlur.blur(out, blurRadius); - } - - public static class Builder { - private Context context; - private float blurRadius = DEFAULT_BLUR_RADIUS; - private int sampling; - - public Builder(@NonNull Context context) { - this.context = context; - } - - /** - * @param blurRadius The radius to use. Must be between 0 and 25. Default is 5. - * @return the same Builder - */ - public Builder blurRadius(@FloatRange(from = 0.0f, to = 25.0f) float blurRadius) { - this.blurRadius = blurRadius; - return this; - } - - /** - * @param sampling The inSampleSize to use. Must be a power of 2, or 1 for no down sampling or 0 for auto detect sampling. Default is 0. - * @return the same Builder - */ - public Builder sampling(int sampling) { - this.sampling = sampling; - return this; - } - - public Builder fromPrototype(BlurProcessor prototype) { - context = prototype.context; - blurRadius = prototype.blurRadius; - sampling = prototype.sampling; - return this; - } - - public BlurProcessor build() { - return new BlurProcessor(this); - } - } -} diff --git a/app/src/main/java/com/kabouzeid/gramophone/imageloader/PhonographExecutor.java b/app/src/main/java/com/kabouzeid/gramophone/imageloader/PhonographExecutor.java deleted file mode 100644 index 0cb61256..00000000 --- a/app/src/main/java/com/kabouzeid/gramophone/imageloader/PhonographExecutor.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.kabouzeid.gramophone.imageloader; - -import android.support.annotation.NonNull; - -import com.nostra13.universalimageloader.core.DefaultConfigurationFactory; -import com.nostra13.universalimageloader.core.ImageLoader; -import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; -import com.nostra13.universalimageloader.core.LoadAndDisplayImageTask; -import com.nostra13.universalimageloader.core.assist.QueueProcessingType; -import com.nostra13.universalimageloader.core.download.ImageDownloader; - -import java.io.File; -import java.util.concurrent.Executor; -import java.util.concurrent.ThreadPoolExecutor; - -/** - * A custom {@link Executor} meant for kabouzeid's fork of nostra13's Android Universal Image Loader (https://github.com/kabouzeid/Android-Universal-Image-Loader). - * This {@link Executor} separates network and disk loading tasks into different executors so the network image loading doesn't block the disk image loading which is in most cases much faster. - *

- * Maybe there is a better solution for this with a single (ThreadPool-)Executor, but I'm lacking experience here. - * - * @author Karim Abou Zeid (kabouzeid) - */ -public class PhonographExecutor implements Executor { - public static final String TAG = PhonographExecutor.class.getSimpleName(); - - private static final int SECONDARY_THREAD_COUNT = 1; // must be more than ImageLoaderConfiguration.Builder.DEFAULT_THREAD_POOL_SIZE - - private ThreadPoolExecutor primaryExecutor; - private ThreadPoolExecutor secondaryExecutor; - - public PhonographExecutor() { - primaryExecutor = (ThreadPoolExecutor) DefaultConfigurationFactory.createExecutor( - ImageLoaderConfiguration.Builder.DEFAULT_THREAD_POOL_SIZE - SECONDARY_THREAD_COUNT, - ImageLoaderConfiguration.Builder.DEFAULT_THREAD_PRIORITY, - ImageLoaderConfiguration.Builder.DEFAULT_TASK_PROCESSING_TYPE - ); - - secondaryExecutor = (ThreadPoolExecutor) DefaultConfigurationFactory.createExecutor( - SECONDARY_THREAD_COUNT, - ImageLoaderConfiguration.Builder.DEFAULT_THREAD_PRIORITY, - QueueProcessingType.FIFO - ); - } - - @Override - public void execute(@NonNull Runnable command) { - if (command instanceof LoadAndDisplayImageTask) { - String uri = ((LoadAndDisplayImageTask) command).getLoadingUri(); - switch (ImageDownloader.Scheme.ofUri(uri)) { - case HTTP: - case HTTPS: - File imageFile = ImageLoader.getInstance().getDiskCache().get(uri); - if (imageFile == null || !imageFile.exists() || imageFile.length() <= 0) { - // the image is not yet in the disk cache - secondaryExecutor.execute(command); - return; - } - } - } - if (secondaryExecutor.getActiveCount() < secondaryExecutor.getPoolSize()) { - // if the secondary executor got unused threads left, use them! - secondaryExecutor.execute(command); - } else { - primaryExecutor.execute(command); - } - } -} diff --git a/app/src/main/java/com/kabouzeid/gramophone/imageloader/PhonographImageDownloader.java b/app/src/main/java/com/kabouzeid/gramophone/imageloader/PhonographImageDownloader.java deleted file mode 100644 index e16d288f..00000000 --- a/app/src/main/java/com/kabouzeid/gramophone/imageloader/PhonographImageDownloader.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.kabouzeid.gramophone.imageloader; - -import android.content.Context; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.kabouzeid.gramophone.lastfm.rest.LastFMRestClient; -import com.kabouzeid.gramophone.lastfm.rest.model.LastFmArtist; -import com.kabouzeid.gramophone.loader.AlbumSongLoader; -import com.kabouzeid.gramophone.model.Song; -import com.kabouzeid.gramophone.util.LastFMUtil; -import com.kabouzeid.gramophone.util.MusicUtil; -import com.kabouzeid.gramophone.util.PreferenceUtil; -import com.nostra13.universalimageloader.core.download.BaseImageDownloader; - -import org.jaudiotagger.audio.AudioFile; -import org.jaudiotagger.audio.AudioFileIO; -import org.jaudiotagger.tag.images.Artwork; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Locale; - -/** - * @author Karim Abou Zeid (kabouzeid) - */ -public class PhonographImageDownloader extends BaseImageDownloader { - public static final String SCHEME_ALBUM = "album://"; - public static final String SCHEME_SONG = "song://"; - public static final String SCHEME_ARTIST = Scheme.HTTP.wrap("artist://"); - - private final LastFMRestClient lastFMRestClient; - - public PhonographImageDownloader(@NonNull Context context) { - super(context); - lastFMRestClient = new LastFMRestClient(context); - } - - @Nullable - @Override - public InputStream getStream(@NonNull String imageUri, Object extra) throws IOException { - if (imageUri.toLowerCase(Locale.US).startsWith(SCHEME_ALBUM)) { - return getStreamFromAlbum(imageUri); - } - if (imageUri.toLowerCase(Locale.US).startsWith(SCHEME_SONG)) { - return getStreamFromSong(imageUri); - } - if (imageUri.toLowerCase(Locale.US).startsWith(SCHEME_ARTIST)) { - return getStreamFromArtist(imageUri, extra); - } - return super.getStream(imageUri, extra); - } - - @Nullable - protected InputStream getStreamFromArtist(@NonNull String imageUri, @NonNull Object extra) throws IOException { - String[] data = imageUri.substring(SCHEME_ARTIST.length()).split("#", 2); - String artistName = data[1]; - - if (MusicUtil.isArtistNameUnknown(artistName)) { - return super.getStream("", extra); - } - - LastFmArtist lastFmArtist = lastFMRestClient.getApiService().getArtistInfo(artistName, data[0].equals("") ? null : data[0]).execute().body(); - return super.getStream(LastFMUtil.getLargestArtistImageUrl(lastFmArtist.getArtist().getImage()), extra); - } - - @Nullable - protected InputStream getStreamFromAlbum(@NonNull String imageUri) throws IOException { - int albumId = Integer.valueOf(imageUri.substring(SCHEME_ALBUM.length())); - - if (PreferenceUtil.getInstance(context).ignoreMediaStoreArtwork()) { - ArrayList songs = AlbumSongLoader.getAlbumSongList(context, albumId); - for (Song song : songs) { - byte[] albumCover = getAlbumCoverBinaryData(new File(song.data)); - if (albumCover != null) { - return new ByteArrayInputStream(albumCover); - } - } - } - return getMediaProviderAlbumArtInputStream(albumId); - } - - @Nullable - protected InputStream getStreamFromSong(@NonNull String imageUri) throws IOException { - String[] data = imageUri.substring(SCHEME_SONG.length()).split("#", 2); - - if (PreferenceUtil.getInstance(context).ignoreMediaStoreArtwork()) { - byte[] albumCover = getAlbumCoverBinaryData(new File(data[1])); - if (albumCover != null) { - return new ByteArrayInputStream(albumCover); - } - } - - int id = Integer.parseInt(data[0]); - return getMediaProviderAlbumArtInputStream(id); - } - - @Nullable - private static byte[] getAlbumCoverBinaryData(File song) { - try { - AudioFile audioFile = AudioFileIO.read(song); - Artwork artwork = audioFile.getTagOrCreateAndSetDefault().getFirstArtwork(); - if (artwork != null) { - return artwork.getBinaryData(); - } - } catch (@NonNull Exception e) { - e.printStackTrace(); - } - return null; - } - - @Nullable - private InputStream getMediaProviderAlbumArtInputStream(int albumId) throws - FileNotFoundException { - return context.getContentResolver().openInputStream(MusicUtil.getAlbumArtUri(albumId)); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/SettingsActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/SettingsActivity.java index 99a03575..e6d18dc1 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/SettingsActivity.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/SettingsActivity.java @@ -19,6 +19,7 @@ import android.view.MenuItem; import android.view.View; import com.afollestad.materialdialogs.color.ColorChooserDialog; +import com.bumptech.glide.Glide; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.prefs.ColorChooserPreference; import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity; @@ -26,7 +27,6 @@ import com.kabouzeid.gramophone.util.ColorUtil; import com.kabouzeid.gramophone.util.NavigationUtil; import com.kabouzeid.gramophone.util.PreferenceUtil; import com.kabouzeid.gramophone.util.ViewUtil; -import com.nostra13.universalimageloader.core.ImageLoader; import butterknife.Bind; import butterknife.ButterKnife; @@ -198,7 +198,7 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia ignoreMediaStoreArtwork.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - ImageLoader.getInstance().clearMemoryCache(); + Glide.get(getActivity()).clearMemory(); return true; } }); diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/tageditor/AbsTagEditorActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/tageditor/AbsTagEditorActivity.java index bc042aee..c6113f7f 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/tageditor/AbsTagEditorActivity.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/tageditor/AbsTagEditorActivity.java @@ -14,7 +14,6 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; -import android.support.v7.graphics.Palette; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.Menu; @@ -25,7 +24,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import com.afollestad.materialdialogs.MaterialDialog; -import com.afollestad.materialdialogs.util.DialogUtils; +import com.bumptech.glide.Glide; import com.github.ksoichiro.android.observablescrollview.ObservableScrollView; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks; @@ -120,7 +119,6 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity { } private void setUpViews() { - resetColors(); setUpScrollView(); setUpFab(); setUpImageView(); @@ -200,19 +198,6 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity { protected abstract void save(); - private void resetColors() { - paletteColorPrimary = getThemeColorPrimary(); - observableScrollViewCallbacks.onScrollChanged(observableScrollView.getCurrentScrollY(), false, false); - setStatusBarColor(paletteColorPrimary); - if (shouldColorNavigationBar()) - setNavigationBarColor(paletteColorPrimary); - header.setBackgroundColor(paletteColorPrimary); - boolean darkContent = ColorUtil.useDarkTextColorOnBackground(paletteColorPrimary); - ViewUtil.setToolbarContentDark(this, toolbar, darkContent); - setUseDarkStatusBarIcons(darkContent); - notifyTaskColorChange(paletteColorPrimary); - } - private void getIntentExtras() { Bundle intentExtras = getIntent().getExtras(); if (intentExtras != null) { @@ -288,43 +273,22 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity { fab.setEnabled(true); } - protected void setImageRes(int resId) { - Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId); - setImageBitmap(bitmap); + protected void setImageBitmap(@Nullable final Bitmap bitmap, int bgColor) { + image.setImageBitmap(bitmap); + setColors(bgColor); } - protected void setImageBitmap(@Nullable final Bitmap bitmap) { - if (bitmap != null) { - image.setImageBitmap(bitmap); - applyPalette(bitmap); - } else { - resetColors(); - } - } - - private void applyPalette(@NonNull final Bitmap bitmap) { - Palette.from(bitmap) - .resizeBitmapSize(100) - .generate(new Palette.PaletteAsyncListener() { - @Override - public void onGenerated(@NonNull Palette palette) { - final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch(); - if (vibrantSwatch != null) { - paletteColorPrimary = palette.getVibrantColor(DialogUtils.resolveColor(AbsTagEditorActivity.this, R.attr.default_bar_color)); - observableScrollViewCallbacks.onScrollChanged(observableScrollView.getCurrentScrollY(), false, false); - if (shouldColorNavigationBar()) - setNavigationBarColor(paletteColorPrimary); - setStatusBarColor(paletteColorPrimary); - header.setBackgroundColor(paletteColorPrimary); - boolean darkContent = ColorUtil.useDarkTextColorOnBackground(paletteColorPrimary); - ViewUtil.setToolbarContentDark(AbsTagEditorActivity.this, toolbar, darkContent); - setUseDarkStatusBarIcons(darkContent); - notifyTaskColorChange(paletteColorPrimary); - } else { - resetColors(); - } - } - }); + private void setColors(int color) { + paletteColorPrimary = color; + observableScrollViewCallbacks.onScrollChanged(observableScrollView.getCurrentScrollY(), false, false); + if (shouldColorNavigationBar()) + setNavigationBarColor(paletteColorPrimary); + setStatusBarColor(paletteColorPrimary); + header.setBackgroundColor(paletteColorPrimary); + boolean darkContent = ColorUtil.useDarkTextColorOnBackground(paletteColorPrimary); + ViewUtil.setToolbarContentDark(AbsTagEditorActivity.this, toolbar, darkContent); + setUseDarkStatusBarIcons(darkContent); + notifyTaskColorChange(paletteColorPrimary); } @Override @@ -390,6 +354,9 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity { }); if (deleteArtwork) { MusicUtil.deleteAlbumArt(AbsTagEditorActivity.this, getId()); + Glide.get(AbsTagEditorActivity.this).clearMemory(); + } else if (artwork != null) { + Glide.get(AbsTagEditorActivity.this).clearMemory(); } rescanMediaAndQuitOnFinish(); } diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/tageditor/AlbumTagEditorActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/tageditor/AlbumTagEditorActivity.java index 1860f7a8..7ed14d55 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/tageditor/AlbumTagEditorActivity.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/tageditor/AlbumTagEditorActivity.java @@ -1,29 +1,33 @@ package com.kabouzeid.gramophone.ui.activities.tageditor; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.support.annotation.NonNull; import android.text.Editable; +import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; -import android.view.View; import android.widget.EditText; import android.widget.Toast; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.request.animation.GlideAnimation; +import com.bumptech.glide.request.target.SimpleTarget; import com.kabouzeid.gramophone.R; +import com.kabouzeid.gramophone.glide.palette.BitmapPaletteTranscoder; +import com.kabouzeid.gramophone.glide.palette.BitmapPaletteWrapper; import com.kabouzeid.gramophone.lastfm.rest.LastFMRestClient; import com.kabouzeid.gramophone.lastfm.rest.model.LastFmAlbum; import com.kabouzeid.gramophone.loader.AlbumSongLoader; import com.kabouzeid.gramophone.model.Song; +import com.kabouzeid.gramophone.util.ColorUtil; import com.kabouzeid.gramophone.util.LastFMUtil; import com.kabouzeid.gramophone.util.MusicUtil; -import com.kabouzeid.gramophone.util.Util; -import com.nostra13.universalimageloader.core.DisplayImageOptions; -import com.nostra13.universalimageloader.core.ImageLoader; -import com.nostra13.universalimageloader.core.assist.FailReason; -import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; -import com.nostra13.universalimageloader.core.process.BitmapProcessor; import org.jaudiotagger.tag.FieldKey; import org.jaudiotagger.tag.images.Artwork; @@ -88,7 +92,8 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text @Override protected void loadCurrentImage() { - setImageBitmap(getAlbumArt()); + Bitmap bitmap = getAlbumArt(); + setImageBitmap(bitmap, ColorUtil.getColor(ColorUtil.generatePalette(bitmap), ColorUtil.resolveColor(this, R.attr.default_bar_color))); deleteAlbumArt = false; } @@ -105,32 +110,36 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text public void onResponse(final Response response, Retrofit retrofit) { LastFmAlbum lastFmAlbum = response.body(); if (lastFmAlbum.getAlbum() != null) { - ImageLoader.getInstance().loadImage(LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.getAlbum().getImage()), - new DisplayImageOptions.Builder() - .preProcessor(albumCoverProcessor) - .build(), - new SimpleImageLoadingListener() { - @Override - public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { - if (loadedImage == null) { - onLoadingFailed(imageUri, view, null); - return; + String url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.getAlbum().getImage()); + if (!TextUtils.isEmpty(url) && url.trim().length() > 0) { + Glide.with(AlbumTagEditorActivity.this) + .load(url) + .asBitmap() + .transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this), BitmapPaletteWrapper.class) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .error(R.drawable.default_album_art) + .into(new SimpleTarget() { + @Override + public void onLoadFailed(Exception e, Drawable errorDrawable) { + super.onLoadFailed(e, errorDrawable); + e.printStackTrace(); + Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show(); } - albumArtBitmap = loadedImage; - setImageBitmap(albumArtBitmap); - deleteAlbumArt = false; - dataChanged(); - setResult(RESULT_OK); - } - @Override - public void onLoadingFailed(String imageUri, View view, FailReason failReason) { - handleFailReason(failReason); - } - }); - } else { - toastLoadingFailed(); + @Override + public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation glideAnimation) { + ColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT); + albumArtBitmap = resource.getBitmap(); + setImageBitmap(albumArtBitmap, ColorUtil.getColor(resource.getPalette(), ColorUtil.resolveColor(AlbumTagEditorActivity.this, R.attr.default_bar_color))); + deleteAlbumArt = false; + dataChanged(); + setResult(RESULT_OK); + } + }); + return; + } } + toastLoadingFailed(); } @Override @@ -152,7 +161,7 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text @Override protected void deleteImage() { - setImageRes(R.drawable.default_album_art); + setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.default_album_art), ColorUtil.resolveColor(this, R.attr.default_bar_color)); deleteAlbumArt = true; dataChanged(); } @@ -200,23 +209,28 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text @Override protected void loadImageFromFile(@NonNull final Uri selectedFileUri) { - ImageLoader.getInstance().loadImage(selectedFileUri.toString(), - new DisplayImageOptions.Builder() - .preProcessor(albumCoverProcessor) - .build(), - new SimpleImageLoadingListener() { + Glide.with(AlbumTagEditorActivity.this) + .load(selectedFileUri) + .asBitmap() + .transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this), BitmapPaletteWrapper.class) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .skipMemoryCache(true) + .into(new SimpleTarget() { @Override - public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { - albumArtBitmap = loadedImage; - setImageBitmap(albumArtBitmap); - deleteAlbumArt = false; - dataChanged(); - setResult(RESULT_OK); + public void onLoadFailed(Exception e, Drawable errorDrawable) { + super.onLoadFailed(e, errorDrawable); + e.printStackTrace(); + Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show(); } @Override - public void onLoadingFailed(String imageUri, View view, FailReason failReason) { - handleFailReason(failReason); + public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation glideAnimation) { + ColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT); + albumArtBitmap = resource.getBitmap(); + setImageBitmap(albumArtBitmap, ColorUtil.getColor(resource.getPalette(), ColorUtil.resolveColor(AlbumTagEditorActivity.this, R.attr.default_bar_color))); + deleteAlbumArt = false; + dataChanged(); + setResult(RESULT_OK); } }); } @@ -236,22 +250,6 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text dataChanged(); } - private BitmapProcessor albumCoverProcessor = new BitmapProcessor() { - @Override - public Bitmap process(Bitmap bitmap) { - return getResizedAlbumCover(bitmap, Util.getSmallerScreenSize(AlbumTagEditorActivity.this)); - } - }; - - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - private void handleFailReason(FailReason failReason) { - Throwable cause = failReason.getCause(); - if (cause != null) { - cause.printStackTrace(); - Toast.makeText(AlbumTagEditorActivity.this, cause.toString(), Toast.LENGTH_LONG).show(); - } - } - private static Bitmap getResizedAlbumCover(@NonNull Bitmap src, int maxForSmallerSize) { int width = src.getWidth(); int height = src.getHeight(); diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/MusicUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/MusicUtil.java index 67b9a7dc..0c8eac8d 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/MusicUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/MusicUtil.java @@ -18,10 +18,8 @@ import android.widget.Toast; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.helper.MusicPlayerRemote; -import com.kabouzeid.gramophone.imageloader.PhonographImageDownloader; import com.kabouzeid.gramophone.loader.PlaylistLoader; import com.kabouzeid.gramophone.loader.SongLoader; -import com.kabouzeid.gramophone.model.Album; import com.kabouzeid.gramophone.model.Artist; import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Song; @@ -36,25 +34,6 @@ import java.util.List; public class MusicUtil { public static final String TAG = MusicUtil.class.getSimpleName(); - @NonNull - public static String getArtistImageLoaderString(@NonNull Artist artist, boolean forceDownload) { - if (forceDownload) { - return PhonographImageDownloader.SCHEME_ARTIST + "no-cache#" + artist.name; - } else { - return PhonographImageDownloader.SCHEME_ARTIST + "#" + artist.name; - } - } - - @NonNull - public static String getAlbumImageLoaderString(@NonNull Album album) { - return PhonographImageDownloader.SCHEME_ALBUM + album.id; - } - - @NonNull - public static String getSongImageLoaderString(@NonNull Song song) { - return PhonographImageDownloader.SCHEME_SONG + song.albumId + "#" + song.data; - } - public static Uri getAlbumArtUri(int albumId) { final Uri sArtworkUri = Uri .parse("content://media/external/audio/albumart");