Further progress with glide
This commit is contained in:
parent
3393136f2e
commit
d776926510
16 changed files with 160 additions and 542 deletions
|
|
@ -125,7 +125,6 @@ dependencies {
|
||||||
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
|
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
|
||||||
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
|
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
|
||||||
compile 'com.squareup.okhttp:okhttp:2.7.0'
|
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 'com.jakewharton:butterknife:7.0.1'
|
||||||
compile 'org.solovyev.android.views:linear-layout-manager:0.5@aar'
|
compile 'org.solovyev.android.views:linear-layout-manager:0.5@aar'
|
||||||
//noinspection GradleDynamicVersion
|
//noinspection GradleDynamicVersion
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,6 @@ package com.kabouzeid.gramophone;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
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;
|
import io.fabric.sdk.android.Fabric;
|
||||||
|
|
||||||
|
|
@ -24,12 +19,5 @@ public class App extends Application {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
if (!BuildConfig.DEBUG) Fabric.with(this, new Crashlytics());
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.kabouzeid.gramophone.adapter.album;
|
package com.kabouzeid.gramophone.adapter.album;
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.annotation.LayoutRes;
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
@ -89,9 +90,6 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
|
||||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||||
final Album album = dataSet.get(position);
|
final Album album = dataSet.get(position);
|
||||||
|
|
||||||
final int defaultBarColor = ColorUtil.resolveColor(activity, R.attr.default_bar_color);
|
|
||||||
setColors(defaultBarColor, holder);
|
|
||||||
|
|
||||||
final boolean isChecked = isChecked(album);
|
final boolean isChecked = isChecked(album);
|
||||||
holder.itemView.setActivated(isChecked);
|
holder.itemView.setActivated(isChecked);
|
||||||
if (holder.selectedIndicator != null) {
|
if (holder.selectedIndicator != null) {
|
||||||
|
|
@ -130,6 +128,12 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
|
||||||
.error(R.drawable.default_album_art)
|
.error(R.drawable.default_album_art)
|
||||||
.animate(android.R.anim.fade_in)
|
.animate(android.R.anim.fade_in)
|
||||||
.into(new PhonographColoredTarget(holder.image) {
|
.into(new PhonographColoredTarget(holder.image) {
|
||||||
|
@Override
|
||||||
|
public void onLoadCleared(Drawable placeholder) {
|
||||||
|
super.onLoadCleared(placeholder);
|
||||||
|
setColors(getDefaultBarColor(), holder);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onColorReady(int color) {
|
public void onColorReady(int color) {
|
||||||
if (usePalette)
|
if (usePalette)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.kabouzeid.gramophone.adapter.artist;
|
package com.kabouzeid.gramophone.adapter.artist;
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.annotation.LayoutRes;
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
@ -126,6 +127,12 @@ public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolde
|
||||||
.error(R.drawable.default_album_art)
|
.error(R.drawable.default_album_art)
|
||||||
.animate(android.R.anim.fade_in)
|
.animate(android.R.anim.fade_in)
|
||||||
.into(new PhonographColoredTarget(holder.image) {
|
.into(new PhonographColoredTarget(holder.image) {
|
||||||
|
@Override
|
||||||
|
public void onLoadCleared(Drawable placeholder) {
|
||||||
|
super.onLoadCleared(placeholder);
|
||||||
|
setColors(getDefaultBarColor(), holder);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onColorReady(int color) {
|
public void onColorReady(int color) {
|
||||||
if (usePalette)
|
if (usePalette)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.afollestad.materialcab.MaterialCab;
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
|
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
|
||||||
|
|
@ -24,9 +26,6 @@ import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
@ -34,8 +33,6 @@ import java.util.ArrayList;
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class ArtistSongAdapter extends ArrayAdapter<Song> implements MaterialCab.Callback {
|
public class ArtistSongAdapter extends ArrayAdapter<Song> implements MaterialCab.Callback {
|
||||||
private static final int FADE_IN_TIME = 500;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final CabHolder cabHolder;
|
private final CabHolder cabHolder;
|
||||||
private MaterialCab cab;
|
private MaterialCab cab;
|
||||||
|
|
@ -77,16 +74,12 @@ public class ArtistSongAdapter extends ArrayAdapter<Song> implements MaterialCab
|
||||||
songTitle.setText(song.title);
|
songTitle.setText(song.title);
|
||||||
songInfo.setText(song.albumName);
|
songInfo.setText(song.albumName);
|
||||||
|
|
||||||
ImageLoader.getInstance().displayImage(
|
Glide.with(activity)
|
||||||
MusicUtil.getSongImageLoaderString(song),
|
.loadFromMediaStore(MusicUtil.getAlbumArtUri(song.albumId))
|
||||||
albumArt,
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||||
new DisplayImageOptions.Builder()
|
.error(R.drawable.default_album_art)
|
||||||
.cacheInMemory(true)
|
.animate(android.R.anim.fade_in)
|
||||||
.showImageOnFail(R.drawable.default_album_art)
|
.into(albumArt);
|
||||||
.resetViewBeforeLoading(true)
|
|
||||||
.displayer(new FadeInBitmapDisplayer(FADE_IN_TIME, true, true, false))
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
albumArt.setTransitionName(activity.getString(R.string.transition_album_art));
|
albumArt.setTransitionName(activity.getString(R.string.transition_album_art));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.kabouzeid.gramophone.adapter.song;
|
package com.kabouzeid.gramophone.adapter.song;
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.annotation.LayoutRes;
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
@ -89,8 +90,6 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
|
||||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||||
final Song song = dataSet.get(position);
|
final Song song = dataSet.get(position);
|
||||||
|
|
||||||
// setColors(ColorUtil.resolveColor(activity, R.attr.default_bar_color), holder);
|
|
||||||
|
|
||||||
boolean isChecked = isChecked(song);
|
boolean isChecked = isChecked(song);
|
||||||
holder.itemView.setActivated(isChecked);
|
holder.itemView.setActivated(isChecked);
|
||||||
if (holder.selectedIndicator != null) {
|
if (holder.selectedIndicator != null) {
|
||||||
|
|
@ -130,6 +129,12 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
|
||||||
.error(R.drawable.default_album_art)
|
.error(R.drawable.default_album_art)
|
||||||
.animate(android.R.anim.fade_in)
|
.animate(android.R.anim.fade_in)
|
||||||
.into(new PhonographColoredTarget(holder.image) {
|
.into(new PhonographColoredTarget(holder.image) {
|
||||||
|
@Override
|
||||||
|
public void onLoadCleared(Drawable placeholder) {
|
||||||
|
super.onLoadCleared(placeholder);
|
||||||
|
setColors(getDefaultBarColor(), holder);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onColorReady(int color) {
|
public void onColorReady(int color) {
|
||||||
if (usePalette)
|
if (usePalette)
|
||||||
|
|
|
||||||
|
|
@ -7,29 +7,27 @@ import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
|
|
||||||
|
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.bumptech.glide.request.target.Target;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.service.MusicService;
|
import com.kabouzeid.gramophone.service.MusicService;
|
||||||
import com.kabouzeid.gramophone.ui.activities.MainActivity;
|
import com.kabouzeid.gramophone.ui.activities.MainActivity;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
|
||||||
import com.nostra13.universalimageloader.core.assist.ImageSize;
|
|
||||||
import com.nostra13.universalimageloader.core.assist.ViewScaleType;
|
|
||||||
import com.nostra13.universalimageloader.core.imageaware.NonViewAware;
|
|
||||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
|
||||||
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
|
||||||
|
|
||||||
public class WidgetMedium extends AppWidgetProvider {
|
public class WidgetMedium extends AppWidgetProvider {
|
||||||
private static RemoteViews widgetLayout;
|
private static RemoteViews widgetLayout;
|
||||||
private static String currentAlbumArtUri;
|
|
||||||
|
|
||||||
public static void updateWidgets(@NonNull final Context context, @NonNull final Song song, boolean isPlaying) {
|
public static void updateWidgets(@NonNull final Context context, @NonNull final Song song, boolean isPlaying) {
|
||||||
if (song.id == -1) return;
|
if (song.id == -1) return;
|
||||||
|
|
@ -39,7 +37,7 @@ public class WidgetMedium extends AppWidgetProvider {
|
||||||
widgetLayout.setTextViewText(R.id.song_secondary_information, song.artistName + " | " + song.albumName);
|
widgetLayout.setTextViewText(R.id.song_secondary_information, song.artistName + " | " + song.albumName);
|
||||||
|
|
||||||
updateWidgetsPlayState(context, isPlaying);
|
updateWidgetsPlayState(context, isPlaying);
|
||||||
loadAlbumArt(context, song);
|
loadAlbumCover(context, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateWidgetsPlayState(@NonNull final Context context, boolean isPlaying) {
|
public static void updateWidgetsPlayState(@NonNull final Context context, boolean isPlaying) {
|
||||||
|
|
@ -59,46 +57,44 @@ public class WidgetMedium extends AppWidgetProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadAlbumArt(@NonNull final Context context, @Nullable final Song song) {
|
private static Handler uiThreadHandler;
|
||||||
if (song != null) {
|
private static Target<Bitmap> target;
|
||||||
int widgetImageSize = context.getResources().getDimensionPixelSize(R.dimen.widget_medium_image_size);
|
|
||||||
currentAlbumArtUri = MusicUtil.getSongImageLoaderString(song);
|
|
||||||
ImageLoader.getInstance().displayImage(
|
|
||||||
currentAlbumArtUri,
|
|
||||||
new NonViewAware(new ImageSize(widgetImageSize, widgetImageSize), ViewScaleType.CROP),
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.postProcessor(new BitmapProcessor() {
|
|
||||||
@Override
|
|
||||||
public Bitmap process(Bitmap bitmap) {
|
|
||||||
// The RemoteViews might wants to recycle the bitmaps thrown at it, so we need
|
|
||||||
// to make sure not to hand out our cache copy
|
|
||||||
Bitmap.Config config = bitmap.getConfig();
|
|
||||||
if (config == null) {
|
|
||||||
config = Bitmap.Config.ARGB_8888;
|
|
||||||
}
|
|
||||||
bitmap = bitmap.copy(config, false);
|
|
||||||
return bitmap.copy(bitmap.getConfig(), true);
|
|
||||||
}
|
|
||||||
}).build(),
|
|
||||||
new SimpleImageLoadingListener() {
|
|
||||||
@Override
|
|
||||||
public void onLoadingComplete(String imageUri, View view, @Nullable Bitmap loadedImage) {
|
|
||||||
if (currentAlbumArtUri.equals(imageUri)) {
|
|
||||||
setAlbumArt(context, loadedImage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private static void loadAlbumCover(@NonNull final Context context, @Nullable final Song song) {
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
if (song == null) return;
|
||||||
if (currentAlbumArtUri.equals(imageUri)) {
|
|
||||||
setAlbumArt(context, null);
|
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<Bitmap>(widgetImageSize, widgetImageSize) {
|
||||||
|
@Override
|
||||||
|
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||||
|
super.onLoadFailed(e, errorDrawable);
|
||||||
|
setAlbumCover(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> 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) {
|
if (albumArt != null) {
|
||||||
widgetLayout.setImageViewBitmap(R.id.image, albumArt);
|
widgetLayout.setImageViewBitmap(R.id.image, albumArt);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ public abstract class PhonographColoredTarget extends BitmapPaletteTarget {
|
||||||
onColorReady(ColorUtil.getColor(resource.getPalette(), getDefaultBarColor()));
|
onColorReady(ColorUtil.getColor(resource.getPalette(), getDefaultBarColor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getDefaultBarColor() {
|
protected int getDefaultBarColor() {
|
||||||
return ColorUtil.resolveColor(getView().getContext(), R.attr.default_bar_color);
|
return ColorUtil.resolveColor(getView().getContext(), R.attr.default_bar_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,8 @@ public class PlayingNotificationHelper {
|
||||||
service.stopForeground(true);
|
service.stopForeground(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isColored = isColored;
|
|
||||||
currentSong = song;
|
currentSong = song;
|
||||||
|
this.isColored = isColored;
|
||||||
this.isPlaying = service.isPlaying();
|
this.isPlaying = service.isPlaying();
|
||||||
|
|
||||||
notificationLayout = new RemoteViews(service.getPackageName(), R.layout.notification);
|
notificationLayout = new RemoteViews(service.getPackageName(), R.layout.notification);
|
||||||
|
|
@ -179,19 +179,15 @@ public class PlayingNotificationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpCollapsedLayout() {
|
private void setUpCollapsedLayout() {
|
||||||
if (currentSong != null) {
|
notificationLayout.setTextViewText(R.id.title, currentSong.title);
|
||||||
notificationLayout.setTextViewText(R.id.title, currentSong.title);
|
notificationLayout.setTextViewText(R.id.text, currentSong.artistName);
|
||||||
notificationLayout.setTextViewText(R.id.text, currentSong.artistName);
|
notificationLayout.setTextViewText(R.id.text2, currentSong.albumName);
|
||||||
notificationLayout.setTextViewText(R.id.text2, currentSong.albumName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpExpandedLayout() {
|
private void setUpExpandedLayout() {
|
||||||
if (currentSong != null) {
|
notificationLayoutBig.setTextViewText(R.id.title, currentSong.title);
|
||||||
notificationLayoutBig.setTextViewText(R.id.title, currentSong.title);
|
notificationLayoutBig.setTextViewText(R.id.text, currentSong.artistName);
|
||||||
notificationLayoutBig.setTextViewText(R.id.text, currentSong.artistName);
|
notificationLayoutBig.setTextViewText(R.id.text2, currentSong.albumName);
|
||||||
notificationLayoutBig.setTextViewText(R.id.text2, currentSong.albumName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadAlbumArt() {
|
private void loadAlbumArt() {
|
||||||
|
|
@ -203,7 +199,6 @@ public class PlayingNotificationHelper {
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.transcode(new BitmapPaletteTranscoder(service), BitmapPaletteWrapper.class)
|
.transcode(new BitmapPaletteTranscoder(service), BitmapPaletteWrapper.class)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||||
.error(R.drawable.default_album_art)
|
|
||||||
.into(target);
|
.into(target);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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.
|
|
||||||
* <p/>
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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<Song> 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -19,6 +19,7 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.color.ColorChooserDialog;
|
import com.afollestad.materialdialogs.color.ColorChooserDialog;
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.prefs.ColorChooserPreference;
|
import com.kabouzeid.gramophone.prefs.ColorChooserPreference;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
|
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.NavigationUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
|
@ -198,7 +198,7 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
||||||
ignoreMediaStoreArtwork.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
ignoreMediaStoreArtwork.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
ImageLoader.getInstance().clearMemoryCache();
|
Glide.get(getActivity()).clearMemory();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v7.graphics.Palette;
|
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
|
@ -25,7 +24,7 @@ import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
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.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
|
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
|
||||||
|
|
@ -120,7 +119,6 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpViews() {
|
private void setUpViews() {
|
||||||
resetColors();
|
|
||||||
setUpScrollView();
|
setUpScrollView();
|
||||||
setUpFab();
|
setUpFab();
|
||||||
setUpImageView();
|
setUpImageView();
|
||||||
|
|
@ -200,19 +198,6 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
|
|
||||||
protected abstract void save();
|
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() {
|
private void getIntentExtras() {
|
||||||
Bundle intentExtras = getIntent().getExtras();
|
Bundle intentExtras = getIntent().getExtras();
|
||||||
if (intentExtras != null) {
|
if (intentExtras != null) {
|
||||||
|
|
@ -288,43 +273,22 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
fab.setEnabled(true);
|
fab.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setImageRes(int resId) {
|
protected void setImageBitmap(@Nullable final Bitmap bitmap, int bgColor) {
|
||||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
|
image.setImageBitmap(bitmap);
|
||||||
setImageBitmap(bitmap);
|
setColors(bgColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setImageBitmap(@Nullable final Bitmap bitmap) {
|
private void setColors(int color) {
|
||||||
if (bitmap != null) {
|
paletteColorPrimary = color;
|
||||||
image.setImageBitmap(bitmap);
|
observableScrollViewCallbacks.onScrollChanged(observableScrollView.getCurrentScrollY(), false, false);
|
||||||
applyPalette(bitmap);
|
if (shouldColorNavigationBar())
|
||||||
} else {
|
setNavigationBarColor(paletteColorPrimary);
|
||||||
resetColors();
|
setStatusBarColor(paletteColorPrimary);
|
||||||
}
|
header.setBackgroundColor(paletteColorPrimary);
|
||||||
}
|
boolean darkContent = ColorUtil.useDarkTextColorOnBackground(paletteColorPrimary);
|
||||||
|
ViewUtil.setToolbarContentDark(AbsTagEditorActivity.this, toolbar, darkContent);
|
||||||
private void applyPalette(@NonNull final Bitmap bitmap) {
|
setUseDarkStatusBarIcons(darkContent);
|
||||||
Palette.from(bitmap)
|
notifyTaskColorChange(paletteColorPrimary);
|
||||||
.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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -390,6 +354,9 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
});
|
});
|
||||||
if (deleteArtwork) {
|
if (deleteArtwork) {
|
||||||
MusicUtil.deleteAlbumArt(AbsTagEditorActivity.this, getId());
|
MusicUtil.deleteAlbumArt(AbsTagEditorActivity.this, getId());
|
||||||
|
Glide.get(AbsTagEditorActivity.this).clearMemory();
|
||||||
|
} else if (artwork != null) {
|
||||||
|
Glide.get(AbsTagEditorActivity.this).clearMemory();
|
||||||
}
|
}
|
||||||
rescanMediaAndQuitOnFinish();
|
rescanMediaAndQuitOnFinish();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,33 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
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.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.LastFMRestClient;
|
||||||
import com.kabouzeid.gramophone.lastfm.rest.model.LastFmAlbum;
|
import com.kabouzeid.gramophone.lastfm.rest.model.LastFmAlbum;
|
||||||
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
|
import com.kabouzeid.gramophone.util.ColorUtil;
|
||||||
import com.kabouzeid.gramophone.util.LastFMUtil;
|
import com.kabouzeid.gramophone.util.LastFMUtil;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
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.FieldKey;
|
||||||
import org.jaudiotagger.tag.images.Artwork;
|
import org.jaudiotagger.tag.images.Artwork;
|
||||||
|
|
@ -88,7 +92,8 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadCurrentImage() {
|
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;
|
deleteAlbumArt = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,32 +110,36 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
|
||||||
public void onResponse(final Response<LastFmAlbum> response, Retrofit retrofit) {
|
public void onResponse(final Response<LastFmAlbum> response, Retrofit retrofit) {
|
||||||
LastFmAlbum lastFmAlbum = response.body();
|
LastFmAlbum lastFmAlbum = response.body();
|
||||||
if (lastFmAlbum.getAlbum() != null) {
|
if (lastFmAlbum.getAlbum() != null) {
|
||||||
ImageLoader.getInstance().loadImage(LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.getAlbum().getImage()),
|
String url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.getAlbum().getImage());
|
||||||
new DisplayImageOptions.Builder()
|
if (!TextUtils.isEmpty(url) && url.trim().length() > 0) {
|
||||||
.preProcessor(albumCoverProcessor)
|
Glide.with(AlbumTagEditorActivity.this)
|
||||||
.build(),
|
.load(url)
|
||||||
new SimpleImageLoadingListener() {
|
.asBitmap()
|
||||||
@Override
|
.transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this), BitmapPaletteWrapper.class)
|
||||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
if (loadedImage == null) {
|
.error(R.drawable.default_album_art)
|
||||||
onLoadingFailed(imageUri, view, null);
|
.into(new SimpleTarget<BitmapPaletteWrapper>() {
|
||||||
return;
|
@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
|
@Override
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
|
||||||
handleFailReason(failReason);
|
ColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT);
|
||||||
}
|
albumArtBitmap = resource.getBitmap();
|
||||||
});
|
setImageBitmap(albumArtBitmap, ColorUtil.getColor(resource.getPalette(), ColorUtil.resolveColor(AlbumTagEditorActivity.this, R.attr.default_bar_color)));
|
||||||
} else {
|
deleteAlbumArt = false;
|
||||||
toastLoadingFailed();
|
dataChanged();
|
||||||
|
setResult(RESULT_OK);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
toastLoadingFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -152,7 +161,7 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deleteImage() {
|
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;
|
deleteAlbumArt = true;
|
||||||
dataChanged();
|
dataChanged();
|
||||||
}
|
}
|
||||||
|
|
@ -200,23 +209,28 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadImageFromFile(@NonNull final Uri selectedFileUri) {
|
protected void loadImageFromFile(@NonNull final Uri selectedFileUri) {
|
||||||
ImageLoader.getInstance().loadImage(selectedFileUri.toString(),
|
Glide.with(AlbumTagEditorActivity.this)
|
||||||
new DisplayImageOptions.Builder()
|
.load(selectedFileUri)
|
||||||
.preProcessor(albumCoverProcessor)
|
.asBitmap()
|
||||||
.build(),
|
.transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this), BitmapPaletteWrapper.class)
|
||||||
new SimpleImageLoadingListener() {
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||||
|
.skipMemoryCache(true)
|
||||||
|
.into(new SimpleTarget<BitmapPaletteWrapper>() {
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||||
albumArtBitmap = loadedImage;
|
super.onLoadFailed(e, errorDrawable);
|
||||||
setImageBitmap(albumArtBitmap);
|
e.printStackTrace();
|
||||||
deleteAlbumArt = false;
|
Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show();
|
||||||
dataChanged();
|
|
||||||
setResult(RESULT_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
|
||||||
handleFailReason(failReason);
|
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();
|
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) {
|
private static Bitmap getResizedAlbumCover(@NonNull Bitmap src, int maxForSmallerSize) {
|
||||||
int width = src.getWidth();
|
int width = src.getWidth();
|
||||||
int height = src.getHeight();
|
int height = src.getHeight();
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,8 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
import com.kabouzeid.gramophone.imageloader.PhonographImageDownloader;
|
|
||||||
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
||||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||||
import com.kabouzeid.gramophone.model.Album;
|
|
||||||
import com.kabouzeid.gramophone.model.Artist;
|
import com.kabouzeid.gramophone.model.Artist;
|
||||||
import com.kabouzeid.gramophone.model.Playlist;
|
import com.kabouzeid.gramophone.model.Playlist;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
|
|
@ -36,25 +34,6 @@ import java.util.List;
|
||||||
public class MusicUtil {
|
public class MusicUtil {
|
||||||
public static final String TAG = MusicUtil.class.getSimpleName();
|
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) {
|
public static Uri getAlbumArtUri(int albumId) {
|
||||||
final Uri sArtworkUri = Uri
|
final Uri sArtworkUri = Uri
|
||||||
.parse("content://media/external/audio/albumart");
|
.parse("content://media/external/audio/albumart");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue