Just code rearrangement
This commit is contained in:
parent
0c3b78eca0
commit
60a3070dfe
58 changed files with 1468 additions and 1500 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest package="com.kabouzeid.materialmusic"
|
||||||
package="com.kabouzeid.materialmusic">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
|
|
||||||
|
|
@ -48,23 +48,10 @@ import android.widget.TextView;
|
||||||
* providing the layout ID of your custom layout.
|
* providing the layout ID of your custom layout.
|
||||||
*/
|
*/
|
||||||
public class SlidingTabLayout extends HorizontalScrollView {
|
public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
/**
|
|
||||||
* Allows complete control over the colors drawn in the tab layout. Set with
|
|
||||||
* {@link #setCustomTabColorizer(com.google.samples.apps.iosched.ui.widget.SlidingTabLayout.TabColorizer)}.
|
|
||||||
*/
|
|
||||||
public interface TabColorizer {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return return the color of the indicator used when {@code position} is selected.
|
|
||||||
*/
|
|
||||||
int getIndicatorColor(int position);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int TITLE_OFFSET_DIPS = 24;
|
private static final int TITLE_OFFSET_DIPS = 24;
|
||||||
private static final int TAB_VIEW_PADDING_DIPS = 16;
|
private static final int TAB_VIEW_PADDING_DIPS = 16;
|
||||||
private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
|
private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
|
||||||
|
private final SlidingTabStrip mTabStrip;
|
||||||
private int mTitleOffset;
|
private int mTitleOffset;
|
||||||
|
|
||||||
private int mTabViewLayoutId;
|
private int mTabViewLayoutId;
|
||||||
|
|
@ -75,8 +62,6 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
private SparseArray<String> mContentDescriptions = new SparseArray<String>();
|
private SparseArray<String> mContentDescriptions = new SparseArray<String>();
|
||||||
private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
|
private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
|
||||||
|
|
||||||
private final SlidingTabStrip mTabStrip;
|
|
||||||
|
|
||||||
public SlidingTabLayout(Context context) {
|
public SlidingTabLayout(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
}
|
}
|
||||||
|
|
@ -158,30 +143,6 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a default view to be used for tabs. This is called if a custom tab view is not set via
|
|
||||||
* {@link #setCustomTabView(int, int)}.
|
|
||||||
*/
|
|
||||||
protected TextView createDefaultTabView(Context context) {
|
|
||||||
TextView textView = new TextView(context);
|
|
||||||
textView.setGravity(Gravity.CENTER);
|
|
||||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
|
|
||||||
textView.setTypeface(Typeface.DEFAULT_BOLD);
|
|
||||||
textView.setLayoutParams(new LinearLayout.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
|
|
||||||
TypedValue outValue = new TypedValue();
|
|
||||||
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
|
|
||||||
outValue, true);
|
|
||||||
textView.setBackgroundResource(outValue.resourceId);
|
|
||||||
textView.setAllCaps(true);
|
|
||||||
|
|
||||||
int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
|
|
||||||
textView.setPadding(padding, padding, padding, padding);
|
|
||||||
|
|
||||||
return textView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateTabStrip() {
|
private void populateTabStrip() {
|
||||||
final PagerAdapter adapter = mViewPager.getAdapter();
|
final PagerAdapter adapter = mViewPager.getAdapter();
|
||||||
final OnClickListener tabClickListener = new TabClickListener();
|
final OnClickListener tabClickListener = new TabClickListener();
|
||||||
|
|
@ -225,6 +186,30 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a default view to be used for tabs. This is called if a custom tab view is not set via
|
||||||
|
* {@link #setCustomTabView(int, int)}.
|
||||||
|
*/
|
||||||
|
protected TextView createDefaultTabView(Context context) {
|
||||||
|
TextView textView = new TextView(context);
|
||||||
|
textView.setGravity(Gravity.CENTER);
|
||||||
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
|
||||||
|
textView.setTypeface(Typeface.DEFAULT_BOLD);
|
||||||
|
textView.setLayoutParams(new LinearLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
|
TypedValue outValue = new TypedValue();
|
||||||
|
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
|
||||||
|
outValue, true);
|
||||||
|
textView.setBackgroundResource(outValue.resourceId);
|
||||||
|
textView.setAllCaps(true);
|
||||||
|
|
||||||
|
int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
|
||||||
|
textView.setPadding(padding, padding, padding, padding);
|
||||||
|
|
||||||
|
return textView;
|
||||||
|
}
|
||||||
|
|
||||||
public void setContentDescription(int i, String desc) {
|
public void setContentDescription(int i, String desc) {
|
||||||
mContentDescriptions.put(i, desc);
|
mContentDescriptions.put(i, desc);
|
||||||
}
|
}
|
||||||
|
|
@ -257,6 +242,19 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows complete control over the colors drawn in the tab layout. Set with
|
||||||
|
* {@link #setCustomTabColorizer(com.google.samples.apps.iosched.ui.widget.SlidingTabLayout.TabColorizer)}.
|
||||||
|
*/
|
||||||
|
public interface TabColorizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return return the color of the indicator used when {@code position} is selected.
|
||||||
|
*/
|
||||||
|
int getIndicatorColor(int position);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
|
private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
|
||||||
private int mScrollState;
|
private int mScrollState;
|
||||||
|
|
||||||
|
|
@ -281,15 +279,6 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageScrollStateChanged(int state) {
|
|
||||||
mScrollState = state;
|
|
||||||
|
|
||||||
if (mViewPagerPageChangeListener != null) {
|
|
||||||
mViewPagerPageChangeListener.onPageScrollStateChanged(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageSelected(int position) {
|
public void onPageSelected(int position) {
|
||||||
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
|
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
|
||||||
|
|
@ -304,6 +293,15 @@ public class SlidingTabLayout extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
mScrollState = state;
|
||||||
|
|
||||||
|
if (mViewPagerPageChangeListener != null) {
|
||||||
|
mViewPagerPageChangeListener.onPageScrollStateChanged(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TabClickListener implements OnClickListener {
|
private class TabClickListener implements OnClickListener {
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,10 @@ class SlidingTabStrip extends LinearLayout {
|
||||||
private final Paint mSelectedIndicatorPaint;
|
private final Paint mSelectedIndicatorPaint;
|
||||||
|
|
||||||
private final int mDefaultBottomBorderColor;
|
private final int mDefaultBottomBorderColor;
|
||||||
|
private final SimpleTabColorizer mDefaultTabColorizer;
|
||||||
private int mSelectedPosition;
|
private int mSelectedPosition;
|
||||||
private float mSelectionOffset;
|
private float mSelectionOffset;
|
||||||
|
|
||||||
private SlidingTabLayout.TabColorizer mCustomTabColorizer;
|
private SlidingTabLayout.TabColorizer mCustomTabColorizer;
|
||||||
private final SimpleTabColorizer mDefaultTabColorizer;
|
|
||||||
|
|
||||||
SlidingTabStrip(Context context) {
|
SlidingTabStrip(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
|
|
@ -75,6 +73,13 @@ class SlidingTabStrip extends LinearLayout {
|
||||||
mSelectedIndicatorPaint = new Paint();
|
mSelectedIndicatorPaint = new Paint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the alpha value of the {@code color} to be the given {@code alpha} value.
|
||||||
|
*/
|
||||||
|
private static int setColorAlpha(int color, byte alpha) {
|
||||||
|
return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
|
||||||
|
}
|
||||||
|
|
||||||
void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
|
void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
|
||||||
mCustomTabColorizer = customTabColorizer;
|
mCustomTabColorizer = customTabColorizer;
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
@ -132,13 +137,6 @@ class SlidingTabStrip extends LinearLayout {
|
||||||
canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
|
canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the alpha value of the {@code color} to be the given {@code alpha} value.
|
|
||||||
*/
|
|
||||||
private static int setColorAlpha(int color, byte alpha) {
|
|
||||||
return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blend {@code color1} and {@code color2} using the given ratio.
|
* Blend {@code color1} and {@code color2} using the given ratio.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -43,13 +43,6 @@ public class App extends Application {
|
||||||
return playerRemote;
|
return playerRemote;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SharedPreferences getDefaultSharedPreferences() {
|
|
||||||
if (defaultSharedPreferences == null) {
|
|
||||||
defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
}
|
|
||||||
return defaultSharedPreferences;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAppTheme() {
|
public int getAppTheme() {
|
||||||
if (appTheme == 0) {
|
if (appTheme == 0) {
|
||||||
appTheme = getDefaultSharedPreferences().getInt(AppKeys.SP_THEME, R.style.Theme_MaterialMusic);
|
appTheme = getDefaultSharedPreferences().getInt(AppKeys.SP_THEME, R.style.Theme_MaterialMusic);
|
||||||
|
|
@ -57,6 +50,13 @@ public class App extends Application {
|
||||||
return appTheme;
|
return appTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SharedPreferences getDefaultSharedPreferences() {
|
||||||
|
if (defaultSharedPreferences == null) {
|
||||||
|
defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
}
|
||||||
|
return defaultSharedPreferences;
|
||||||
|
}
|
||||||
|
|
||||||
public void setAppTheme(int appTheme) {
|
public void setAppTheme(int appTheme) {
|
||||||
this.appTheme = appTheme;
|
this.appTheme = appTheme;
|
||||||
defaultSharedPreferences.edit().putInt(AppKeys.SP_THEME, appTheme);
|
defaultSharedPreferences.edit().putInt(AppKeys.SP_THEME, appTheme);
|
||||||
|
|
@ -70,15 +70,15 @@ public class App extends Application {
|
||||||
return getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
|
return getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addToRequestQueue(Request request) {
|
||||||
|
request.setTag(TAG);
|
||||||
|
getRequestQueue().add(request);
|
||||||
|
}
|
||||||
|
|
||||||
public RequestQueue getRequestQueue() {
|
public RequestQueue getRequestQueue() {
|
||||||
if (requestQueue == null) {
|
if (requestQueue == null) {
|
||||||
requestQueue = Volley.newRequestQueue(this);
|
requestQueue = Volley.newRequestQueue(this);
|
||||||
}
|
}
|
||||||
return requestQueue;
|
return requestQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToRequestQueue(Request request) {
|
|
||||||
request.setTag(TAG);
|
|
||||||
getRequestQueue().add(request);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,23 +36,6 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
private MusicService musicService;
|
private MusicService musicService;
|
||||||
private Intent musicServiceIntent;
|
private Intent musicServiceIntent;
|
||||||
private boolean musicBound = false;
|
private boolean musicBound = false;
|
||||||
|
|
||||||
public MusicPlayerRemote(Context context) {
|
|
||||||
app = (App) context.getApplicationContext();
|
|
||||||
playingQueue = new ArrayList<>();
|
|
||||||
restoredOriginalQueue = new ArrayList<>();
|
|
||||||
onMusicRemoteEventListeners = new ArrayList<>();
|
|
||||||
startAndBindService();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startAndBindService() {
|
|
||||||
if (musicServiceIntent == null) {
|
|
||||||
musicServiceIntent = new Intent(app, MusicService.class);
|
|
||||||
app.bindService(musicServiceIntent, musicConnection, Context.BIND_AUTO_CREATE);
|
|
||||||
app.startService(musicServiceIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ServiceConnection musicConnection = new ServiceConnection() {
|
private ServiceConnection musicConnection = new ServiceConnection() {
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
|
@ -71,6 +54,22 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public MusicPlayerRemote(Context context) {
|
||||||
|
app = (App) context.getApplicationContext();
|
||||||
|
playingQueue = new ArrayList<>();
|
||||||
|
restoredOriginalQueue = new ArrayList<>();
|
||||||
|
onMusicRemoteEventListeners = new ArrayList<>();
|
||||||
|
startAndBindService();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startAndBindService() {
|
||||||
|
if (musicServiceIntent == null) {
|
||||||
|
musicServiceIntent = new Intent(app, MusicService.class);
|
||||||
|
app.bindService(musicServiceIntent, musicConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
app.startService(musicServiceIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean playSongAt(final int position) {
|
public boolean playSongAt(final int position) {
|
||||||
if (musicBound) {
|
if (musicBound) {
|
||||||
musicService.playSongAt(position);
|
musicService.playSongAt(position);
|
||||||
|
|
@ -126,6 +125,21 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void openQueue(final List<Song> playingQueue, final int startPosition, final boolean startPlaying) {
|
||||||
|
this.playingQueue = playingQueue;
|
||||||
|
if (musicBound) {
|
||||||
|
musicService.openQueue(this.playingQueue, startPosition, startPlaying);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Song getCurrentSong() {
|
||||||
|
final int position = getPosition();
|
||||||
|
if (position != -1) {
|
||||||
|
return getPlayingQueue().get(position);
|
||||||
|
}
|
||||||
|
return new Song();
|
||||||
|
}
|
||||||
|
|
||||||
public int getPosition() {
|
public int getPosition() {
|
||||||
if (musicBound) {
|
if (musicBound) {
|
||||||
position = musicService.getPosition();
|
position = musicService.getPosition();
|
||||||
|
|
@ -140,13 +154,6 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openQueue(final List<Song> playingQueue, final int startPosition, final boolean startPlaying) {
|
|
||||||
this.playingQueue = playingQueue;
|
|
||||||
if (musicBound) {
|
|
||||||
musicService.openQueue(this.playingQueue, startPosition, startPlaying);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Song> getPlayingQueue() {
|
public List<Song> getPlayingQueue() {
|
||||||
if (musicBound) {
|
if (musicBound) {
|
||||||
playingQueue = musicService.getPlayingQueue();
|
playingQueue = musicService.getPlayingQueue();
|
||||||
|
|
@ -154,14 +161,6 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
return playingQueue;
|
return playingQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Song getCurrentSong() {
|
|
||||||
final int position = getPosition();
|
|
||||||
if (position != -1) {
|
|
||||||
return getPlayingQueue().get(position);
|
|
||||||
}
|
|
||||||
return new Song();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSongProgressMillis() {
|
public int getSongProgressMillis() {
|
||||||
if (isPlayerPrepared()) {
|
if (isPlayerPrepared()) {
|
||||||
return musicService.getSongProgressMillis();
|
return musicService.getSongProgressMillis();
|
||||||
|
|
@ -169,6 +168,13 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPlayerPrepared() {
|
||||||
|
if (musicBound) {
|
||||||
|
return musicService.isPlayerPrepared();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public int getSongDurationMillis() {
|
public int getSongDurationMillis() {
|
||||||
if (isPlayerPrepared()) {
|
if (isPlayerPrepared()) {
|
||||||
return musicService.getSongDurationMillis();
|
return musicService.getSongDurationMillis();
|
||||||
|
|
@ -186,13 +192,6 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlayerPrepared() {
|
|
||||||
if (musicBound) {
|
|
||||||
return musicService.isPlayerPrepared();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRepeatMode() {
|
public int getRepeatMode() {
|
||||||
if (musicBound) {
|
if (musicBound) {
|
||||||
return musicService.getRepeatMode();
|
return musicService.getRepeatMode();
|
||||||
|
|
@ -223,15 +222,15 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveSong(int from, int to){
|
public void moveSong(int from, int to) {
|
||||||
final int currentPosition = getPosition();
|
final int currentPosition = getPosition();
|
||||||
Song songToMove = getPlayingQueue().remove(from);
|
Song songToMove = getPlayingQueue().remove(from);
|
||||||
getPlayingQueue().add(to, songToMove);
|
getPlayingQueue().add(to, songToMove);
|
||||||
if(from > currentPosition && to <= currentPosition){
|
if (from > currentPosition && to <= currentPosition) {
|
||||||
setPosition(getPosition() + 1);
|
setPosition(getPosition() + 1);
|
||||||
} else if(from < currentPosition && to >= currentPosition){
|
} else if (from < currentPosition && to >= currentPosition) {
|
||||||
setPosition(getPosition() - 1);
|
setPosition(getPosition() - 1);
|
||||||
} else if(from == currentPosition){
|
} else if (from == currentPosition) {
|
||||||
setPosition(to);
|
setPosition(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -241,6 +240,13 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
notifyOnMusicRemoteEventListeners(event.getAction());
|
notifyOnMusicRemoteEventListeners(event.getAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyOnMusicRemoteEventListeners(int event) {
|
||||||
|
MusicRemoteEvent musicRemoteEvent = new MusicRemoteEvent(event);
|
||||||
|
for (OnMusicRemoteEventListener listener : onMusicRemoteEventListeners) {
|
||||||
|
listener.onMusicRemoteEvent(musicRemoteEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addOnMusicRemoteEventListener(OnMusicRemoteEventListener onMusicRemoteEventListener) {
|
public void addOnMusicRemoteEventListener(OnMusicRemoteEventListener onMusicRemoteEventListener) {
|
||||||
onMusicRemoteEventListeners.add(onMusicRemoteEventListener);
|
onMusicRemoteEventListeners.add(onMusicRemoteEventListener);
|
||||||
}
|
}
|
||||||
|
|
@ -253,13 +259,6 @@ public class MusicPlayerRemote implements OnMusicRemoteEventListener {
|
||||||
onMusicRemoteEventListeners.clear();
|
onMusicRemoteEventListeners.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyOnMusicRemoteEventListeners(int event) {
|
|
||||||
MusicRemoteEvent musicRemoteEvent = new MusicRemoteEvent(event);
|
|
||||||
for (OnMusicRemoteEventListener listener : onMusicRemoteEventListeners) {
|
|
||||||
listener.onMusicRemoteEvent(musicRemoteEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void restorePreviousState() {
|
public void restorePreviousState() {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -64,26 +64,6 @@ public class NotificationHelper {
|
||||||
service.startForeground(NOTIFICATION_ID, notification);
|
service.startForeground(NOTIFICATION_ID, notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void killNotification() {
|
|
||||||
service.stopForeground(true);
|
|
||||||
notification = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updatePlayState(final boolean isPlaying) {
|
|
||||||
if (notification == null || notificationManager == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (notificationLayout != null) {
|
|
||||||
notificationLayout.setImageViewResource(R.id.button_toggle_play_pause,
|
|
||||||
isPlaying ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp);
|
|
||||||
}
|
|
||||||
if (notificationLayoutExpanded != null) {
|
|
||||||
notificationLayoutExpanded.setImageViewResource(R.id.button_toggle_play_pause,
|
|
||||||
isPlaying ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp);
|
|
||||||
}
|
|
||||||
notificationManager.notify(NOTIFICATION_ID, notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PendingIntent getOpenMusicControllerPendingIntent() {
|
private PendingIntent getOpenMusicControllerPendingIntent() {
|
||||||
Intent result = new Intent(service, MusicControllerActivity.class);
|
Intent result = new Intent(service, MusicControllerActivity.class);
|
||||||
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(service);
|
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(service);
|
||||||
|
|
@ -160,13 +140,6 @@ public class NotificationHelper {
|
||||||
notificationLayout.setTextViewText(R.id.song_artist, song.title);
|
notificationLayout.setTextViewText(R.id.song_artist, song.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpExpandedLayout(Song song) {
|
|
||||||
loadAlbumArt(notificationLayoutExpanded, MusicUtil.getAlbumArtUri(song.albumId).toString());
|
|
||||||
notificationLayoutExpanded.setTextViewText(R.id.song_title, song.title);
|
|
||||||
notificationLayoutExpanded.setTextViewText(R.id.song_artist, song.artistName);
|
|
||||||
notificationLayoutExpanded.setTextViewText(R.id.album_title, song.albumName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loadAlbumArt(RemoteViews notificationView, String albumArtUri) {
|
private static void loadAlbumArt(RemoteViews notificationView, String albumArtUri) {
|
||||||
Bitmap albumArtBitmap = ImageLoader.getInstance().loadImageSync(albumArtUri);
|
Bitmap albumArtBitmap = ImageLoader.getInstance().loadImageSync(albumArtUri);
|
||||||
if (albumArtBitmap == null) {
|
if (albumArtBitmap == null) {
|
||||||
|
|
@ -175,4 +148,31 @@ public class NotificationHelper {
|
||||||
notificationView.setImageViewBitmap(R.id.album_art, albumArtBitmap);
|
notificationView.setImageViewBitmap(R.id.album_art, albumArtBitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpExpandedLayout(Song song) {
|
||||||
|
loadAlbumArt(notificationLayoutExpanded, MusicUtil.getAlbumArtUri(song.albumId).toString());
|
||||||
|
notificationLayoutExpanded.setTextViewText(R.id.song_title, song.title);
|
||||||
|
notificationLayoutExpanded.setTextViewText(R.id.song_artist, song.artistName);
|
||||||
|
notificationLayoutExpanded.setTextViewText(R.id.album_title, song.albumName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void killNotification() {
|
||||||
|
service.stopForeground(true);
|
||||||
|
notification = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePlayState(final boolean isPlaying) {
|
||||||
|
if (notification == null || notificationManager == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (notificationLayout != null) {
|
||||||
|
notificationLayout.setImageViewResource(R.id.button_toggle_play_pause,
|
||||||
|
isPlaying ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp);
|
||||||
|
}
|
||||||
|
if (notificationLayoutExpanded != null) {
|
||||||
|
notificationLayoutExpanded.setImageViewResource(R.id.button_toggle_play_pause,
|
||||||
|
isPlaying ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp);
|
||||||
|
}
|
||||||
|
notificationManager.notify(NOTIFICATION_ID, notification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.kabouzeid.materialmusic.App;
|
import com.kabouzeid.materialmusic.App;
|
||||||
import com.kabouzeid.materialmusic.R;
|
import com.kabouzeid.materialmusic.R;
|
||||||
import com.kabouzeid.materialmusic.adapter.PlayingQueueAdapter;
|
import com.kabouzeid.materialmusic.adapter.PlayingQueueAdapter;
|
||||||
import com.kabouzeid.materialmusic.model.Song;
|
|
||||||
import com.mobeta.android.dslv.DragSortListView;
|
import com.mobeta.android.dslv.DragSortListView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,15 @@ public class LastFMAlbumInfoUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JSONArray getAlbumImageArrayFromJSON(JSONObject rootJSON) {
|
||||||
|
try {
|
||||||
|
return rootJSON.getJSONObject("album").getJSONArray("image");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
//Log.e(TAG, "Error while getting album image array from JSON parameter!", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String getAlbumImageUrlFromJSON(JSONObject rootJSON) {
|
public static String getAlbumImageUrlFromJSON(JSONObject rootJSON) {
|
||||||
try {
|
try {
|
||||||
JSONArray images = getAlbumImageArrayFromJSON(rootJSON);
|
JSONArray images = getAlbumImageArrayFromJSON(rootJSON);
|
||||||
|
|
@ -71,15 +80,6 @@ public class LastFMAlbumInfoUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSONArray getAlbumImageArrayFromJSON(JSONObject rootJSON) {
|
|
||||||
try {
|
|
||||||
return rootJSON.getJSONObject("album").getJSONArray("image");
|
|
||||||
} catch (JSONException e) {
|
|
||||||
//Log.e(TAG, "Error while getting album image array from JSON parameter!", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void saveAlbumJSONDataToCacheAndDisk(Context context, String album, String artist, JSONObject jsonObject) {
|
public static void saveAlbumJSONDataToCacheAndDisk(Context context, String album, String artist, JSONObject jsonObject) {
|
||||||
Log.i(TAG, "Saving new JSON album data for " + album + "...");
|
Log.i(TAG, "Saving new JSON album data for " + album + "...");
|
||||||
AlbumJSONStore.getInstance(context).addAlbumJSON(album + artist, jsonObject.toString());
|
AlbumJSONStore.getInstance(context).addAlbumJSON(album + artist, jsonObject.toString());
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,15 @@ public class LastFMArtistInfoUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JSONArray getArtistImageArrayFromJSON(JSONObject rootJSON) {
|
||||||
|
try {
|
||||||
|
return rootJSON.getJSONObject("artist").getJSONArray("image");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
//Log.e(TAG, "Error while getting artist image array from JSON parameter!", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String getArtistImageUrlFromJSON(JSONObject rootJSON) {
|
public static String getArtistImageUrlFromJSON(JSONObject rootJSON) {
|
||||||
try {
|
try {
|
||||||
JSONArray images = getArtistImageArrayFromJSON(rootJSON);
|
JSONArray images = getArtistImageArrayFromJSON(rootJSON);
|
||||||
|
|
@ -70,15 +79,6 @@ public class LastFMArtistInfoUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSONArray getArtistImageArrayFromJSON(JSONObject rootJSON) {
|
|
||||||
try {
|
|
||||||
return rootJSON.getJSONObject("artist").getJSONArray("image");
|
|
||||||
} catch (JSONException e) {
|
|
||||||
//Log.e(TAG, "Error while getting artist image array from JSON parameter!", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getArtistBiographyFromJSON(JSONObject rootJSON) {
|
public static String getArtistBiographyFromJSON(JSONObject rootJSON) {
|
||||||
try {
|
try {
|
||||||
return rootJSON.getJSONObject("artist").getJSONObject("bio").getString("content");
|
return rootJSON.getJSONObject("artist").getJSONObject("bio").getString("content");
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,24 @@ public class AlbumLoader {
|
||||||
return albums;
|
return albums;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Cursor makeAlbumCursor(final Context context) {
|
||||||
|
return context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
|
||||||
|
new String[]{
|
||||||
|
/* 0 */
|
||||||
|
BaseColumns._ID,
|
||||||
|
/* 1 */
|
||||||
|
MediaStore.Audio.AlbumColumns.ALBUM,
|
||||||
|
/* 2 */
|
||||||
|
MediaStore.Audio.AlbumColumns.ARTIST,
|
||||||
|
/* 3 */
|
||||||
|
MediaStore.Audio.Media.ARTIST_ID,
|
||||||
|
/* 4 */
|
||||||
|
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
|
||||||
|
/* 5 */
|
||||||
|
MediaStore.Audio.AlbumColumns.FIRST_YEAR
|
||||||
|
}, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static Album getAlbum(Context context, int albumId) {
|
public static Album getAlbum(Context context, int albumId) {
|
||||||
Cursor cursor = makeAlbumCursor(context);
|
Cursor cursor = makeAlbumCursor(context);
|
||||||
Album album = new Album();
|
Album album = new Album();
|
||||||
|
|
@ -85,22 +103,4 @@ public class AlbumLoader {
|
||||||
}
|
}
|
||||||
return albums;
|
return albums;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Cursor makeAlbumCursor(final Context context) {
|
|
||||||
return context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
|
|
||||||
new String[]{
|
|
||||||
/* 0 */
|
|
||||||
BaseColumns._ID,
|
|
||||||
/* 1 */
|
|
||||||
MediaStore.Audio.AlbumColumns.ALBUM,
|
|
||||||
/* 2 */
|
|
||||||
MediaStore.Audio.AlbumColumns.ARTIST,
|
|
||||||
/* 3 */
|
|
||||||
MediaStore.Audio.Media.ARTIST_ID,
|
|
||||||
/* 4 */
|
|
||||||
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
|
|
||||||
/* 5 */
|
|
||||||
MediaStore.Audio.AlbumColumns.FIRST_YEAR
|
|
||||||
}, null, null, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,20 @@ public class ArtistLoader {
|
||||||
return artists;
|
return artists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Cursor makeArtistCursor(final Context context) {
|
||||||
|
return context.getContentResolver().query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
|
||||||
|
new String[]{
|
||||||
|
/* 0 */
|
||||||
|
BaseColumns._ID,
|
||||||
|
/* 1 */
|
||||||
|
MediaStore.Audio.ArtistColumns.ARTIST,
|
||||||
|
/* 2 */
|
||||||
|
MediaStore.Audio.ArtistColumns.NUMBER_OF_ALBUMS,
|
||||||
|
/* 3 */
|
||||||
|
MediaStore.Audio.ArtistColumns.NUMBER_OF_TRACKS
|
||||||
|
}, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static Artist getArtist(Context context, int artistId) {
|
public static Artist getArtist(Context context, int artistId) {
|
||||||
Cursor cursor = makeArtistCursor(context);
|
Cursor cursor = makeArtistCursor(context);
|
||||||
Artist artist = new Artist();
|
Artist artist = new Artist();
|
||||||
|
|
@ -80,18 +94,4 @@ public class ArtistLoader {
|
||||||
}
|
}
|
||||||
return artists;
|
return artists;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Cursor makeArtistCursor(final Context context) {
|
|
||||||
return context.getContentResolver().query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
|
|
||||||
new String[]{
|
|
||||||
/* 0 */
|
|
||||||
BaseColumns._ID,
|
|
||||||
/* 1 */
|
|
||||||
MediaStore.Audio.ArtistColumns.ARTIST,
|
|
||||||
/* 2 */
|
|
||||||
MediaStore.Audio.ArtistColumns.NUMBER_OF_ALBUMS,
|
|
||||||
/* 3 */
|
|
||||||
MediaStore.Audio.ArtistColumns.NUMBER_OF_TRACKS
|
|
||||||
}, null, null, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,16 @@ public class SongFileLoader {
|
||||||
return songFiles;
|
return songFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Cursor makeSongFileCursor(final Context context) {
|
||||||
|
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||||
|
new String[]{
|
||||||
|
/* 0 */
|
||||||
|
BaseColumns._ID,
|
||||||
|
/* 1 */
|
||||||
|
MediaStore.Audio.AudioColumns.DATA,
|
||||||
|
}, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static String getSongFile(Context context, int queryId) {
|
public static String getSongFile(Context context, int queryId) {
|
||||||
Cursor cursor = makeSongFileCursor(context);
|
Cursor cursor = makeSongFileCursor(context);
|
||||||
String filePath = "";
|
String filePath = "";
|
||||||
|
|
@ -49,14 +59,4 @@ public class SongFileLoader {
|
||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Cursor makeSongFileCursor(final Context context) {
|
|
||||||
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
|
||||||
new String[]{
|
|
||||||
/* 0 */
|
|
||||||
BaseColumns._ID,
|
|
||||||
/* 1 */
|
|
||||||
MediaStore.Audio.AudioColumns.DATA,
|
|
||||||
}, null, null, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,30 @@ public class SongLoader {
|
||||||
return songs;
|
return songs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Cursor makeAlbumSongCursor(final Context context) {
|
||||||
|
final StringBuilder selection = new StringBuilder();
|
||||||
|
selection.append(MediaStore.Audio.AudioColumns.IS_MUSIC + "=1");
|
||||||
|
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||||
|
new String[]{
|
||||||
|
/* 0 */
|
||||||
|
BaseColumns._ID,
|
||||||
|
/* 1 */
|
||||||
|
MediaStore.Audio.AudioColumns.TITLE,
|
||||||
|
/* 2 */
|
||||||
|
MediaStore.Audio.AudioColumns.ARTIST,
|
||||||
|
/* 3 */
|
||||||
|
MediaStore.Audio.AudioColumns.ALBUM,
|
||||||
|
/* 4 */
|
||||||
|
MediaStore.Audio.AudioColumns.DURATION,
|
||||||
|
/* 5 */
|
||||||
|
MediaStore.Audio.AudioColumns.TRACK,
|
||||||
|
/* 6 */
|
||||||
|
MediaStore.Audio.AudioColumns.ARTIST_ID,
|
||||||
|
/* 7 */
|
||||||
|
MediaStore.Audio.AudioColumns.ALBUM_ID
|
||||||
|
}, selection.toString(), null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Song> getSongs(Context context, String query) {
|
public static List<Song> getSongs(Context context, String query) {
|
||||||
Cursor cursor = makeAlbumSongCursor(context);
|
Cursor cursor = makeAlbumSongCursor(context);
|
||||||
List<Song> songs = new ArrayList<>();
|
List<Song> songs = new ArrayList<>();
|
||||||
|
|
@ -90,28 +114,4 @@ public class SongLoader {
|
||||||
}
|
}
|
||||||
return song;
|
return song;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Cursor makeAlbumSongCursor(final Context context) {
|
|
||||||
final StringBuilder selection = new StringBuilder();
|
|
||||||
selection.append(MediaStore.Audio.AudioColumns.IS_MUSIC + "=1");
|
|
||||||
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
|
||||||
new String[]{
|
|
||||||
/* 0 */
|
|
||||||
BaseColumns._ID,
|
|
||||||
/* 1 */
|
|
||||||
MediaStore.Audio.AudioColumns.TITLE,
|
|
||||||
/* 2 */
|
|
||||||
MediaStore.Audio.AudioColumns.ARTIST,
|
|
||||||
/* 3 */
|
|
||||||
MediaStore.Audio.AudioColumns.ALBUM,
|
|
||||||
/* 4 */
|
|
||||||
MediaStore.Audio.AudioColumns.DURATION,
|
|
||||||
/* 5 */
|
|
||||||
MediaStore.Audio.AudioColumns.TRACK,
|
|
||||||
/* 6 */
|
|
||||||
MediaStore.Audio.AudioColumns.ARTIST_ID,
|
|
||||||
/* 7 */
|
|
||||||
MediaStore.Audio.AudioColumns.ALBUM_ID
|
|
||||||
}, selection.toString(), null, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,33 +8,33 @@ import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
|
||||||
public class AlbumJSONStore extends SQLiteOpenHelper {
|
public class AlbumJSONStore extends SQLiteOpenHelper {
|
||||||
|
|
||||||
private static final int VERSION = 1;
|
|
||||||
public static final String DATABASE_NAME = "albumJSONLastFM.db";
|
public static final String DATABASE_NAME = "albumJSONLastFM.db";
|
||||||
|
private static final int VERSION = 1;
|
||||||
private static AlbumJSONStore sInstance = null;
|
private static AlbumJSONStore sInstance = null;
|
||||||
|
|
||||||
public AlbumJSONStore(final Context context) {
|
public AlbumJSONStore(final Context context) {
|
||||||
super(context, DATABASE_NAME, null, VERSION);
|
super(context, DATABASE_NAME, null, VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(final SQLiteDatabase db) {
|
|
||||||
db.execSQL("CREATE TABLE IF NOT EXISTS " + AlbumJSONColumns.NAME +
|
|
||||||
" (" + AlbumJSONColumns.ALBUMANDARTIST_NAME + " TEXT NOT NULL," +
|
|
||||||
AlbumJSONColumns.JSON + " TEXT NOT NULL);"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + AlbumJSONColumns.NAME);
|
|
||||||
onCreate(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized AlbumJSONStore getInstance(final Context context) {
|
public static synchronized AlbumJSONStore getInstance(final Context context) {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
sInstance = new AlbumJSONStore(context.getApplicationContext());
|
sInstance = new AlbumJSONStore(context.getApplicationContext());
|
||||||
}
|
}
|
||||||
return sInstance;
|
return sInstance;
|
||||||
|
} @Override
|
||||||
|
public void onCreate(final SQLiteDatabase db) {
|
||||||
|
db.execSQL("CREATE TABLE IF NOT EXISTS " + AlbumJSONColumns.NAME +
|
||||||
|
" (" + AlbumJSONColumns.ALBUMANDARTIST_NAME + " TEXT NOT NULL," +
|
||||||
|
AlbumJSONColumns.JSON + " TEXT NOT NULL);"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteDatabase(final Context context) {
|
||||||
|
context.deleteDatabase(DATABASE_NAME);
|
||||||
|
} @Override
|
||||||
|
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
||||||
|
db.execSQL("DROP TABLE IF EXISTS " + AlbumJSONColumns.NAME);
|
||||||
|
onCreate(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAlbumJSON(final String albumAndArtistName, final String JSON) {
|
public void addAlbumJSON(final String albumAndArtistName, final String JSON) {
|
||||||
|
|
@ -82,10 +82,6 @@ public class AlbumJSONStore extends SQLiteOpenHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteDatabase(final Context context) {
|
|
||||||
context.deleteDatabase(DATABASE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeItem(final String albumAndArtistName) {
|
public void removeItem(final String albumAndArtistName) {
|
||||||
final SQLiteDatabase database = getReadableDatabase();
|
final SQLiteDatabase database = getReadableDatabase();
|
||||||
database.delete(AlbumJSONColumns.NAME, AlbumJSONColumns.ALBUMANDARTIST_NAME + " = ?", new String[]{
|
database.delete(AlbumJSONColumns.NAME, AlbumJSONColumns.ALBUMANDARTIST_NAME + " = ?", new String[]{
|
||||||
|
|
@ -100,4 +96,8 @@ public class AlbumJSONStore extends SQLiteOpenHelper {
|
||||||
public static final String JSON = "JSON";
|
public static final String JSON = "JSON";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,33 +8,33 @@ import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
|
||||||
public class ArtistJSONStore extends SQLiteOpenHelper {
|
public class ArtistJSONStore extends SQLiteOpenHelper {
|
||||||
|
|
||||||
private static final int VERSION = 1;
|
|
||||||
public static final String DATABASE_NAME = "artistJSONLastFM.db";
|
public static final String DATABASE_NAME = "artistJSONLastFM.db";
|
||||||
|
private static final int VERSION = 1;
|
||||||
private static ArtistJSONStore sInstance = null;
|
private static ArtistJSONStore sInstance = null;
|
||||||
|
|
||||||
public ArtistJSONStore(final Context context) {
|
public ArtistJSONStore(final Context context) {
|
||||||
super(context, DATABASE_NAME, null, VERSION);
|
super(context, DATABASE_NAME, null, VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(final SQLiteDatabase db) {
|
|
||||||
db.execSQL("CREATE TABLE IF NOT EXISTS " + ArtistJSONColumns.NAME +
|
|
||||||
" (" + ArtistJSONColumns.ARTIST_NAME + " TEXT NOT NULL," +
|
|
||||||
ArtistJSONColumns.JSON + " TEXT NOT NULL);"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + ArtistJSONColumns.NAME);
|
|
||||||
onCreate(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized ArtistJSONStore getInstance(final Context context) {
|
public static synchronized ArtistJSONStore getInstance(final Context context) {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
sInstance = new ArtistJSONStore(context.getApplicationContext());
|
sInstance = new ArtistJSONStore(context.getApplicationContext());
|
||||||
}
|
}
|
||||||
return sInstance;
|
return sInstance;
|
||||||
|
} @Override
|
||||||
|
public void onCreate(final SQLiteDatabase db) {
|
||||||
|
db.execSQL("CREATE TABLE IF NOT EXISTS " + ArtistJSONColumns.NAME +
|
||||||
|
" (" + ArtistJSONColumns.ARTIST_NAME + " TEXT NOT NULL," +
|
||||||
|
ArtistJSONColumns.JSON + " TEXT NOT NULL);"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteDatabase(final Context context) {
|
||||||
|
context.deleteDatabase(DATABASE_NAME);
|
||||||
|
} @Override
|
||||||
|
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
||||||
|
db.execSQL("DROP TABLE IF EXISTS " + ArtistJSONColumns.NAME);
|
||||||
|
onCreate(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addArtistJSON(final String artistName, final String JSON) {
|
public void addArtistJSON(final String artistName, final String JSON) {
|
||||||
|
|
@ -82,10 +82,6 @@ public class ArtistJSONStore extends SQLiteOpenHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteDatabase(final Context context) {
|
|
||||||
context.deleteDatabase(DATABASE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeItem(final String artistName) {
|
public void removeItem(final String artistName) {
|
||||||
final SQLiteDatabase database = getReadableDatabase();
|
final SQLiteDatabase database = getReadableDatabase();
|
||||||
database.delete(ArtistJSONColumns.NAME, ArtistJSONColumns.ARTIST_NAME + " = ?", new String[]{
|
database.delete(ArtistJSONColumns.NAME, ArtistJSONColumns.ARTIST_NAME + " = ?", new String[]{
|
||||||
|
|
@ -100,4 +96,8 @@ public class ArtistJSONStore extends SQLiteOpenHelper {
|
||||||
public static final String JSON = "JSON";
|
public static final String JSON = "JSON";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, AudioManager.OnAudioFocusChangeListener {
|
public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, AudioManager.OnAudioFocusChangeListener {
|
||||||
private static final String TAG = MusicService.class.getSimpleName();
|
|
||||||
|
|
||||||
public static final String ACTION_TOGGLE_PLAYBACK = "com.kabouzeid.materialmusic.action.TOGGLE_PLAYBACK";
|
public static final String ACTION_TOGGLE_PLAYBACK = "com.kabouzeid.materialmusic.action.TOGGLE_PLAYBACK";
|
||||||
public static final String ACTION_PLAY = "com.kabouzeid.materialmusic.action.PLAY";
|
public static final String ACTION_PLAY = "com.kabouzeid.materialmusic.action.PLAY";
|
||||||
public static final String ACTION_PAUSE = "com.kabouzeid.materialmusic.action.PAUSE";
|
public static final String ACTION_PAUSE = "com.kabouzeid.materialmusic.action.PAUSE";
|
||||||
|
|
@ -46,32 +44,13 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
public static final String ACTION_SKIP = "com.kabouzeid.materialmusic.action.SKIP";
|
public static final String ACTION_SKIP = "com.kabouzeid.materialmusic.action.SKIP";
|
||||||
public static final String ACTION_REWIND = "com.kabouzeid.materialmusic.action.REWIND";
|
public static final String ACTION_REWIND = "com.kabouzeid.materialmusic.action.REWIND";
|
||||||
public static final String ACTION_QUIT = "com.kabouzeid.materialmusic.action.QUIT";
|
public static final String ACTION_QUIT = "com.kabouzeid.materialmusic.action.QUIT";
|
||||||
|
|
||||||
public static final int SHUFFLE_MODE_NONE = 0;
|
public static final int SHUFFLE_MODE_NONE = 0;
|
||||||
public static final int SHUFFLE_MODE_SHUFFLE = 1;
|
public static final int SHUFFLE_MODE_SHUFFLE = 1;
|
||||||
|
|
||||||
public static final int REPEAT_MODE_NONE = 0;
|
public static final int REPEAT_MODE_NONE = 0;
|
||||||
public static final int REPEAT_MODE_ALL = 1;
|
public static final int REPEAT_MODE_ALL = 1;
|
||||||
public static final int REPEAT_MODE_THIS = 2;
|
public static final int REPEAT_MODE_THIS = 2;
|
||||||
|
private static final String TAG = MusicService.class.getSimpleName();
|
||||||
private MediaPlayer player;
|
|
||||||
private List<Song> playingQueue;
|
|
||||||
private List<Song> originalPlayingQueue;
|
|
||||||
private List<OnMusicRemoteEventListener> onMusicRemoteEventListeners;
|
|
||||||
private int currentSongId = -1;
|
|
||||||
private int position = -1;
|
|
||||||
private int shuffleMode;
|
|
||||||
private int repeatMode;
|
|
||||||
private final IBinder musicBind = new MusicBinder();
|
private final IBinder musicBind = new MusicBinder();
|
||||||
private boolean isPlayerPrepared;
|
|
||||||
private boolean wasPlayingBeforeFocusLoss;
|
|
||||||
private boolean thingsRegistered;
|
|
||||||
private boolean saveQueuesAgain;
|
|
||||||
private boolean isSavingQueues;
|
|
||||||
private NotificationHelper notificationHelper;
|
|
||||||
private AudioManager audioManager;
|
|
||||||
private RemoteControlClient remoteControlClient;
|
|
||||||
|
|
||||||
private final BroadcastReceiver receiver = new BroadcastReceiver() {
|
private final BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
|
@ -80,13 +59,22 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private MediaPlayer player;
|
||||||
private AudioManager getAudioManager() {
|
private List<Song> playingQueue;
|
||||||
if (audioManager == null) {
|
private List<Song> originalPlayingQueue;
|
||||||
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
private List<OnMusicRemoteEventListener> onMusicRemoteEventListeners;
|
||||||
}
|
private int currentSongId = -1;
|
||||||
return audioManager;
|
private int position = -1;
|
||||||
}
|
private int shuffleMode;
|
||||||
|
private int repeatMode;
|
||||||
|
private boolean isPlayerPrepared;
|
||||||
|
private boolean wasPlayingBeforeFocusLoss;
|
||||||
|
private boolean thingsRegistered;
|
||||||
|
private boolean saveQueuesAgain;
|
||||||
|
private boolean isSavingQueues;
|
||||||
|
private NotificationHelper notificationHelper;
|
||||||
|
private AudioManager audioManager;
|
||||||
|
private RemoteControlClient remoteControlClient;
|
||||||
|
|
||||||
public MusicService() {
|
public MusicService() {
|
||||||
}
|
}
|
||||||
|
|
@ -106,11 +94,22 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
registerEverything();
|
registerEverything();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean requestFocus() {
|
private void registerEverything() {
|
||||||
int result = getAudioManager().requestAudioFocus(this, AudioManager.STREAM_MUSIC,
|
if (!thingsRegistered) {
|
||||||
AudioManager.AUDIOFOCUS_GAIN);
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
|
||||||
|
registerReceiver(receiver, intentFilter);
|
||||||
|
getAudioManager().registerMediaButtonEventReceiver(new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class));
|
||||||
|
initRemoteControlClient();
|
||||||
|
thingsRegistered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
private AudioManager getAudioManager() {
|
||||||
|
if (audioManager == null) {
|
||||||
|
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
||||||
|
}
|
||||||
|
return audioManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initRemoteControlClient() {
|
private void initRemoteControlClient() {
|
||||||
|
|
@ -126,39 +125,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
getAudioManager().registerRemoteControlClient(remoteControlClient);
|
getAudioManager().registerRemoteControlClient(remoteControlClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerEverything() {
|
|
||||||
if (!thingsRegistered) {
|
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
|
||||||
intentFilter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
|
|
||||||
registerReceiver(receiver, intentFilter);
|
|
||||||
getAudioManager().registerMediaButtonEventReceiver(new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class));
|
|
||||||
initRemoteControlClient();
|
|
||||||
thingsRegistered = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unregisterEverything() {
|
|
||||||
if (thingsRegistered) {
|
|
||||||
unregisterReceiver(receiver);
|
|
||||||
getAudioManager().unregisterRemoteControlClient(remoteControlClient);
|
|
||||||
getAudioManager().unregisterMediaButtonEventReceiver(new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class));
|
|
||||||
getAudioManager().abandonAudioFocus(this);
|
|
||||||
thingsRegistered = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateRemoteControlClient() {
|
|
||||||
Song song = getPlayingQueue().get(getPosition());
|
|
||||||
Bitmap loadedImage = ImageLoader.getInstance().loadImageSync(MusicUtil.getAlbumArtUri(song.albumId).toString());
|
|
||||||
remoteControlClient
|
|
||||||
.editMetadata(false)
|
|
||||||
.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, song.artistName)
|
|
||||||
.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, song.title)
|
|
||||||
.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, song.duration)
|
|
||||||
.putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, loadedImage)
|
|
||||||
.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
setUpMediaPlayerIfNeeded();
|
setUpMediaPlayerIfNeeded();
|
||||||
|
|
@ -196,6 +162,12 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
unregisterEverything();
|
||||||
|
killEverythingAndReleaseResources();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
Log.i(TAG, "onBind");
|
Log.i(TAG, "onBind");
|
||||||
|
|
@ -209,6 +181,77 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void unregisterEverything() {
|
||||||
|
if (thingsRegistered) {
|
||||||
|
unregisterReceiver(receiver);
|
||||||
|
getAudioManager().unregisterRemoteControlClient(remoteControlClient);
|
||||||
|
getAudioManager().unregisterMediaButtonEventReceiver(new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class));
|
||||||
|
getAudioManager().abandonAudioFocus(this);
|
||||||
|
thingsRegistered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void killEverythingAndReleaseResources() {
|
||||||
|
stopPlaying();
|
||||||
|
notificationHelper.killNotification();
|
||||||
|
savePosition();
|
||||||
|
saveQueues();
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopPlaying() {
|
||||||
|
isPlayerPrepared = false;
|
||||||
|
player.stop();
|
||||||
|
notificationHelper.updatePlayState(isPlaying());
|
||||||
|
remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
|
||||||
|
player.release();
|
||||||
|
player = null;
|
||||||
|
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPlaying() {
|
||||||
|
return player != null && player.isPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyOnMusicRemoteEventListeners(int event) {
|
||||||
|
MusicRemoteEvent musicRemoteEvent = new MusicRemoteEvent(event);
|
||||||
|
for (OnMusicRemoteEventListener listener : onMusicRemoteEventListeners) {
|
||||||
|
listener.onMusicRemoteEvent(musicRemoteEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveQueues() {
|
||||||
|
try {
|
||||||
|
InternalStorageUtil.writeObject(MusicService.this, AppKeys.IS_PLAYING_QUEUE, playingQueue);
|
||||||
|
InternalStorageUtil.writeObject(MusicService.this, AppKeys.IS_ORIGINAL_PLAYING_QUEUE, originalPlayingQueue);
|
||||||
|
Log.i(TAG, "saved current queue state");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "error while saving music service queue state", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void savePosition() {
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
InternalStorageUtil.writeObject(MusicService.this, AppKeys.IS_POSITION_IN_QUEUE, getPosition());
|
||||||
|
Log.i(TAG, "saved current position state");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "error while saving music service position state", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(int position) {
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCompletion(MediaPlayer mp) {
|
public void onCompletion(MediaPlayer mp) {
|
||||||
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.SONG_COMPLETED);
|
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.SONG_COMPLETED);
|
||||||
|
|
@ -222,6 +265,112 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void playNextSong() {
|
||||||
|
if (position != -1) {
|
||||||
|
if (isPlayerPrepared) {
|
||||||
|
setPosition(getNextPosition());
|
||||||
|
playSong();
|
||||||
|
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.NEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playSong() {
|
||||||
|
if (requestFocus()) {
|
||||||
|
setUpMediaPlayerIfNeeded();
|
||||||
|
registerEverything();
|
||||||
|
isPlayerPrepared = false;
|
||||||
|
player.reset();
|
||||||
|
Uri trackUri = getCurrentPositionTrackUri();
|
||||||
|
try {
|
||||||
|
player.setDataSource(getApplicationContext(), trackUri);
|
||||||
|
currentSongId = getPlayingQueue().get(getPosition()).id;
|
||||||
|
updateNotification();
|
||||||
|
updateRemoteControlClient();
|
||||||
|
player.prepareAsync();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("MUSIC SERVICE", "Error setting data source", e);
|
||||||
|
player.reset();
|
||||||
|
Toast.makeText(getApplicationContext(), getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show();
|
||||||
|
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.STOP);
|
||||||
|
notificationHelper.updatePlayState(false);
|
||||||
|
remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, getResources().getString(R.string.audio_focus_denied), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean requestFocus() {
|
||||||
|
int result = getAudioManager().requestAudioFocus(this, AudioManager.STREAM_MUSIC,
|
||||||
|
AudioManager.AUDIOFOCUS_GAIN);
|
||||||
|
|
||||||
|
return (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRemoteControlClient() {
|
||||||
|
Song song = getPlayingQueue().get(getPosition());
|
||||||
|
Bitmap loadedImage = ImageLoader.getInstance().loadImageSync(MusicUtil.getAlbumArtUri(song.albumId).toString());
|
||||||
|
remoteControlClient
|
||||||
|
.editMetadata(false)
|
||||||
|
.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, song.artistName)
|
||||||
|
.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, song.title)
|
||||||
|
.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, song.duration)
|
||||||
|
.putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, loadedImage)
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpMediaPlayerIfNeeded() {
|
||||||
|
if (player == null) {
|
||||||
|
player = new MediaPlayer();
|
||||||
|
|
||||||
|
player.setOnPreparedListener(this);
|
||||||
|
player.setOnCompletionListener(this);
|
||||||
|
player.setOnErrorListener(this);
|
||||||
|
|
||||||
|
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||||
|
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateNotification() {
|
||||||
|
notificationHelper.buildNotification(playingQueue.get(position), isPlaying());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uri getCurrentPositionTrackUri() {
|
||||||
|
return ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, playingQueue.get(position).id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNextPosition() {
|
||||||
|
int position = 0;
|
||||||
|
switch (repeatMode) {
|
||||||
|
case REPEAT_MODE_NONE:
|
||||||
|
position = getPosition() + 1;
|
||||||
|
if (isLastTrack()) {
|
||||||
|
position -= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REPEAT_MODE_ALL:
|
||||||
|
position = getPosition() + 1;
|
||||||
|
if (isLastTrack()) {
|
||||||
|
position = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REPEAT_MODE_THIS:
|
||||||
|
position = getPosition();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLastTrack() {
|
||||||
|
return getPosition() == getPlayingQueue().size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Song> getPlayingQueue() {
|
||||||
|
return playingQueue;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onError(MediaPlayer mp, int what, int extra) {
|
public boolean onError(MediaPlayer mp, int what, int extra) {
|
||||||
isPlayerPrepared = false;
|
isPlayerPrepared = false;
|
||||||
|
|
@ -240,37 +389,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
savePosition();
|
savePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
unregisterEverything();
|
|
||||||
killEverythingAndReleaseResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void killEverythingAndReleaseResources() {
|
|
||||||
stopPlaying();
|
|
||||||
notificationHelper.killNotification();
|
|
||||||
savePosition();
|
|
||||||
saveQueues();
|
|
||||||
stopSelf();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpMediaPlayerIfNeeded() {
|
|
||||||
if (player == null) {
|
|
||||||
player = new MediaPlayer();
|
|
||||||
|
|
||||||
player.setOnPreparedListener(this);
|
|
||||||
player.setOnCompletionListener(this);
|
|
||||||
player.setOnErrorListener(this);
|
|
||||||
|
|
||||||
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
|
||||||
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateNotification() {
|
|
||||||
notificationHelper.buildNotification(playingQueue.get(position), isPlaying());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void openQueue(final List<Song> playingQueue, final int startPosition, final boolean startPlaying) {
|
public void openQueue(final List<Song> playingQueue, final int startPosition, final boolean startPlaying) {
|
||||||
if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue.size()) {
|
if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue.size()) {
|
||||||
originalPlayingQueue = playingQueue;
|
originalPlayingQueue = playingQueue;
|
||||||
|
|
@ -287,6 +405,29 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void saveState() {
|
||||||
|
saveQueuesAsync();
|
||||||
|
savePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveQueuesAsync() {
|
||||||
|
if (isSavingQueues) {
|
||||||
|
saveQueuesAgain = true;
|
||||||
|
} else {
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
isSavingQueues = true;
|
||||||
|
do {
|
||||||
|
saveQueuesAgain = false;
|
||||||
|
saveQueues();
|
||||||
|
} while (saveQueuesAgain);
|
||||||
|
isSavingQueues = false;
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void restorePreviousState(final List<Song> originalPlayingQueue, final List<Song> playingQueue, int position) {
|
public void restorePreviousState(final List<Song> originalPlayingQueue, final List<Song> playingQueue, int position) {
|
||||||
this.originalPlayingQueue = originalPlayingQueue;
|
this.originalPlayingQueue = originalPlayingQueue;
|
||||||
this.playingQueue = playingQueue;
|
this.playingQueue = playingQueue;
|
||||||
|
|
@ -294,18 +435,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
saveState();
|
saveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Song> getPlayingQueue() {
|
|
||||||
return playingQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPosition(int position) {
|
|
||||||
this.position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCurrentSongId() {
|
public long getCurrentSongId() {
|
||||||
return currentSongId;
|
return currentSongId;
|
||||||
}
|
}
|
||||||
|
|
@ -353,12 +482,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MusicBinder extends Binder {
|
|
||||||
public MusicService getService() {
|
|
||||||
return MusicService.this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playSongAt(final int position) {
|
public void playSongAt(final int position) {
|
||||||
if (position < getPlayingQueue().size() && position >= 0) {
|
if (position < getPlayingQueue().size() && position >= 0) {
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
|
|
@ -368,32 +491,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playSong() {
|
|
||||||
if (requestFocus()) {
|
|
||||||
setUpMediaPlayerIfNeeded();
|
|
||||||
registerEverything();
|
|
||||||
isPlayerPrepared = false;
|
|
||||||
player.reset();
|
|
||||||
Uri trackUri = getCurrentPositionTrackUri();
|
|
||||||
try {
|
|
||||||
player.setDataSource(getApplicationContext(), trackUri);
|
|
||||||
currentSongId = getPlayingQueue().get(getPosition()).id;
|
|
||||||
updateNotification();
|
|
||||||
updateRemoteControlClient();
|
|
||||||
player.prepareAsync();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("MUSIC SERVICE", "Error setting data source", e);
|
|
||||||
player.reset();
|
|
||||||
Toast.makeText(getApplicationContext(), getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show();
|
|
||||||
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.STOP);
|
|
||||||
notificationHelper.updatePlayState(false);
|
|
||||||
remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Toast.makeText(this, getResources().getString(R.string.audio_focus_denied), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pausePlaying() {
|
public void pausePlaying() {
|
||||||
if (isPlaying()) {
|
if (isPlaying()) {
|
||||||
player.pause();
|
player.pause();
|
||||||
|
|
@ -418,26 +515,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopPlaying() {
|
|
||||||
isPlayerPrepared = false;
|
|
||||||
player.stop();
|
|
||||||
notificationHelper.updatePlayState(isPlaying());
|
|
||||||
remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
|
|
||||||
player.release();
|
|
||||||
player = null;
|
|
||||||
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.STOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playNextSong() {
|
|
||||||
if (position != -1) {
|
|
||||||
if (isPlayerPrepared) {
|
|
||||||
setPosition(getNextPosition());
|
|
||||||
playSong();
|
|
||||||
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.NEXT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playPreviousSong() {
|
public void playPreviousSong() {
|
||||||
if (position != -1) {
|
if (position != -1) {
|
||||||
setPosition(getPreviousPosition());
|
setPosition(getPreviousPosition());
|
||||||
|
|
@ -456,28 +533,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextPosition() {
|
|
||||||
int position = 0;
|
|
||||||
switch (repeatMode) {
|
|
||||||
case REPEAT_MODE_NONE:
|
|
||||||
position = getPosition() + 1;
|
|
||||||
if (isLastTrack()) {
|
|
||||||
position -= 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case REPEAT_MODE_ALL:
|
|
||||||
position = getPosition() + 1;
|
|
||||||
if (isLastTrack()) {
|
|
||||||
position = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case REPEAT_MODE_THIS:
|
|
||||||
position = getPosition();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPreviousPosition() {
|
public int getPreviousPosition() {
|
||||||
int position = 0;
|
int position = 0;
|
||||||
switch (repeatMode) {
|
switch (repeatMode) {
|
||||||
|
|
@ -500,14 +555,6 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlaying() {
|
|
||||||
return player != null && player.isPlaying();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Uri getCurrentPositionTrackUri() {
|
|
||||||
return ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, playingQueue.get(position).id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSongProgressMillis() {
|
public int getSongProgressMillis() {
|
||||||
return player.getCurrentPosition();
|
return player.getCurrentPosition();
|
||||||
}
|
}
|
||||||
|
|
@ -524,66 +571,52 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
return player != null && isPlayerPrepared;
|
return player != null && isPlayerPrepared;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isLastTrack() {
|
|
||||||
return getPosition() == getPlayingQueue().size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyOnMusicRemoteEventListeners(int event) {
|
|
||||||
MusicRemoteEvent musicRemoteEvent = new MusicRemoteEvent(event);
|
|
||||||
for (OnMusicRemoteEventListener listener : onMusicRemoteEventListeners) {
|
|
||||||
listener.onMusicRemoteEvent(musicRemoteEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addOnMusicRemoteEventListener(OnMusicRemoteEventListener onMusicRemoteEventListener) {
|
public void addOnMusicRemoteEventListener(OnMusicRemoteEventListener onMusicRemoteEventListener) {
|
||||||
onMusicRemoteEventListeners.add(onMusicRemoteEventListener);
|
onMusicRemoteEventListeners.add(onMusicRemoteEventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveState() {
|
public void cycleRepeatMode() {
|
||||||
saveQueuesAsync();
|
switch (getRepeatMode()) {
|
||||||
savePosition();
|
case REPEAT_MODE_NONE:
|
||||||
|
setRepeatMode(REPEAT_MODE_ALL);
|
||||||
|
break;
|
||||||
|
case REPEAT_MODE_ALL:
|
||||||
|
setRepeatMode(REPEAT_MODE_THIS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setRepeatMode(REPEAT_MODE_NONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveQueuesAsync() {
|
public int getRepeatMode() {
|
||||||
if (isSavingQueues) {
|
return repeatMode;
|
||||||
saveQueuesAgain = true;
|
}
|
||||||
|
|
||||||
|
public void setRepeatMode(final int repeatMode) {
|
||||||
|
switch (repeatMode) {
|
||||||
|
case REPEAT_MODE_NONE:
|
||||||
|
case REPEAT_MODE_ALL:
|
||||||
|
case REPEAT_MODE_THIS:
|
||||||
|
this.repeatMode = repeatMode;
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(this).edit()
|
||||||
|
.putInt(AppKeys.SP_REPEAT_MODE, repeatMode)
|
||||||
|
.apply();
|
||||||
|
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.REPEAT_MODE_CHANGED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggleShuffle() {
|
||||||
|
if (getShuffleMode() == SHUFFLE_MODE_NONE) {
|
||||||
|
setShuffleMode(SHUFFLE_MODE_SHUFFLE);
|
||||||
} else {
|
} else {
|
||||||
new Thread(new Runnable() {
|
setShuffleMode(SHUFFLE_MODE_NONE);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
isSavingQueues = true;
|
|
||||||
do {
|
|
||||||
saveQueuesAgain = false;
|
|
||||||
saveQueues();
|
|
||||||
} while (saveQueuesAgain);
|
|
||||||
isSavingQueues = false;
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveQueues() {
|
public int getShuffleMode() {
|
||||||
try {
|
return shuffleMode;
|
||||||
InternalStorageUtil.writeObject(MusicService.this, AppKeys.IS_PLAYING_QUEUE, playingQueue);
|
|
||||||
InternalStorageUtil.writeObject(MusicService.this, AppKeys.IS_ORIGINAL_PLAYING_QUEUE, originalPlayingQueue);
|
|
||||||
Log.i(TAG, "saved current queue state");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "error while saving music service queue state", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void savePosition() {
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
InternalStorageUtil.writeObject(MusicService.this, AppKeys.IS_POSITION_IN_QUEUE, getPosition());
|
|
||||||
Log.i(TAG, "saved current position state");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "error while saving music service position state", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShuffleMode(final int shuffleMode) {
|
public void setShuffleMode(final int shuffleMode) {
|
||||||
|
|
@ -615,47 +648,9 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRepeatMode(final int repeatMode) {
|
public class MusicBinder extends Binder {
|
||||||
switch (repeatMode) {
|
public MusicService getService() {
|
||||||
case REPEAT_MODE_NONE:
|
return MusicService.this;
|
||||||
case REPEAT_MODE_ALL:
|
|
||||||
case REPEAT_MODE_THIS:
|
|
||||||
this.repeatMode = repeatMode;
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(this).edit()
|
|
||||||
.putInt(AppKeys.SP_REPEAT_MODE, repeatMode)
|
|
||||||
.apply();
|
|
||||||
notifyOnMusicRemoteEventListeners(MusicRemoteEvent.REPEAT_MODE_CHANGED);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cycleRepeatMode() {
|
|
||||||
switch (getRepeatMode()) {
|
|
||||||
case REPEAT_MODE_NONE:
|
|
||||||
setRepeatMode(REPEAT_MODE_ALL);
|
|
||||||
break;
|
|
||||||
case REPEAT_MODE_ALL:
|
|
||||||
setRepeatMode(REPEAT_MODE_THIS);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setRepeatMode(REPEAT_MODE_NONE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void toggleShuffle() {
|
|
||||||
if (getShuffleMode() == SHUFFLE_MODE_NONE) {
|
|
||||||
setShuffleMode(SHUFFLE_MODE_SHUFFLE);
|
|
||||||
} else {
|
|
||||||
setShuffleMode(SHUFFLE_MODE_NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRepeatMode() {
|
|
||||||
return repeatMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getShuffleMode() {
|
|
||||||
return shuffleMode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,10 +84,56 @@ public class AlbumDetailActivity extends AbsFabActivity implements OnMusicRemote
|
||||||
private int titleViewHeight;
|
private int titleViewHeight;
|
||||||
private int albumArtViewHeight;
|
private int albumArtViewHeight;
|
||||||
private int toolbarColor;
|
private int toolbarColor;
|
||||||
|
private SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||||
|
@Override
|
||||||
|
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||||
|
super.onScrollChanged(scrollY, b, b2);
|
||||||
|
// Translate overlay and image
|
||||||
|
float flexibleRange = albumArtViewHeight - headerOffset;
|
||||||
|
int minOverlayTransitionY = headerOffset - albumArtOverlayView.getHeight();
|
||||||
|
ViewHelper.setTranslationY(albumArtOverlayView, Math.max(minOverlayTransitionY, Math.min(0, -scrollY)));
|
||||||
|
ViewHelper.setTranslationY(albumArtImageView, Math.max(minOverlayTransitionY, Math.min(0, -scrollY / 2)));
|
||||||
|
|
||||||
|
// Translate list background
|
||||||
|
ViewHelper.setTranslationY(songsBackgroundView, Math.max(0, -scrollY + albumArtViewHeight));
|
||||||
|
|
||||||
|
// Change alpha of overlay
|
||||||
|
ViewHelper.setAlpha(albumArtOverlayView, Math.max(0, Math.min(1, (float) scrollY / flexibleRange)));
|
||||||
|
|
||||||
|
// Translate name text
|
||||||
|
int maxTitleTranslationY = albumArtViewHeight;
|
||||||
|
int titleTranslationY = maxTitleTranslationY - scrollY;
|
||||||
|
if (TOOLBAR_IS_STICKY) {
|
||||||
|
titleTranslationY = Math.max(headerOffset, titleTranslationY);
|
||||||
|
}
|
||||||
|
ViewHelper.setTranslationY(albumTitleView, titleTranslationY);
|
||||||
|
|
||||||
|
// Translate FAB
|
||||||
|
int fabTranslationY = titleTranslationY + titleViewHeight - (fab.getHeight() / 2);
|
||||||
|
ViewHelper.setTranslationY(fab, fabTranslationY);
|
||||||
|
|
||||||
|
if (TOOLBAR_IS_STICKY) {
|
||||||
|
// Change alpha of toolbar background
|
||||||
|
if (-scrollY + albumArtViewHeight <= headerOffset) {
|
||||||
|
ViewUtil.setBackgroundAlpha(toolbar, 1, toolbarColor);
|
||||||
|
ViewUtil.setBackgroundAlpha(statusBar, 1, toolbarColor);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ViewUtil.setBackgroundAlpha(toolbar, 0, toolbarColor);
|
||||||
|
ViewUtil.setBackgroundAlpha(statusBar, 0, toolbarColor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Translate Toolbar
|
||||||
|
if (scrollY < albumArtViewHeight) {
|
||||||
|
ViewHelper.setTranslationY(toolbar, 0);
|
||||||
|
} else {
|
||||||
|
ViewHelper.setTranslationY(toolbar, -scrollY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
private Bitmap albumCover;
|
private Bitmap albumCover;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
app = (App) getApplicationContext();
|
app = (App) getApplicationContext();
|
||||||
|
|
@ -115,49 +161,6 @@ public class AlbumDetailActivity extends AbsFabActivity implements OnMusicRemote
|
||||||
animateEnterActivity();
|
animateEnterActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
enableViews();
|
|
||||||
updateFabIcon();
|
|
||||||
app.getMusicPlayerRemote().addOnMusicRemoteEventListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
app.getMusicPlayerRemote().removeOnMusicRemoteEventListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.menu_album_detail, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
int id = item.getItemId();
|
|
||||||
switch (id) {
|
|
||||||
case android.R.id.home:
|
|
||||||
super.onBackPressed();
|
|
||||||
return true;
|
|
||||||
case R.id.action_settings:
|
|
||||||
return true;
|
|
||||||
case R.id.action_current_playing:
|
|
||||||
return openCurrentPlayingIfPossible(null);
|
|
||||||
case R.id.action_tag_editor:
|
|
||||||
Intent intent = new Intent(this, AlbumTagEditorActivity.class);
|
|
||||||
intent.putExtra(AppKeys.E_ID, album.id);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
case R.id.action_go_to_artist:
|
|
||||||
goToArtistDetailsActivity(album.artistId, null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
albumArtImageView = (ImageView) findViewById(R.id.album_art);
|
albumArtImageView = (ImageView) findViewById(R.id.album_art);
|
||||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
|
|
@ -217,26 +220,16 @@ public class AlbumDetailActivity extends AbsFabActivity implements OnMusicRemote
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpSongsAdapter() {
|
private void applyPalette(Bitmap bitmap) {
|
||||||
final List<Song> songs = AlbumSongLoader.getAlbumSongList(this, album.id);
|
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
||||||
Collections.sort(songs, new SongTrackNumberComparator());
|
|
||||||
final SongAdapter songAdapter = new SongAdapter(this, this, songs);
|
|
||||||
|
|
||||||
// SwingBottomInAnimationAdapter songsAdapter = new SwingBottomInAnimationAdapter(songAdapter);
|
|
||||||
// SwingRightInAnimationAdapter songsAdapter = new SwingRightInAnimationAdapter(songAdapter);
|
|
||||||
// SwingLeftInAnimationAdapter songsAdapter = new SwingLeftInAnimationAdapter(songAdapter);
|
|
||||||
ScaleInAnimationAdapter songsAdapter = new ScaleInAnimationAdapter(songAdapter);
|
|
||||||
// AlphaInAnimationAdapter songsAdapter = new AlphaInAnimationAdapter(songAdapter);
|
|
||||||
|
|
||||||
animatedSongsAdapter = songsAdapter;
|
|
||||||
animatedSongsAdapter.setAbsListView(absSongListView);
|
|
||||||
|
|
||||||
absSongListView.setAdapter(animatedSongsAdapter);
|
|
||||||
absSongListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
public void onGenerated(Palette palette) {
|
||||||
if (position > 0) {
|
Palette.Swatch swatch = palette.getVibrantSwatch();
|
||||||
app.getMusicPlayerRemote().openQueue(songs, position - 1, true);
|
if (swatch != null) {
|
||||||
|
toolbarColor = swatch.getRgb();
|
||||||
|
albumArtOverlayView.setBackgroundColor(swatch.getRgb());
|
||||||
|
albumTitleView.setBackgroundColor(swatch.getRgb());
|
||||||
|
albumTitleView.setTextColor(swatch.getTitleTextColor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -289,107 +282,6 @@ public class AlbumDetailActivity extends AbsFabActivity implements OnMusicRemote
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyPalette(Bitmap bitmap) {
|
|
||||||
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
|
||||||
@Override
|
|
||||||
public void onGenerated(Palette palette) {
|
|
||||||
Palette.Swatch swatch = palette.getVibrantSwatch();
|
|
||||||
if (swatch != null) {
|
|
||||||
toolbarColor = swatch.getRgb();
|
|
||||||
albumArtOverlayView.setBackgroundColor(swatch.getRgb());
|
|
||||||
albumTitleView.setBackgroundColor(swatch.getRgb());
|
|
||||||
albumTitleView.setTextColor(swatch.getTitleTextColor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
|
||||||
@Override
|
|
||||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
|
||||||
super.onScrollChanged(scrollY, b, b2);
|
|
||||||
// Translate overlay and image
|
|
||||||
float flexibleRange = albumArtViewHeight - headerOffset;
|
|
||||||
int minOverlayTransitionY = headerOffset - albumArtOverlayView.getHeight();
|
|
||||||
ViewHelper.setTranslationY(albumArtOverlayView, Math.max(minOverlayTransitionY, Math.min(0, -scrollY)));
|
|
||||||
ViewHelper.setTranslationY(albumArtImageView, Math.max(minOverlayTransitionY, Math.min(0, -scrollY / 2)));
|
|
||||||
|
|
||||||
// Translate list background
|
|
||||||
ViewHelper.setTranslationY(songsBackgroundView, Math.max(0, -scrollY + albumArtViewHeight));
|
|
||||||
|
|
||||||
// Change alpha of overlay
|
|
||||||
ViewHelper.setAlpha(albumArtOverlayView, Math.max(0, Math.min(1, (float) scrollY / flexibleRange)));
|
|
||||||
|
|
||||||
// Translate name text
|
|
||||||
int maxTitleTranslationY = albumArtViewHeight;
|
|
||||||
int titleTranslationY = maxTitleTranslationY - scrollY;
|
|
||||||
if (TOOLBAR_IS_STICKY) {
|
|
||||||
titleTranslationY = Math.max(headerOffset, titleTranslationY);
|
|
||||||
}
|
|
||||||
ViewHelper.setTranslationY(albumTitleView, titleTranslationY);
|
|
||||||
|
|
||||||
// Translate FAB
|
|
||||||
int fabTranslationY = titleTranslationY + titleViewHeight - (fab.getHeight() / 2);
|
|
||||||
ViewHelper.setTranslationY(fab, fabTranslationY);
|
|
||||||
|
|
||||||
if (TOOLBAR_IS_STICKY) {
|
|
||||||
// Change alpha of toolbar background
|
|
||||||
if (-scrollY + albumArtViewHeight <= headerOffset) {
|
|
||||||
ViewUtil.setBackgroundAlpha(toolbar, 1, toolbarColor);
|
|
||||||
ViewUtil.setBackgroundAlpha(statusBar, 1, toolbarColor);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ViewUtil.setBackgroundAlpha(toolbar, 0, toolbarColor);
|
|
||||||
ViewUtil.setBackgroundAlpha(statusBar, 0, toolbarColor);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Translate Toolbar
|
|
||||||
if (scrollY < albumArtViewHeight) {
|
|
||||||
ViewHelper.setTranslationY(toolbar, 0);
|
|
||||||
} else {
|
|
||||||
ViewHelper.setTranslationY(toolbar, -scrollY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
|
||||||
switch (event.getAction()) {
|
|
||||||
case MusicRemoteEvent.PLAY:
|
|
||||||
fab.setImageDrawable(getResources().getDrawable(R.drawable.ic_pause_white_48dp));
|
|
||||||
break;
|
|
||||||
case MusicRemoteEvent.PAUSE:
|
|
||||||
fab.setImageDrawable(getResources().getDrawable(R.drawable.ic_play_arrow_white_48dp));
|
|
||||||
break;
|
|
||||||
case MusicRemoteEvent.RESUME:
|
|
||||||
fab.setImageDrawable(getResources().getDrawable(R.drawable.ic_pause_white_48dp));
|
|
||||||
break;
|
|
||||||
case MusicRemoteEvent.STOP:
|
|
||||||
fab.setImageDrawable(getResources().getDrawable(R.drawable.ic_play_arrow_white_48dp));
|
|
||||||
break;
|
|
||||||
case MusicRemoteEvent.QUEUE_COMPLETED:
|
|
||||||
fab.setImageResource(R.drawable.ic_play_arrow_white_48dp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableViews() {
|
|
||||||
super.enableViews();
|
|
||||||
absSongListView.setEnabled(true);
|
|
||||||
fab.setEnabled(true);
|
|
||||||
toolbar.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableViews() {
|
|
||||||
super.disableViews();
|
|
||||||
absSongListView.setEnabled(false);
|
|
||||||
fab.setEnabled(false);
|
|
||||||
toolbar.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpTranslucence() {
|
private void setUpTranslucence() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
Util.setStatusBarTranslucent(getWindow(), true);
|
Util.setStatusBarTranslucent(getWindow(), true);
|
||||||
|
|
@ -399,14 +291,50 @@ public class AlbumDetailActivity extends AbsFabActivity implements OnMusicRemote
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFabIcon() {
|
private void animateEnterActivity() {
|
||||||
if (app.getMusicPlayerRemote().isPlaying()) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
fab.setImageResource(R.drawable.ic_pause_white_48dp);
|
new Handler().postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
animateHeader(0);
|
||||||
|
setUpSongsAdapter();
|
||||||
|
}
|
||||||
|
}, DEFAULT_DELAY);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fab.setImageResource(R.drawable.ic_play_arrow_white_48dp);
|
setUpSongsAdapter();
|
||||||
|
fab.setScaleX(0);
|
||||||
|
fab.setScaleY(0);
|
||||||
|
animateHeader(DEFAULT_DELAY_NO_TRANSITION);
|
||||||
|
animateFab(DEFAULT_DELAY_NO_TRANSITION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpSongsAdapter() {
|
||||||
|
final List<Song> songs = AlbumSongLoader.getAlbumSongList(this, album.id);
|
||||||
|
Collections.sort(songs, new SongTrackNumberComparator());
|
||||||
|
final SongAdapter songAdapter = new SongAdapter(this, this, songs);
|
||||||
|
|
||||||
|
// SwingBottomInAnimationAdapter songsAdapter = new SwingBottomInAnimationAdapter(songAdapter);
|
||||||
|
// SwingRightInAnimationAdapter songsAdapter = new SwingRightInAnimationAdapter(songAdapter);
|
||||||
|
// SwingLeftInAnimationAdapter songsAdapter = new SwingLeftInAnimationAdapter(songAdapter);
|
||||||
|
ScaleInAnimationAdapter songsAdapter = new ScaleInAnimationAdapter(songAdapter);
|
||||||
|
// AlphaInAnimationAdapter songsAdapter = new AlphaInAnimationAdapter(songAdapter);
|
||||||
|
|
||||||
|
animatedSongsAdapter = songsAdapter;
|
||||||
|
animatedSongsAdapter.setAbsListView(absSongListView);
|
||||||
|
|
||||||
|
absSongListView.setAdapter(animatedSongsAdapter);
|
||||||
|
absSongListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
if (position > 0) {
|
||||||
|
app.getMusicPlayerRemote().openQueue(songs, position - 1, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void animateHeader(int startDelay) {
|
private void animateHeader(int startDelay) {
|
||||||
ViewPropertyAnimator.animate(albumTitleView)
|
ViewPropertyAnimator.animate(albumTitleView)
|
||||||
.scaleX(1)
|
.scaleX(1)
|
||||||
|
|
@ -427,25 +355,6 @@ public class AlbumDetailActivity extends AbsFabActivity implements OnMusicRemote
|
||||||
.start();
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void animateEnterActivity() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
new Handler().postDelayed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
animateHeader(0);
|
|
||||||
setUpSongsAdapter();
|
|
||||||
}
|
|
||||||
}, DEFAULT_DELAY);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
setUpSongsAdapter();
|
|
||||||
fab.setScaleX(0);
|
|
||||||
fab.setScaleY(0);
|
|
||||||
animateHeader(DEFAULT_DELAY_NO_TRANSITION);
|
|
||||||
animateFab(DEFAULT_DELAY_NO_TRANSITION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void goToAlbum(int albumId) {
|
public void goToAlbum(int albumId) {
|
||||||
if (album.id != albumId) {
|
if (album.id != albumId) {
|
||||||
|
|
@ -487,4 +396,92 @@ public class AlbumDetailActivity extends AbsFabActivity implements OnMusicRemote
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
enableViews();
|
||||||
|
updateFabIcon();
|
||||||
|
app.getMusicPlayerRemote().addOnMusicRemoteEventListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enableViews() {
|
||||||
|
super.enableViews();
|
||||||
|
absSongListView.setEnabled(true);
|
||||||
|
fab.setEnabled(true);
|
||||||
|
toolbar.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableViews() {
|
||||||
|
super.disableViews();
|
||||||
|
absSongListView.setEnabled(false);
|
||||||
|
fab.setEnabled(false);
|
||||||
|
toolbar.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
app.getMusicPlayerRemote().removeOnMusicRemoteEventListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MusicRemoteEvent.PLAY:
|
||||||
|
fab.setImageDrawable(getResources().getDrawable(R.drawable.ic_pause_white_48dp));
|
||||||
|
break;
|
||||||
|
case MusicRemoteEvent.PAUSE:
|
||||||
|
fab.setImageDrawable(getResources().getDrawable(R.drawable.ic_play_arrow_white_48dp));
|
||||||
|
break;
|
||||||
|
case MusicRemoteEvent.RESUME:
|
||||||
|
fab.setImageDrawable(getResources().getDrawable(R.drawable.ic_pause_white_48dp));
|
||||||
|
break;
|
||||||
|
case MusicRemoteEvent.STOP:
|
||||||
|
fab.setImageDrawable(getResources().getDrawable(R.drawable.ic_play_arrow_white_48dp));
|
||||||
|
break;
|
||||||
|
case MusicRemoteEvent.QUEUE_COMPLETED:
|
||||||
|
fab.setImageResource(R.drawable.ic_play_arrow_white_48dp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFabIcon() {
|
||||||
|
if (app.getMusicPlayerRemote().isPlaying()) {
|
||||||
|
fab.setImageResource(R.drawable.ic_pause_white_48dp);
|
||||||
|
} else {
|
||||||
|
fab.setImageResource(R.drawable.ic_play_arrow_white_48dp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.menu_album_detail, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
int id = item.getItemId();
|
||||||
|
switch (id) {
|
||||||
|
case android.R.id.home:
|
||||||
|
super.onBackPressed();
|
||||||
|
return true;
|
||||||
|
case R.id.action_settings:
|
||||||
|
return true;
|
||||||
|
case R.id.action_current_playing:
|
||||||
|
return openCurrentPlayingIfPossible(null);
|
||||||
|
case R.id.action_tag_editor:
|
||||||
|
Intent intent = new Intent(this, AlbumTagEditorActivity.class);
|
||||||
|
intent.putExtra(AppKeys.E_ID, album.id);
|
||||||
|
startActivity(intent);
|
||||||
|
return true;
|
||||||
|
case R.id.action_go_to_artist:
|
||||||
|
goToArtistDetailsActivity(album.artistId, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,28 +97,6 @@ public class ArtistDetailActivity extends AbsFabActivity implements OnMusicRemot
|
||||||
lollipopTransitionImageWrongSizeFix();
|
lollipopTransitionImageWrongSizeFix();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.menu_artist_detail, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
int id = item.getItemId();
|
|
||||||
switch (id) {
|
|
||||||
case android.R.id.home:
|
|
||||||
super.onBackPressed();
|
|
||||||
return true;
|
|
||||||
case R.id.action_settings:
|
|
||||||
return true;
|
|
||||||
case R.id.action_current_playing:
|
|
||||||
openCurrentPlayingIfPossible(null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
artistImageView = (ImageView) findViewById(R.id.artist_image);
|
artistImageView = (ImageView) findViewById(R.id.artist_image);
|
||||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
|
|
@ -181,80 +159,42 @@ public class ArtistDetailActivity extends AbsFabActivity implements OnMusicRemot
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpArtistImageAndApplyPalette() {
|
public void restoreY(final int scrollY) {
|
||||||
if (artistImage == null) {
|
translateToolBar(scrollY);
|
||||||
LastFMArtistImageLoader.loadArtistImage(this, artist.name, new LastFMArtistImageLoader.ArtistImageLoaderCallback() {
|
int animationTime = 1000;
|
||||||
@Override
|
DecelerateInterpolator interpolator = new DecelerateInterpolator(4);
|
||||||
public void onArtistImageLoaded(Bitmap artistImage) {
|
int titleTranslationY = getTitleTranslation(scrollY);
|
||||||
if (artistImage != null) {
|
ViewPropertyAnimator.animate(artistArtOverlayView).y(getOverlayTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||||
ArtistDetailActivity.this.artistImage = artistImage;
|
ViewPropertyAnimator.animate(artistImageView).y(getImageViewTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||||
artistImageView.setImageBitmap(artistImage);
|
ViewPropertyAnimator.animate(absAlbumListBackgroundView).y(getListBackgroundTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||||
applyPalette(artistImage);
|
ViewPropertyAnimator.animate(artistArtOverlayView).alpha(getOverlayAlpha(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||||
}
|
ViewPropertyAnimator.animate(slidingTabs).y(titleTranslationY + titleViewHeight).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||||
}
|
ViewPropertyAnimator.animate(artistTitleText).y(titleTranslationY).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||||
});
|
ViewPropertyAnimator.animate(getFab()).y(getFabTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).setListener(new Animator.AnimatorListener() {
|
||||||
} else {
|
|
||||||
artistImageView.setImageBitmap(artistImage);
|
|
||||||
applyPalette(artistImage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpViewPatch() {
|
|
||||||
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
|
|
||||||
contentView.post(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void onAnimationStart(Animator animation) {
|
||||||
absAlbumListBackgroundView.getLayoutParams().height = contentView.getHeight();
|
isAnimating = true;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpToolBar() {
|
|
||||||
setSupportActionBar(toolbar);
|
|
||||||
getSupportActionBar().setTitle(null);
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
if (!TOOLBAR_IS_STICKY) {
|
|
||||||
toolbar.setBackgroundColor(Color.TRANSPARENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyPalette(Bitmap bitmap) {
|
|
||||||
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onGenerated(Palette palette) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
Palette.Swatch swatch = palette.getVibrantSwatch();
|
translateToolBar(scrollY);
|
||||||
if (swatch != null) {
|
isAnimating = false;
|
||||||
toolbarColor = swatch.getRgb();
|
if (currentFragment instanceof AbsViewPagerTabArtistListFragment) {
|
||||||
artistArtOverlayView.setBackgroundColor(swatch.getRgb());
|
onScrollChanged((((AbsViewPagerTabArtistListFragment) currentFragment).getY()), false, false);
|
||||||
artistTitleText.setBackgroundColor(swatch.getRgb());
|
|
||||||
slidingTabs.setBackgroundColor(swatch.getRgb());
|
|
||||||
artistTitleText.setTextColor(swatch.getTitleTextColor());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enableViews() {
|
public void onAnimationCancel(Animator animation) {
|
||||||
super.enableViews();
|
isAnimating = false;
|
||||||
viewPager.setEnabled(true);
|
}
|
||||||
toolbar.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disableViews() {
|
public void onAnimationRepeat(Animator animation) {
|
||||||
super.disableViews();
|
isAnimating = true;
|
||||||
viewPager.setEnabled(false);
|
}
|
||||||
toolbar.setEnabled(false);
|
}).start();
|
||||||
}
|
|
||||||
|
|
||||||
private void getIntentExtras() {
|
|
||||||
Bundle intentExtras = getIntent().getExtras();
|
|
||||||
final int artistId = intentExtras.getInt(AppKeys.E_ARTIST);
|
|
||||||
artist = ArtistLoader.getArtist(this, artistId);
|
|
||||||
if (artist == null) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -272,6 +212,14 @@ public class ArtistDetailActivity extends AbsFabActivity implements OnMusicRemot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDownMotionEvent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||||
|
}
|
||||||
|
|
||||||
private int getImageViewTranslation(int scrollY) {
|
private int getImageViewTranslation(int scrollY) {
|
||||||
int minOverlayTransitionY = headerOffset - artistArtOverlayView.getHeight();
|
int minOverlayTransitionY = headerOffset - artistArtOverlayView.getHeight();
|
||||||
return Math.max(minOverlayTransitionY, Math.min(0, -scrollY / 2));
|
return Math.max(minOverlayTransitionY, Math.min(0, -scrollY / 2));
|
||||||
|
|
@ -325,50 +273,66 @@ public class ArtistDetailActivity extends AbsFabActivity implements OnMusicRemot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void restoreY(final int scrollY) {
|
private void setUpArtistImageAndApplyPalette() {
|
||||||
translateToolBar(scrollY);
|
if (artistImage == null) {
|
||||||
int animationTime = 1000;
|
LastFMArtistImageLoader.loadArtistImage(this, artist.name, new LastFMArtistImageLoader.ArtistImageLoaderCallback() {
|
||||||
DecelerateInterpolator interpolator = new DecelerateInterpolator(4);
|
@Override
|
||||||
int titleTranslationY = getTitleTranslation(scrollY);
|
public void onArtistImageLoaded(Bitmap artistImage) {
|
||||||
ViewPropertyAnimator.animate(artistArtOverlayView).y(getOverlayTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
if (artistImage != null) {
|
||||||
ViewPropertyAnimator.animate(artistImageView).y(getImageViewTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
ArtistDetailActivity.this.artistImage = artistImage;
|
||||||
ViewPropertyAnimator.animate(absAlbumListBackgroundView).y(getListBackgroundTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
artistImageView.setImageBitmap(artistImage);
|
||||||
ViewPropertyAnimator.animate(artistArtOverlayView).alpha(getOverlayAlpha(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
applyPalette(artistImage);
|
||||||
ViewPropertyAnimator.animate(slidingTabs).y(titleTranslationY + titleViewHeight).setDuration(animationTime).setInterpolator(interpolator).start();
|
}
|
||||||
ViewPropertyAnimator.animate(artistTitleText).y(titleTranslationY).setDuration(animationTime).setInterpolator(interpolator).start();
|
}
|
||||||
ViewPropertyAnimator.animate(getFab()).y(getFabTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).setListener(new Animator.AnimatorListener() {
|
});
|
||||||
@Override
|
} else {
|
||||||
public void onAnimationStart(Animator animation) {
|
artistImageView.setImageBitmap(artistImage);
|
||||||
isAnimating = true;
|
applyPalette(artistImage);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyPalette(Bitmap bitmap) {
|
||||||
|
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onGenerated(Palette palette) {
|
||||||
translateToolBar(scrollY);
|
Palette.Swatch swatch = palette.getVibrantSwatch();
|
||||||
isAnimating = false;
|
if (swatch != null) {
|
||||||
if (currentFragment instanceof AbsViewPagerTabArtistListFragment) {
|
toolbarColor = swatch.getRgb();
|
||||||
onScrollChanged((((AbsViewPagerTabArtistListFragment) currentFragment).getY()), false, false);
|
artistArtOverlayView.setBackgroundColor(swatch.getRgb());
|
||||||
|
artistTitleText.setBackgroundColor(swatch.getRgb());
|
||||||
|
slidingTabs.setBackgroundColor(swatch.getRgb());
|
||||||
|
artistTitleText.setTextColor(swatch.getTitleTextColor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
@Override
|
|
||||||
public void onAnimationCancel(Animator animation) {
|
|
||||||
isAnimating = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationRepeat(Animator animation) {
|
|
||||||
isAnimating = true;
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setUpViewPatch() {
|
||||||
public void onDownMotionEvent() {
|
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
|
||||||
|
contentView.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
absAlbumListBackgroundView.getLayoutParams().height = contentView.getHeight();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setUpToolBar() {
|
||||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
setSupportActionBar(toolbar);
|
||||||
|
getSupportActionBar().setTitle(null);
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
if (!TOOLBAR_IS_STICKY) {
|
||||||
|
toolbar.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getIntentExtras() {
|
||||||
|
Bundle intentExtras = getIntent().getExtras();
|
||||||
|
final int artistId = intentExtras.getInt(AppKeys.E_ARTIST);
|
||||||
|
artist = ArtistLoader.getArtist(this, artistId);
|
||||||
|
if (artist == null) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -420,6 +384,42 @@ public class ArtistDetailActivity extends AbsFabActivity implements OnMusicRemot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.menu_artist_detail, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
int id = item.getItemId();
|
||||||
|
switch (id) {
|
||||||
|
case android.R.id.home:
|
||||||
|
super.onBackPressed();
|
||||||
|
return true;
|
||||||
|
case R.id.action_settings:
|
||||||
|
return true;
|
||||||
|
case R.id.action_current_playing:
|
||||||
|
openCurrentPlayingIfPossible(null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enableViews() {
|
||||||
|
super.enableViews();
|
||||||
|
viewPager.setEnabled(true);
|
||||||
|
toolbar.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableViews() {
|
||||||
|
super.disableViews();
|
||||||
|
viewPager.setEnabled(false);
|
||||||
|
toolbar.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
private static class NavigationAdapter extends FragmentPagerAdapter {
|
private static class NavigationAdapter extends FragmentPagerAdapter {
|
||||||
|
|
||||||
private String[] titles;
|
private String[] titles;
|
||||||
|
|
@ -465,6 +465,14 @@ public class ArtistDetailActivity extends AbsFabActivity implements OnMusicRemot
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||||
|
if (0 <= mPages.indexOfKey(position)) {
|
||||||
|
mPages.remove(position);
|
||||||
|
}
|
||||||
|
super.destroyItem(container, position, object);
|
||||||
|
}
|
||||||
|
|
||||||
public Fragment getItemAt(int position) {
|
public Fragment getItemAt(int position) {
|
||||||
return mPages.get(position, null);
|
return mPages.get(position, null);
|
||||||
}
|
}
|
||||||
|
|
@ -474,14 +482,6 @@ public class ArtistDetailActivity extends AbsFabActivity implements OnMusicRemot
|
||||||
return titles.length;
|
return titles.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
|
||||||
if (0 <= mPages.indexOfKey(position)) {
|
|
||||||
mPages.remove(position);
|
|
||||||
}
|
|
||||||
super.destroyItem(container, position, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getPageTitle(int position) {
|
public CharSequence getPageTitle(int position) {
|
||||||
return titles[position];
|
return titles[position];
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,48 @@ public class MainActivity extends AbsFabActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
|
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||||
|
navigationDrawerFragment = (NavigationDrawerFragment)
|
||||||
|
getFragmentManager().findFragmentById(R.id.navigation_drawer);
|
||||||
|
updateNavigationDrawerHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateNavigationDrawerHeader() {
|
||||||
|
Song song = getApp().getMusicPlayerRemote().getCurrentSong();
|
||||||
|
if (navigationDrawerFragment != null && song.id != -1) {
|
||||||
|
ImageLoader.getInstance().displayImage(MusicUtil.getAlbumArtUri(song.albumId).toString(), navigationDrawerFragment.getAlbumArtImageView(), new ImageLoaderUtil.defaultAlbumArtOnFailed());
|
||||||
|
navigationDrawerFragment.getSongTitle().setText(song.title);
|
||||||
|
navigationDrawerFragment.getSongArtist().setText(song.artistName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpToolBar() {
|
||||||
|
toolbarTitle = getTitle();
|
||||||
|
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
|
statusBar = findViewById(R.id.statusBar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
ViewUtil.setBackgroundAlpha(toolbar, 0.97f, Util.resolveColor(this, R.attr.colorPrimary));
|
||||||
|
ViewUtil.setBackgroundAlpha(statusBar, 0.97f, Util.resolveColor(this, R.attr.colorPrimary));
|
||||||
|
setUpDrawerToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpDrawerToggle() {
|
||||||
|
drawerToggle = new ActionBarDrawerToggle(
|
||||||
|
this,
|
||||||
|
drawerLayout,
|
||||||
|
R.string.navigation_drawer_open,
|
||||||
|
R.string.navigation_drawer_close
|
||||||
|
);
|
||||||
|
drawerLayout.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
drawerToggle.syncState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
drawerLayout.setDrawerListener(drawerToggle);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
@ -75,9 +117,23 @@ public class MainActivity extends AbsFabActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
public void enableViews() {
|
||||||
super.onDestroy();
|
try {
|
||||||
getApp().getMusicPlayerRemote().removeAllOnMusicRemoteEventListeners();
|
super.enableViews();
|
||||||
|
toolbar.setEnabled(true);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.e(TAG, "wasn't able to enable the views", e.fillInStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableViews() {
|
||||||
|
try {
|
||||||
|
super.disableViews();
|
||||||
|
toolbar.setEnabled(false);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.e(TAG, "wasn't able to disable the views", e.fillInStackTrace());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -135,22 +191,6 @@ public class MainActivity extends AbsFabActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initViews() {
|
|
||||||
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
|
||||||
navigationDrawerFragment = (NavigationDrawerFragment)
|
|
||||||
getFragmentManager().findFragmentById(R.id.navigation_drawer);
|
|
||||||
updateNavigationDrawerHeader();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void restoreActionBar() {
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
|
||||||
actionBar.setDisplayShowTitleEnabled(true);
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
|
||||||
actionBar.setHomeButtonEnabled(true);
|
|
||||||
actionBar.setTitle(toolbarTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.drawer, menu);
|
getMenuInflater().inflate(R.menu.drawer, menu);
|
||||||
|
|
@ -193,6 +233,14 @@ public class MainActivity extends AbsFabActivity
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void restoreActionBar() {
|
||||||
|
ActionBar actionBar = getSupportActionBar();
|
||||||
|
actionBar.setDisplayShowTitleEnabled(true);
|
||||||
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
|
actionBar.setHomeButtonEnabled(true);
|
||||||
|
actionBar.setTitle(toolbarTitle);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (drawerToggle.onOptionsItemSelected(item)) {
|
if (drawerToggle.onOptionsItemSelected(item)) {
|
||||||
|
|
@ -216,6 +264,12 @@ public class MainActivity extends AbsFabActivity
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
getApp().getMusicPlayerRemote().removeAllOnMusicRemoteEventListeners();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (navigationDrawerFragment.isDrawerOpen()) {
|
if (navigationDrawerFragment.isDrawerOpen()) {
|
||||||
|
|
@ -225,41 +279,6 @@ public class MainActivity extends AbsFabActivity
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpToolBar() {
|
|
||||||
toolbarTitle = getTitle();
|
|
||||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
|
||||||
statusBar = findViewById(R.id.statusBar);
|
|
||||||
setSupportActionBar(toolbar);
|
|
||||||
ViewUtil.setBackgroundAlpha(toolbar, 0.97f, Util.resolveColor(this, R.attr.colorPrimary));
|
|
||||||
ViewUtil.setBackgroundAlpha(statusBar, 0.97f, Util.resolveColor(this, R.attr.colorPrimary));
|
|
||||||
setUpDrawerToggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpDrawerToggle() {
|
|
||||||
drawerToggle = new ActionBarDrawerToggle(
|
|
||||||
this,
|
|
||||||
drawerLayout,
|
|
||||||
R.string.navigation_drawer_open,
|
|
||||||
R.string.navigation_drawer_close
|
|
||||||
);
|
|
||||||
drawerLayout.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
drawerToggle.syncState();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
drawerLayout.setDrawerListener(drawerToggle);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateNavigationDrawerHeader() {
|
|
||||||
Song song = getApp().getMusicPlayerRemote().getCurrentSong();
|
|
||||||
if (navigationDrawerFragment != null && song.id != -1) {
|
|
||||||
ImageLoader.getInstance().displayImage(MusicUtil.getAlbumArtUri(song.albumId).toString(), navigationDrawerFragment.getAlbumArtImageView(), new ImageLoaderUtil.defaultAlbumArtOnFailed());
|
|
||||||
navigationDrawerFragment.getSongTitle().setText(song.title);
|
|
||||||
navigationDrawerFragment.getSongArtist().setText(song.artistName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableFragmentViews() {
|
private void disableFragmentViews() {
|
||||||
if (currentFragmentPosition >= 0 && currentFragmentPosition < getApp().MainActivityFragments.length) {
|
if (currentFragmentPosition >= 0 && currentFragmentPosition < getApp().MainActivityFragments.length) {
|
||||||
if (getApp().MainActivityFragments[currentFragmentPosition] instanceof KabViewsDisableAble) {
|
if (getApp().MainActivityFragments[currentFragmentPosition] instanceof KabViewsDisableAble) {
|
||||||
|
|
@ -285,26 +304,6 @@ public class MainActivity extends AbsFabActivity
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableViews() {
|
|
||||||
try {
|
|
||||||
super.enableViews();
|
|
||||||
toolbar.setEnabled(true);
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
Log.e(TAG, "wasn't able to enable the views", e.fillInStackTrace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableViews() {
|
|
||||||
try {
|
|
||||||
super.disableViews();
|
|
||||||
toolbar.setEnabled(false);
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
Log.e(TAG, "wasn't able to disable the views", e.fillInStackTrace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PlaceholderFragment extends Fragment {
|
public static class PlaceholderFragment extends Fragment {
|
||||||
|
|
||||||
public PlaceholderFragment() {
|
public PlaceholderFragment() {
|
||||||
|
|
|
||||||
|
|
@ -84,56 +84,6 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
setUpToolBar();
|
setUpToolBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.menu_title_playing, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
int id = item.getItemId();
|
|
||||||
switch (id) {
|
|
||||||
case android.R.id.home:
|
|
||||||
super.onBackPressed();
|
|
||||||
return true;
|
|
||||||
case R.id.action_playing_queue:
|
|
||||||
final MaterialDialog materialDialog = PlayingQueueDialogHelper.getDialog(this);
|
|
||||||
materialDialog.show();
|
|
||||||
return true;
|
|
||||||
case R.id.action_tag_editor:
|
|
||||||
Intent intent = new Intent(this, SongTagEditorActivity.class);
|
|
||||||
intent.putExtra(AppKeys.E_ID, song.id);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
case R.id.action_details:
|
|
||||||
String songFilePath = SongFileLoader.getSongFile(this, song.id);
|
|
||||||
File songFile = new File(songFilePath);
|
|
||||||
SongDetailDialogHelper.getDialog(this, songFile).show();
|
|
||||||
return true;
|
|
||||||
case R.id.action_go_to_album:
|
|
||||||
goToAlbumDetailsActivity(song.albumId, null);
|
|
||||||
return true;
|
|
||||||
case R.id.action_go_to_artist:
|
|
||||||
goToArtistDetailsActivity(song.artistId, null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
startMusicControllerStateUpdateThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
killThreads = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCurrentSong() {
|
private void updateCurrentSong() {
|
||||||
getCurrentSongAndQueue();
|
getCurrentSongAndQueue();
|
||||||
setHeadersText();
|
setHeadersText();
|
||||||
|
|
@ -143,13 +93,6 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
currentSongProgress.setText(MusicUtil.getReadableDurationString(-1));
|
currentSongProgress.setText(MusicUtil.getReadableDurationString(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void moveSeekBarIntoPlace() {
|
|
||||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) progressSlider.getLayoutParams();
|
|
||||||
progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
|
||||||
lp.setMargins(0, 0, 0, -(progressSlider.getMeasuredHeight() / 2));
|
|
||||||
progressSlider.setLayoutParams(lp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setHeadersText() {
|
private void setHeadersText() {
|
||||||
songTitle.setText(song.title);
|
songTitle.setText(song.title);
|
||||||
songArtist.setText(song.artistName);
|
songArtist.setText(song.artistName);
|
||||||
|
|
@ -181,41 +124,6 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpArtistArt() {
|
|
||||||
if (artistArt != null) {
|
|
||||||
artistArt.setImageResource(R.drawable.default_artist_image);
|
|
||||||
LastFMArtistImageLoader.loadArtistImage(this, song.artistName, new LastFMArtistImageLoader.ArtistImageLoaderCallback() {
|
|
||||||
@Override
|
|
||||||
public void onArtistImageLoaded(Bitmap artistImage) {
|
|
||||||
artistArt.setImageBitmap(artistImage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getCurrentSongAndQueue() {
|
|
||||||
if (getApp().getMusicPlayerRemote().getPosition() >= 0) {
|
|
||||||
song = getApp().getMusicPlayerRemote().getPlayingQueue().get(getApp().getMusicPlayerRemote().getPosition());
|
|
||||||
} else {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initViews() {
|
|
||||||
nextButton = (ImageButton) findViewById(R.id.next_button);
|
|
||||||
prevButton = (ImageButton) findViewById(R.id.prev_button);
|
|
||||||
repeatButton = (ImageButton) findViewById(R.id.repeat_button);
|
|
||||||
shuffleButton = (ImageButton) findViewById(R.id.shuffle_button);
|
|
||||||
albumArt = (ImageView) findViewById(R.id.album_art);
|
|
||||||
artistArt = (ImageView) findViewById(R.id.artist_image);
|
|
||||||
songTitle = (TextView) findViewById(R.id.song_title);
|
|
||||||
songArtist = (TextView) findViewById(R.id.song_artist);
|
|
||||||
currentSongProgress = (TextView) findViewById(R.id.song_current_progress);
|
|
||||||
totalSongDuration = (TextView) findViewById(R.id.song_total_time);
|
|
||||||
footer = findViewById(R.id.footer);
|
|
||||||
progressSlider = (SeekBar) findViewById(R.id.progress_slider);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyPalette(Bitmap bitmap) {
|
private void applyPalette(Bitmap bitmap) {
|
||||||
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -255,6 +163,48 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
lastFooterColor = newColor;
|
lastFooterColor = newColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpArtistArt() {
|
||||||
|
if (artistArt != null) {
|
||||||
|
artistArt.setImageResource(R.drawable.default_artist_image);
|
||||||
|
LastFMArtistImageLoader.loadArtistImage(this, song.artistName, new LastFMArtistImageLoader.ArtistImageLoaderCallback() {
|
||||||
|
@Override
|
||||||
|
public void onArtistImageLoaded(Bitmap artistImage) {
|
||||||
|
artistArt.setImageBitmap(artistImage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getCurrentSongAndQueue() {
|
||||||
|
if (getApp().getMusicPlayerRemote().getPosition() >= 0) {
|
||||||
|
song = getApp().getMusicPlayerRemote().getPlayingQueue().get(getApp().getMusicPlayerRemote().getPosition());
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveSeekBarIntoPlace() {
|
||||||
|
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) progressSlider.getLayoutParams();
|
||||||
|
progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||||
|
lp.setMargins(0, 0, 0, -(progressSlider.getMeasuredHeight() / 2));
|
||||||
|
progressSlider.setLayoutParams(lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
|
nextButton = (ImageButton) findViewById(R.id.next_button);
|
||||||
|
prevButton = (ImageButton) findViewById(R.id.prev_button);
|
||||||
|
repeatButton = (ImageButton) findViewById(R.id.repeat_button);
|
||||||
|
shuffleButton = (ImageButton) findViewById(R.id.shuffle_button);
|
||||||
|
albumArt = (ImageView) findViewById(R.id.album_art);
|
||||||
|
artistArt = (ImageView) findViewById(R.id.artist_image);
|
||||||
|
songTitle = (TextView) findViewById(R.id.song_title);
|
||||||
|
songArtist = (TextView) findViewById(R.id.song_artist);
|
||||||
|
currentSongProgress = (TextView) findViewById(R.id.song_current_progress);
|
||||||
|
totalSongDuration = (TextView) findViewById(R.id.song_total_time);
|
||||||
|
footer = findViewById(R.id.footer);
|
||||||
|
progressSlider = (SeekBar) findViewById(R.id.progress_slider);
|
||||||
|
}
|
||||||
|
|
||||||
private void setUpMusicControllers() {
|
private void setUpMusicControllers() {
|
||||||
setUpPrevNext();
|
setUpPrevNext();
|
||||||
setUpRepeatButton();
|
setUpRepeatButton();
|
||||||
|
|
@ -306,6 +256,17 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateShuffleState() {
|
||||||
|
switch (getApp().getMusicPlayerRemote().getShuffleMode()) {
|
||||||
|
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||||
|
shuffleButton.setImageResource(R.drawable.ic_shuffle_white_48dp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
shuffleButton.setImageResource(R.drawable.ic_shuffle_grey600_48dp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setUpRepeatButton() {
|
private void setUpRepeatButton() {
|
||||||
updateRepeatState();
|
updateRepeatState();
|
||||||
repeatButton.setOnClickListener(new View.OnClickListener() {
|
repeatButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
@ -330,22 +291,21 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateShuffleState() {
|
private void prepareViewsForOpenAnimation() {
|
||||||
switch (getApp().getMusicPlayerRemote().getShuffleMode()) {
|
footer.setPivotY(0);
|
||||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
footer.setScaleY(0);
|
||||||
shuffleButton.setImageResource(R.drawable.ic_shuffle_white_48dp);
|
}
|
||||||
break;
|
|
||||||
default:
|
private void setUpToolBar() {
|
||||||
shuffleButton.setImageResource(R.drawable.ic_shuffle_grey600_48dp);
|
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
||||||
break;
|
getSupportActionBar().setTitle(null);
|
||||||
}
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateControllerState() {
|
protected void onResume() {
|
||||||
super.updateControllerState();
|
super.onResume();
|
||||||
updateRepeatState();
|
startMusicControllerStateUpdateThread();
|
||||||
updateShuffleState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startMusicControllerStateUpdateThread() {
|
private void startMusicControllerStateUpdateThread() {
|
||||||
|
|
@ -379,6 +339,19 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean openCurrentPlayingIfPossible(Pair[] sharedViews) {
|
||||||
|
onBackPressed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateControllerState() {
|
||||||
|
super.updateControllerState();
|
||||||
|
updateRepeatState();
|
||||||
|
updateShuffleState();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
||||||
super.onMusicRemoteEvent(event);
|
super.onMusicRemoteEvent(event);
|
||||||
|
|
@ -398,9 +371,56 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareViewsForOpenAnimation() {
|
@Override
|
||||||
footer.setPivotY(0);
|
protected void onPause() {
|
||||||
footer.setScaleY(0);
|
super.onPause();
|
||||||
|
killThreads = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
|
super.onWindowFocusChanged(hasFocus);
|
||||||
|
if (hasFocus) {
|
||||||
|
animateActivityOpened(DEFAULT_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.menu_title_playing, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
int id = item.getItemId();
|
||||||
|
switch (id) {
|
||||||
|
case android.R.id.home:
|
||||||
|
super.onBackPressed();
|
||||||
|
return true;
|
||||||
|
case R.id.action_playing_queue:
|
||||||
|
final MaterialDialog materialDialog = PlayingQueueDialogHelper.getDialog(this);
|
||||||
|
materialDialog.show();
|
||||||
|
return true;
|
||||||
|
case R.id.action_tag_editor:
|
||||||
|
Intent intent = new Intent(this, SongTagEditorActivity.class);
|
||||||
|
intent.putExtra(AppKeys.E_ID, song.id);
|
||||||
|
startActivity(intent);
|
||||||
|
return true;
|
||||||
|
case R.id.action_details:
|
||||||
|
String songFilePath = SongFileLoader.getSongFile(this, song.id);
|
||||||
|
File songFile = new File(songFilePath);
|
||||||
|
SongDetailDialogHelper.getDialog(this, songFile).show();
|
||||||
|
return true;
|
||||||
|
case R.id.action_go_to_album:
|
||||||
|
goToAlbumDetailsActivity(song.albumId, null);
|
||||||
|
return true;
|
||||||
|
case R.id.action_go_to_artist:
|
||||||
|
goToArtistDetailsActivity(song.artistId, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void animateActivityOpened(int startDelay) {
|
private void animateActivityOpened(int startDelay) {
|
||||||
|
|
@ -412,24 +432,4 @@ public class MusicControllerActivity extends AbsFabActivity implements OnMusicRe
|
||||||
.setStartDelay(startDelay)
|
.setStartDelay(startDelay)
|
||||||
.start();
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onWindowFocusChanged(boolean hasFocus) {
|
|
||||||
super.onWindowFocusChanged(hasFocus);
|
|
||||||
if (hasFocus) {
|
|
||||||
animateActivityOpened(DEFAULT_DELAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpToolBar() {
|
|
||||||
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
|
||||||
getSupportActionBar().setTitle(null);
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean openCurrentPlayingIfPossible(Pair[] sharedViews) {
|
|
||||||
onBackPressed();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,34 @@ public abstract class AbsBaseActivity extends ActionBarActivity implements KabVi
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected App getApp() {
|
||||||
|
if (app == null) {
|
||||||
|
app = (App) getApplicationContext();
|
||||||
|
}
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
enableViews();
|
enableViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enableViews() {
|
||||||
|
areViewsEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableViews() {
|
||||||
|
areViewsEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areViewsEnabled() {
|
||||||
|
return areViewsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
protected void setUpTranslucence(boolean statusBarTranslucent, boolean navigationBarTranslucent) {
|
protected void setUpTranslucence(boolean statusBarTranslucent, boolean navigationBarTranslucent) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
Util.setStatusBarTranslucent(getWindow(), statusBarTranslucent);
|
Util.setStatusBarTranslucent(getWindow(), statusBarTranslucent);
|
||||||
|
|
@ -78,19 +100,6 @@ public abstract class AbsBaseActivity extends ActionBarActivity implements KabVi
|
||||||
goToArtistDetailsActivity(artistId, null);
|
goToArtistDetailsActivity(artistId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void goToAlbumDetailsActivity(int albumId, Pair[] sharedViews) {
|
|
||||||
final Intent intent = new Intent(this, AlbumDetailActivity.class);
|
|
||||||
intent.putExtra(AppKeys.E_ALBUM, albumId);
|
|
||||||
if (sharedViews != null) {
|
|
||||||
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this,
|
|
||||||
sharedViews
|
|
||||||
);
|
|
||||||
ActivityCompat.startActivity(this, intent, optionsCompat.toBundle());
|
|
||||||
} else {
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void goToArtistDetailsActivity(int artistId, Pair[] sharedViews) {
|
public void goToArtistDetailsActivity(int artistId, Pair[] sharedViews) {
|
||||||
final Intent intent = new Intent(this, ArtistDetailActivity.class);
|
final Intent intent = new Intent(this, ArtistDetailActivity.class);
|
||||||
intent.putExtra(AppKeys.E_ARTIST, artistId);
|
intent.putExtra(AppKeys.E_ARTIST, artistId);
|
||||||
|
|
@ -104,25 +113,16 @@ public abstract class AbsBaseActivity extends ActionBarActivity implements KabVi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void goToAlbumDetailsActivity(int albumId, Pair[] sharedViews) {
|
||||||
public boolean areViewsEnabled() {
|
final Intent intent = new Intent(this, AlbumDetailActivity.class);
|
||||||
return areViewsEnabled;
|
intent.putExtra(AppKeys.E_ALBUM, albumId);
|
||||||
}
|
if (sharedViews != null) {
|
||||||
|
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this,
|
||||||
@Override
|
sharedViews
|
||||||
public void enableViews() {
|
);
|
||||||
areViewsEnabled = true;
|
ActivityCompat.startActivity(this, intent, optionsCompat.toBundle());
|
||||||
}
|
} else {
|
||||||
|
startActivity(intent);
|
||||||
@Override
|
|
||||||
public void disableViews() {
|
|
||||||
areViewsEnabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected App getApp() {
|
|
||||||
if (app == null) {
|
|
||||||
app = (App) getApplicationContext();
|
|
||||||
}
|
}
|
||||||
return app;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,73 +19,12 @@ import com.melnykov.fab.FloatingActionButton;
|
||||||
public abstract class AbsFabActivity extends AbsBaseActivity implements OnMusicRemoteEventListener {
|
public abstract class AbsFabActivity extends AbsBaseActivity implements OnMusicRemoteEventListener {
|
||||||
private FloatingActionButton fab;
|
private FloatingActionButton fab;
|
||||||
|
|
||||||
protected FloatingActionButton getFab() {
|
|
||||||
if (fab == null) {
|
|
||||||
fab = (FloatingActionButton) findViewById(R.id.fab);
|
|
||||||
}
|
|
||||||
return fab;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
protected void onPostCreate(Bundle savedInstanceState) {
|
||||||
super.onPostCreate(savedInstanceState);
|
super.onPostCreate(savedInstanceState);
|
||||||
setUpFab();
|
setUpFab();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
updateControllerState();
|
|
||||||
getApp().getMusicPlayerRemote().addOnMusicRemoteEventListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
getApp().getMusicPlayerRemote().removeOnMusicRemoteEventListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableViews() {
|
|
||||||
super.enableViews();
|
|
||||||
fab.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableViews() {
|
|
||||||
super.disableViews();
|
|
||||||
fab.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean openCurrentPlayingIfPossible(Pair[] sharedViews) {
|
|
||||||
return super.openCurrentPlayingIfPossible(getSharedViewsWithFab(sharedViews));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void goToArtistDetailsActivity(int artistId, Pair[] sharedViews) {
|
|
||||||
super.goToArtistDetailsActivity(artistId, getSharedViewsWithFab(sharedViews));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void goToAlbumDetailsActivity(int albumId, Pair[] sharedViews) {
|
|
||||||
super.goToAlbumDetailsActivity(albumId, getSharedViewsWithFab(sharedViews));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Pair[] getSharedViewsWithFab(Pair[] sharedViews) {
|
|
||||||
Pair[] sharedViewsWithFab;
|
|
||||||
if (sharedViews != null) {
|
|
||||||
sharedViewsWithFab = new Pair[sharedViews.length + 1];
|
|
||||||
for (int i = 0; i < sharedViews.length; i++) {
|
|
||||||
sharedViewsWithFab[i] = sharedViews[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sharedViewsWithFab = new Pair[1];
|
|
||||||
}
|
|
||||||
sharedViewsWithFab[sharedViewsWithFab.length - 1] = Pair.create((View) getFab(), getString(R.string.transition_fab));
|
|
||||||
return sharedViewsWithFab;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpFab() {
|
private void setUpFab() {
|
||||||
updateFabState();
|
updateFabState();
|
||||||
final GestureDetector gestureDetector = new GestureDetector(this, new SmallOnGestureListener() {
|
final GestureDetector gestureDetector = new GestureDetector(this, new SmallOnGestureListener() {
|
||||||
|
|
@ -128,10 +67,6 @@ public abstract class AbsFabActivity extends AbsBaseActivity implements OnMusicR
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateControllerState() {
|
|
||||||
updateFabState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateFabState() {
|
private void updateFabState() {
|
||||||
if (getApp().getMusicPlayerRemote().isPlaying()) {
|
if (getApp().getMusicPlayerRemote().isPlaying()) {
|
||||||
getFab().setImageResource(R.drawable.ic_pause_white_48dp);
|
getFab().setImageResource(R.drawable.ic_pause_white_48dp);
|
||||||
|
|
@ -140,6 +75,71 @@ public abstract class AbsFabActivity extends AbsBaseActivity implements OnMusicR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected FloatingActionButton getFab() {
|
||||||
|
if (fab == null) {
|
||||||
|
fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||||
|
}
|
||||||
|
return fab;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
updateControllerState();
|
||||||
|
getApp().getMusicPlayerRemote().addOnMusicRemoteEventListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enableViews() {
|
||||||
|
super.enableViews();
|
||||||
|
fab.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableViews() {
|
||||||
|
super.disableViews();
|
||||||
|
fab.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean openCurrentPlayingIfPossible(Pair[] sharedViews) {
|
||||||
|
return super.openCurrentPlayingIfPossible(getSharedViewsWithFab(sharedViews));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void goToArtistDetailsActivity(int artistId, Pair[] sharedViews) {
|
||||||
|
super.goToArtistDetailsActivity(artistId, getSharedViewsWithFab(sharedViews));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void goToAlbumDetailsActivity(int albumId, Pair[] sharedViews) {
|
||||||
|
super.goToAlbumDetailsActivity(albumId, getSharedViewsWithFab(sharedViews));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair[] getSharedViewsWithFab(Pair[] sharedViews) {
|
||||||
|
Pair[] sharedViewsWithFab;
|
||||||
|
if (sharedViews != null) {
|
||||||
|
sharedViewsWithFab = new Pair[sharedViews.length + 1];
|
||||||
|
for (int i = 0; i < sharedViews.length; i++) {
|
||||||
|
sharedViewsWithFab[i] = sharedViews[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sharedViewsWithFab = new Pair[1];
|
||||||
|
}
|
||||||
|
sharedViewsWithFab[sharedViewsWithFab.length - 1] = Pair.create((View) getFab(), getString(R.string.transition_fab));
|
||||||
|
return sharedViewsWithFab;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateControllerState() {
|
||||||
|
updateFabState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
getApp().getMusicPlayerRemote().removeOnMusicRemoteEventListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,21 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
private Toolbar toolBar;
|
private Toolbar toolBar;
|
||||||
private ImageView image;
|
private ImageView image;
|
||||||
private View header;
|
private View header;
|
||||||
|
private SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||||
|
@Override
|
||||||
|
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||||
|
float alpha;
|
||||||
|
if (!isInNoImageMode) {
|
||||||
|
alpha = 1 - (float) Math.max(0, headerVariableSpace - scrollY) / headerVariableSpace;
|
||||||
|
} else {
|
||||||
|
ViewHelper.setTranslationY(header, scrollY);
|
||||||
|
alpha = 1;
|
||||||
|
}
|
||||||
|
ViewUtil.setBackgroundAlpha(toolBar, alpha, paletteColorPrimary);
|
||||||
|
ViewUtil.setBackgroundAlpha(header, alpha, paletteColorPrimary);
|
||||||
|
ViewHelper.setTranslationY(image, scrollY / 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
private List<String> songPaths;
|
private List<String> songPaths;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -147,23 +161,44 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void searchWebFor(List<String> strings) {
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
for (String string : strings) {
|
|
||||||
stringBuilder.append(string);
|
|
||||||
stringBuilder.append(" ");
|
|
||||||
}
|
|
||||||
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
|
|
||||||
intent.putExtra(SearchManager.QUERY, stringBuilder.toString());
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startImagePicker() {
|
private void startImagePicker() {
|
||||||
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
|
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
|
||||||
photoPickerIntent.setType("image/*");
|
photoPickerIntent.setType("image/*");
|
||||||
startActivityForResult(photoPickerIntent, REQUEST_CODE_SELECT_IMAGE);
|
startActivityForResult(photoPickerIntent, REQUEST_CODE_SELECT_IMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void loadCurrentImage();
|
||||||
|
|
||||||
|
protected abstract void getImageFromLastFM();
|
||||||
|
|
||||||
|
protected abstract void searchImageOnWeb();
|
||||||
|
|
||||||
|
protected abstract void deleteImage();
|
||||||
|
|
||||||
|
protected void setUpFab() {
|
||||||
|
ViewHelper.setScaleX(fab, 0);
|
||||||
|
ViewHelper.setScaleY(fab, 0);
|
||||||
|
fab.setEnabled(false);
|
||||||
|
fab.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void save();
|
||||||
|
|
||||||
|
private void restoreStandardColors() {
|
||||||
|
final int vibrantColor = Util.resolveColor(this, R.attr.colorPrimary);
|
||||||
|
paletteColorPrimary = vibrantColor;
|
||||||
|
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
getWindow().setStatusBarColor(vibrantColor);
|
||||||
|
getWindow().setNavigationBarColor(vibrantColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setUpTranslucence() {
|
private void setUpTranslucence() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
Util.setStatusBarTranslucent(getWindow(), false);
|
Util.setStatusBarTranslucent(getWindow(), false);
|
||||||
|
|
@ -184,6 +219,21 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract int getContentViewResId();
|
||||||
|
|
||||||
|
protected abstract List<String> getSongPaths();
|
||||||
|
|
||||||
|
protected void searchWebFor(List<String> strings) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (String string : strings) {
|
||||||
|
stringBuilder.append(string);
|
||||||
|
stringBuilder.append(" ");
|
||||||
|
}
|
||||||
|
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
|
||||||
|
intent.putExtra(SearchManager.QUERY, stringBuilder.toString());
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.menu_tag_editor, menu);
|
getMenuInflater().inflate(R.menu.menu_tag_editor, menu);
|
||||||
|
|
@ -203,16 +253,16 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setUpFab() {
|
protected void setNoImageMode() {
|
||||||
ViewHelper.setScaleX(fab, 0);
|
isInNoImageMode = true;
|
||||||
ViewHelper.setScaleY(fab, 0);
|
image.setVisibility(View.GONE);
|
||||||
fab.setEnabled(false);
|
image.setEnabled(false);
|
||||||
fab.setOnClickListener(new View.OnClickListener() {
|
scrollView.setPadding(0, Util.getActionBarSize(this), 0, 0);
|
||||||
@Override
|
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
||||||
public void onClick(View v) {
|
}
|
||||||
save();
|
|
||||||
}
|
protected void dataChanged() {
|
||||||
});
|
showFab();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showFab() {
|
private void showFab() {
|
||||||
|
|
@ -225,21 +275,17 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
fab.setEnabled(true);
|
fab.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
protected void setImageRes(int resId) {
|
||||||
@Override
|
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
|
||||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
setImageBitmap(bitmap);
|
||||||
float alpha;
|
}
|
||||||
if (!isInNoImageMode) {
|
|
||||||
alpha = 1 - (float) Math.max(0, headerVariableSpace - scrollY) / headerVariableSpace;
|
protected void setImageBitmap(final Bitmap bitmap) {
|
||||||
} else {
|
if (bitmap != null) {
|
||||||
ViewHelper.setTranslationY(header, scrollY);
|
image.setImageBitmap(bitmap);
|
||||||
alpha = 1;
|
applyPalette(bitmap);
|
||||||
}
|
|
||||||
ViewUtil.setBackgroundAlpha(toolBar, alpha, paletteColorPrimary);
|
|
||||||
ViewUtil.setBackgroundAlpha(header, alpha, paletteColorPrimary);
|
|
||||||
ViewHelper.setTranslationY(image, scrollY / 2);
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
private void applyPalette(final Bitmap bitmap) {
|
private void applyPalette(final Bitmap bitmap) {
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
|
|
@ -260,71 +306,10 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restoreStandardColors() {
|
|
||||||
final int vibrantColor = Util.resolveColor(this, R.attr.colorPrimary);
|
|
||||||
paletteColorPrimary = vibrantColor;
|
|
||||||
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
getWindow().setStatusBarColor(vibrantColor);
|
|
||||||
getWindow().setNavigationBarColor(vibrantColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setNoImageMode() {
|
|
||||||
isInNoImageMode = true;
|
|
||||||
image.setVisibility(View.GONE);
|
|
||||||
image.setEnabled(false);
|
|
||||||
scrollView.setPadding(0, Util.getActionBarSize(this), 0, 0);
|
|
||||||
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void dataChanged() {
|
|
||||||
showFab();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setImageBitmap(final Bitmap bitmap) {
|
|
||||||
if (bitmap != null) {
|
|
||||||
image.setImageBitmap(bitmap);
|
|
||||||
applyPalette(bitmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setImageRes(int resId) {
|
|
||||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
|
|
||||||
setImageBitmap(bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rescanMedia() {
|
|
||||||
String[] toBeScanned = new String[songPaths.size()];
|
|
||||||
toBeScanned = songPaths.toArray(toBeScanned);
|
|
||||||
MediaScannerConnection.scanFile(this, toBeScanned, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AudioFile getAudioFile(String path) {
|
|
||||||
try {
|
|
||||||
return AudioFileIO.read(new File(path));
|
|
||||||
} catch (CannotReadException | ReadOnlyFileException | InvalidAudioFrameException | TagException | IOException e) {
|
|
||||||
Log.e(TAG, "error while trying to create the AudioFile from File", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap) {
|
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap) {
|
||||||
writeValuesToFiles(fieldKeyValueMap, null, false);
|
writeValuesToFiles(fieldKeyValueMap, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, final Artwork artwork) {
|
|
||||||
if (artwork == null) {
|
|
||||||
writeValuesToFiles(fieldKeyValueMap, null, true);
|
|
||||||
} else {
|
|
||||||
writeValuesToFiles(fieldKeyValueMap, artwork, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, boolean deleteArtwork) {
|
|
||||||
writeValuesToFiles(fieldKeyValueMap, null, deleteArtwork);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, final Artwork artwork, final boolean deleteArtwork) {
|
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, final Artwork artwork, final boolean deleteArtwork) {
|
||||||
final String writingFileStr = getResources().getString(R.string.writing_file_number);
|
final String writingFileStr = getResources().getString(R.string.writing_file_number);
|
||||||
final MaterialDialog progressDialog = new MaterialDialog.Builder(AbsTagEditorActivity.this)
|
final MaterialDialog progressDialog = new MaterialDialog.Builder(AbsTagEditorActivity.this)
|
||||||
|
|
@ -382,6 +367,12 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void rescanMedia() {
|
||||||
|
String[] toBeScanned = new String[songPaths.size()];
|
||||||
|
toBeScanned = songPaths.toArray(toBeScanned);
|
||||||
|
MediaScannerConnection.scanFile(this, toBeScanned, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
private void restartApp() {
|
private void restartApp() {
|
||||||
Intent i = getBaseContext().getPackageManager()
|
Intent i = getBaseContext().getPackageManager()
|
||||||
.getLaunchIntentForPackage(getBaseContext().getPackageName());
|
.getLaunchIntentForPackage(getBaseContext().getPackageName());
|
||||||
|
|
@ -389,6 +380,22 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, final Artwork artwork) {
|
||||||
|
if (artwork == null) {
|
||||||
|
writeValuesToFiles(fieldKeyValueMap, null, true);
|
||||||
|
} else {
|
||||||
|
writeValuesToFiles(fieldKeyValueMap, artwork, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, boolean deleteArtwork) {
|
||||||
|
writeValuesToFiles(fieldKeyValueMap, null, deleteArtwork);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
|
||||||
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
|
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
|
||||||
|
|
@ -401,30 +408,12 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void save();
|
|
||||||
|
|
||||||
protected abstract int getContentViewResId();
|
|
||||||
|
|
||||||
protected abstract void loadCurrentImage();
|
|
||||||
|
|
||||||
protected abstract void getImageFromLastFM();
|
|
||||||
|
|
||||||
protected abstract void searchImageOnWeb();
|
|
||||||
|
|
||||||
protected abstract void loadImageFromFile(Uri selectedFile);
|
protected abstract void loadImageFromFile(Uri selectedFile);
|
||||||
|
|
||||||
protected abstract void deleteImage();
|
|
||||||
|
|
||||||
protected abstract List<String> getSongPaths();
|
|
||||||
|
|
||||||
protected App getApp() {
|
protected App getApp() {
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getSongTitle() {
|
protected String getSongTitle() {
|
||||||
try {
|
try {
|
||||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TITLE);
|
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TITLE);
|
||||||
|
|
@ -433,6 +422,15 @@ public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AudioFile getAudioFile(String path) {
|
||||||
|
try {
|
||||||
|
return AudioFileIO.read(new File(path));
|
||||||
|
} catch (CannotReadException | ReadOnlyFileException | InvalidAudioFrameException | TagException | IOException e) {
|
||||||
|
Log.e(TAG, "error while trying to create the AudioFile from File", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected String getAlbumTitle() {
|
protected String getAlbumTitle() {
|
||||||
try {
|
try {
|
||||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ALBUM);
|
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ALBUM);
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import org.jaudiotagger.tag.images.ArtworkFactory;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,14 @@ import com.nhaarman.listviewanimations.appearance.simple.AlphaInAnimationAdapter
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class NavigationDrawerFragment extends Fragment {
|
public class NavigationDrawerFragment extends Fragment {
|
||||||
private static final String TAG = NavigationDrawerFragment.class.getSimpleName();
|
|
||||||
|
|
||||||
public static final int NAVIGATION_DRAWER_HEADER = -1;
|
public static final int NAVIGATION_DRAWER_HEADER = -1;
|
||||||
|
private static final String TAG = NavigationDrawerFragment.class.getSimpleName();
|
||||||
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
|
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
|
||||||
|
|
||||||
private App app;
|
|
||||||
|
|
||||||
private NavigationDrawerCallbacks mCallbacks;
|
|
||||||
|
|
||||||
private NavigationDrawerItemAdapter drawerAdapter;
|
|
||||||
|
|
||||||
private DrawerLayout drawerLayout;
|
|
||||||
public View fragmentRootView;
|
public View fragmentRootView;
|
||||||
|
private App app;
|
||||||
|
private NavigationDrawerCallbacks mCallbacks;
|
||||||
|
private NavigationDrawerItemAdapter drawerAdapter;
|
||||||
|
private DrawerLayout drawerLayout;
|
||||||
private ListView drawerListView;
|
private ListView drawerListView;
|
||||||
private View fragmentContainerView;
|
private View fragmentContainerView;
|
||||||
|
|
||||||
|
|
@ -53,6 +48,45 @@ public class NavigationDrawerFragment extends Fragment {
|
||||||
public NavigationDrawerFragment() {
|
public NavigationDrawerFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDrawerOpen() {
|
||||||
|
return drawerLayout != null && drawerLayout.isDrawerOpen(fragmentContainerView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUp(int fragmentId, final DrawerLayout drawerLayout) {
|
||||||
|
fragmentContainerView = getActivity().findViewById(fragmentId);
|
||||||
|
this.drawerLayout = drawerLayout;
|
||||||
|
this.drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
|
||||||
|
|
||||||
|
|
||||||
|
if (!userLearnedDrawer && !fromSavedInstanceState) {
|
||||||
|
this.drawerLayout.openDrawer(fragmentContainerView);
|
||||||
|
userLearnedDrawer = true;
|
||||||
|
app.getDefaultSharedPreferences().edit().putBoolean(AppKeys.SP_USER_LEARNED_DRAWER, true).apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getSongArtist() {
|
||||||
|
return songArtist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageView getAlbumArtImageView() {
|
||||||
|
return albumArt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getSongTitle() {
|
||||||
|
return songTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity) {
|
||||||
|
super.onAttach(activity);
|
||||||
|
try {
|
||||||
|
mCallbacks = (NavigationDrawerCallbacks) activity;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
app = (App) getActivity().getApplicationContext();
|
app = (App) getActivity().getApplicationContext();
|
||||||
|
|
@ -126,23 +160,6 @@ public class NavigationDrawerFragment extends Fragment {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDrawerOpen() {
|
|
||||||
return drawerLayout != null && drawerLayout.isDrawerOpen(fragmentContainerView);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUp(int fragmentId, final DrawerLayout drawerLayout) {
|
|
||||||
fragmentContainerView = getActivity().findViewById(fragmentId);
|
|
||||||
this.drawerLayout = drawerLayout;
|
|
||||||
this.drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
|
|
||||||
|
|
||||||
|
|
||||||
if (!userLearnedDrawer && !fromSavedInstanceState) {
|
|
||||||
this.drawerLayout.openDrawer(fragmentContainerView);
|
|
||||||
userLearnedDrawer = true;
|
|
||||||
app.getDefaultSharedPreferences().edit().putBoolean(AppKeys.SP_USER_LEARNED_DRAWER, true).apply();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectItem(int position) {
|
private void selectItem(int position) {
|
||||||
if (position != NAVIGATION_DRAWER_HEADER) {
|
if (position != NAVIGATION_DRAWER_HEADER) {
|
||||||
currentSelectedPosition = position;
|
currentSelectedPosition = position;
|
||||||
|
|
@ -165,26 +182,10 @@ public class NavigationDrawerFragment extends Fragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextView getSongArtist() {
|
|
||||||
return songArtist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImageView getAlbumArtImageView() {
|
|
||||||
return albumArt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextView getSongTitle() {
|
|
||||||
return songTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
super.onAttach(activity);
|
super.onSaveInstanceState(outState);
|
||||||
try {
|
outState.putInt(STATE_SELECTED_POSITION, currentSelectedPosition);
|
||||||
mCallbacks = (NavigationDrawerCallbacks) activity;
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -193,12 +194,6 @@ public class NavigationDrawerFragment extends Fragment {
|
||||||
mCallbacks = null;
|
mCallbacks = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putInt(STATE_SELECTED_POSITION, currentSelectedPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface NavigationDrawerCallbacks {
|
public static interface NavigationDrawerCallbacks {
|
||||||
void onNavigationDrawerItemSelected(int position);
|
void onNavigationDrawerItemSelected(int position);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,44 @@ public abstract class AbsViewPagerTabArtistListFragment extends Fragment impleme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* IMPORTANT:
|
||||||
|
*
|
||||||
|
* You CAN return null here and use setAdapter(ListAdapter adapter) inside getAdapter() to manually set the adapter.
|
||||||
|
*
|
||||||
|
* (i.e. if you must set the adapter async).
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
protected abstract ListAdapter getAdapter();
|
||||||
|
|
||||||
|
protected void setAdapter(ListAdapter adapter) {
|
||||||
|
observableGridView.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
enableViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enableViews() {
|
||||||
|
areViewsEnabled = true;
|
||||||
|
observableGridView.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableViews() {
|
||||||
|
areViewsEnabled = false;
|
||||||
|
observableGridView.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areViewsEnabled() {
|
||||||
|
return areViewsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
public int getY() {
|
public int getY() {
|
||||||
return observableGridView.getCurrentScrollY() + paddingViewHeight;
|
return observableGridView.getCurrentScrollY() + paddingViewHeight;
|
||||||
}
|
}
|
||||||
|
|
@ -84,10 +122,6 @@ public abstract class AbsViewPagerTabArtistListFragment extends Fragment impleme
|
||||||
return parentActivity;
|
return parentActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setAdapter(ListAdapter adapter) {
|
|
||||||
observableGridView.setAdapter(adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
|
protected void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
|
||||||
observableGridView.setOnItemClickListener(onItemClickListener);
|
observableGridView.setOnItemClickListener(onItemClickListener);
|
||||||
}
|
}
|
||||||
|
|
@ -96,17 +130,6 @@ public abstract class AbsViewPagerTabArtistListFragment extends Fragment impleme
|
||||||
observableGridView.setNumColumns(columns);
|
observableGridView.setNumColumns(columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* IMPORTANT:
|
|
||||||
*
|
|
||||||
* You CAN return null here and use setAdapter(ListAdapter adapter) inside getAdapter() to manually set the adapter.
|
|
||||||
*
|
|
||||||
* (i.e. if you must set the adapter async).
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
protected abstract ListAdapter getAdapter();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||||
|
|
@ -125,27 +148,4 @@ public abstract class AbsViewPagerTabArtistListFragment extends Fragment impleme
|
||||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableViews() {
|
|
||||||
areViewsEnabled = false;
|
|
||||||
observableGridView.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean areViewsEnabled() {
|
|
||||||
return areViewsEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableViews() {
|
|
||||||
areViewsEnabled = true;
|
|
||||||
observableGridView.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
enableViews();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,6 @@ public class ViewPagerTabArtistAlbumFragment extends AbsViewPagerTabArtistListFr
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
fab = (FloatingActionButton) getParentActivity().findViewById(R.id.fab);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void openAlbumDetailsActivityIfPossible(Album album, View albumArtForTransition) {
|
private void openAlbumDetailsActivityIfPossible(Album album, View albumArtForTransition) {
|
||||||
if (areParentActivitiesViewsEnabled()) {
|
if (areParentActivitiesViewsEnabled()) {
|
||||||
|
|
@ -83,4 +77,10 @@ public class ViewPagerTabArtistAlbumFragment extends AbsViewPagerTabArtistListFr
|
||||||
private boolean areParentActivitiesViewsEnabled() {
|
private boolean areParentActivitiesViewsEnabled() {
|
||||||
return !(getParentActivity() instanceof KabViewsDisableAble) || ((KabViewsDisableAble) getParentActivity()).areViewsEnabled();
|
return !(getParentActivity() instanceof KabViewsDisableAble) || ((KabViewsDisableAble) getParentActivity()).areViewsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
fab = (FloatingActionButton) getParentActivity().findViewById(R.id.fab);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,23 @@ public class AlbumViewFragment extends Fragment implements KabViewsDisableAble,
|
||||||
enableViews();
|
enableViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enableViews() {
|
||||||
|
areViewsEnabled = true;
|
||||||
|
absListView.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableViews() {
|
||||||
|
areViewsEnabled = false;
|
||||||
|
absListView.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areViewsEnabled() {
|
||||||
|
return areViewsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
absListView = (AbsListView) fragmentRootView.findViewById(R.id.absList);
|
absListView = (AbsListView) fragmentRootView.findViewById(R.id.absList);
|
||||||
fab = (FloatingActionButton) getActivity().findViewById(R.id.fab);
|
fab = (FloatingActionButton) getActivity().findViewById(R.id.fab);
|
||||||
|
|
@ -82,11 +99,6 @@ public class AlbumViewFragment extends Fragment implements KabViewsDisableAble,
|
||||||
fillAbsListView(albums);
|
fillAbsListView(albums);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpAbsListView(String query) {
|
|
||||||
List<Album> albums = AlbumLoader.getAlbums(getActivity(), query);
|
|
||||||
fillAbsListView(albums);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillAbsListView(List<Album> albums) {
|
private void fillAbsListView(List<Album> albums) {
|
||||||
Collections.sort(albums, new AlbumAlphabeticComparator());
|
Collections.sort(albums, new AlbumAlphabeticComparator());
|
||||||
AlbumViewGridAdapter albumTileAdapter = new AlbumViewGridAdapter(getActivity(), albums);
|
AlbumViewGridAdapter albumTileAdapter = new AlbumViewGridAdapter(getActivity(), albums);
|
||||||
|
|
@ -144,28 +156,16 @@ public class AlbumViewFragment extends Fragment implements KabViewsDisableAble,
|
||||||
return !(getActivity() instanceof KabViewsDisableAble) || ((KabViewsDisableAble) getActivity()).areViewsEnabled();
|
return !(getActivity() instanceof KabViewsDisableAble) || ((KabViewsDisableAble) getActivity()).areViewsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableViews() {
|
|
||||||
areViewsEnabled = false;
|
|
||||||
absListView.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean areViewsEnabled() {
|
|
||||||
return areViewsEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableViews() {
|
|
||||||
areViewsEnabled = true;
|
|
||||||
absListView.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void search(String query) {
|
public void search(String query) {
|
||||||
setUpAbsListView(query);
|
setUpAbsListView(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpAbsListView(String query) {
|
||||||
|
List<Album> albums = AlbumLoader.getAlbums(getActivity(), query);
|
||||||
|
fillAbsListView(albums);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void returnToNonSearch() {
|
public void returnToNonSearch() {
|
||||||
setUpAbsListView();
|
setUpAbsListView();
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,23 @@ public class ArtistViewFragment extends Fragment implements KabSearchAbleFragmen
|
||||||
enableViews();
|
enableViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enableViews() {
|
||||||
|
areViewsEnabled = true;
|
||||||
|
absListView.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableViews() {
|
||||||
|
areViewsEnabled = false;
|
||||||
|
absListView.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areViewsEnabled() {
|
||||||
|
return areViewsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
absListView = (AbsListView) fragmentRootView.findViewById(R.id.absList);
|
absListView = (AbsListView) fragmentRootView.findViewById(R.id.absList);
|
||||||
}
|
}
|
||||||
|
|
@ -78,11 +95,6 @@ public class ArtistViewFragment extends Fragment implements KabSearchAbleFragmen
|
||||||
fillAbsListView(artists);
|
fillAbsListView(artists);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpAbsListView(String query) {
|
|
||||||
List<Artist> artists = ArtistLoader.getArtists(getActivity(), query);
|
|
||||||
fillAbsListView(artists);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillAbsListView(List<Artist> artists) {
|
private void fillAbsListView(List<Artist> artists) {
|
||||||
Collections.sort(artists, new ArtistAlphabeticComparator());
|
Collections.sort(artists, new ArtistAlphabeticComparator());
|
||||||
ArtistViewListAdapter artistAdapter = new ArtistViewListAdapter(getActivity(), artists);
|
ArtistViewListAdapter artistAdapter = new ArtistViewListAdapter(getActivity(), artists);
|
||||||
|
|
@ -121,6 +133,11 @@ public class ArtistViewFragment extends Fragment implements KabSearchAbleFragmen
|
||||||
setUpAbsListView(query);
|
setUpAbsListView(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpAbsListView(String query) {
|
||||||
|
List<Artist> artists = ArtistLoader.getArtists(getActivity(), query);
|
||||||
|
fillAbsListView(artists);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void returnToNonSearch() {
|
public void returnToNonSearch() {
|
||||||
setUpAbsListView();
|
setUpAbsListView();
|
||||||
|
|
@ -135,21 +152,4 @@ public class ArtistViewFragment extends Fragment implements KabSearchAbleFragmen
|
||||||
private boolean areParentActivityViewsEnabled() {
|
private boolean areParentActivityViewsEnabled() {
|
||||||
return !(getActivity() instanceof KabViewsDisableAble) || ((KabViewsDisableAble) getActivity()).areViewsEnabled();
|
return !(getActivity() instanceof KabViewsDisableAble) || ((KabViewsDisableAble) getActivity()).areViewsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableViews() {
|
|
||||||
areViewsEnabled = true;
|
|
||||||
absListView.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableViews() {
|
|
||||||
areViewsEnabled = false;
|
|
||||||
absListView.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean areViewsEnabled() {
|
|
||||||
return areViewsEnabled;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,11 +66,6 @@ public class SongViewFragment extends Fragment implements KabSearchAbleFragment
|
||||||
fillAbsListView(songs);
|
fillAbsListView(songs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpAbsListView(String query) {
|
|
||||||
List<Song> songs = SongLoader.getSongs(getActivity(), query);
|
|
||||||
fillAbsListView(songs);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillAbsListView(final List<Song> songs) {
|
private void fillAbsListView(final List<Song> songs) {
|
||||||
Collections.sort(songs, new SongAlphabeticComparator());
|
Collections.sort(songs, new SongAlphabeticComparator());
|
||||||
AbsBaseActivity absBaseActivity = null;
|
AbsBaseActivity absBaseActivity = null;
|
||||||
|
|
@ -102,6 +97,11 @@ public class SongViewFragment extends Fragment implements KabSearchAbleFragment
|
||||||
setUpAbsListView(query);
|
setUpAbsListView(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpAbsListView(String query) {
|
||||||
|
List<Song> songs = SongLoader.getSongs(getActivity(), query);
|
||||||
|
fillAbsListView(songs);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void returnToNonSearch() {
|
public void returnToNonSearch() {
|
||||||
setUpAbsListView();
|
setUpAbsListView();
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,11 @@ public class MusicUtil {
|
||||||
contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null);
|
contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File getAlbumArtFile(Context context, String name)
|
||||||
|
throws IOException {
|
||||||
|
return new File(createAlbumArtDir(context), name + System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
public static File createAlbumArtDir(Context paramContext) {
|
public static File createAlbumArtDir(Context paramContext) {
|
||||||
File albumArtDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "/.albumart/");
|
File albumArtDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "/.albumart/");
|
||||||
if (!albumArtDir.exists()) {
|
if (!albumArtDir.exists()) {
|
||||||
|
|
@ -68,9 +73,4 @@ public class MusicUtil {
|
||||||
}
|
}
|
||||||
return albumArtDir;
|
return albumArtDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getAlbumArtFile(Context context, String name)
|
|
||||||
throws IOException {
|
|
||||||
return new File(createAlbumArtDir(context), name + System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ import com.kabouzeid.materialmusic.misc.AppKeys;
|
||||||
* Created by karim on 12.12.14.
|
* Created by karim on 12.12.14.
|
||||||
*/
|
*/
|
||||||
public class Util {
|
public class Util {
|
||||||
|
private static int albumArtSize = 600;
|
||||||
|
|
||||||
public static int resolveDrawable(Context context, int drawable) {
|
public static int resolveDrawable(Context context, int drawable) {
|
||||||
TypedArray a = context.obtainStyledAttributes(new int[]{drawable});
|
TypedArray a = context.obtainStyledAttributes(new int[]{drawable});
|
||||||
int resId = a.getResourceId(0, 0);
|
int resId = a.getResourceId(0, 0);
|
||||||
|
|
@ -160,8 +162,6 @@ public class Util {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int albumArtSize = 600;
|
|
||||||
|
|
||||||
public static Bitmap getAlbumArtScaledBitmap(final Bitmap bitmap, boolean keepAspectRatio) {
|
public static Bitmap getAlbumArtScaledBitmap(final Bitmap bitmap, boolean keepAspectRatio) {
|
||||||
if (keepAspectRatio) {
|
if (keepAspectRatio) {
|
||||||
double aspectRatio = (double) bitmap.getHeight() / (double) bitmap.getWidth();
|
double aspectRatio = (double) bitmap.getHeight() / (double) bitmap.getWidth();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<item android:state_activated="true" android:drawable="@drawable/list_item_activated"/>
|
<item android:drawable="@drawable/list_item_activated" android:state_activated="true"/>
|
||||||
<item android:state_pressed="true" android:drawable="@drawable/list_item_selected"/>
|
<item android:drawable="@drawable/list_item_selected" android:state_pressed="true"/>
|
||||||
<item android:drawable="@drawable/transparent"/>
|
<item android:drawable="@drawable/transparent"/>
|
||||||
|
|
||||||
</selector>
|
</selector>
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<item android:state_activated="true" android:drawable="@drawable/list_item_activated_dark"/>
|
|
||||||
<item android:state_pressed="true" android:drawable="@drawable/list_item_selected_dark"/>
|
|
||||||
<item android:drawable="@drawable/transparent"/>
|
|
||||||
|
|
||||||
</selector>
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:fab="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
@ -137,7 +136,6 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:id="@+id/prev_button"
|
android:id="@+id/prev_button"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
|
@ -145,10 +143,10 @@
|
||||||
android:layout_toLeftOf="@+id/fab"
|
android:layout_toLeftOf="@+id/fab"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="14dp"
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_skip_previous_white_48dp"/>
|
android:src="@drawable/ic_skip_previous_white_48dp"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:id="@+id/next_button"
|
android:id="@+id/next_button"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
|
@ -156,30 +154,31 @@
|
||||||
android:layout_toRightOf="@+id/fab"
|
android:layout_toRightOf="@+id/fab"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="14dp"
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_skip_next_white_48dp"/>
|
android:src="@drawable/ic_skip_next_white_48dp"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:id="@+id/repeat_button"
|
android:id="@+id/repeat_button"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="14dp"
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_repeat_grey600_48dp"/>
|
android:src="@drawable/ic_repeat_grey600_48dp"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:id="@+id/shuffle_button"
|
android:id="@+id/shuffle_button"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="14dp"
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_shuffle_grey600_48dp"/>
|
android:src="@drawable/ic_shuffle_grey600_48dp"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
||||||
|
|
@ -74,16 +74,16 @@
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/button_toggle_play_pause"
|
android:id="@+id/button_toggle_play_pause"
|
||||||
style="@style/NotificationButton"
|
style="@style/NotificationButton"
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
|
android:paddingTop="16dp"
|
||||||
android:src="@drawable/ic_play_arrow_white_48dp"
|
android:src="@drawable/ic_play_arrow_white_48dp"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/button_next"
|
android:id="@+id/button_next"
|
||||||
style="@style/NotificationButton"
|
style="@style/NotificationButton"
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
|
android:paddingTop="16dp"
|
||||||
android:src="@drawable/ic_skip_next_white_48dp"
|
android:src="@drawable/ic_skip_next_white_48dp"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,9 +158,9 @@
|
||||||
<com.melnykov.fab.FloatingActionButton
|
<com.melnykov.fab.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
style="@style/PlayPauseFab"
|
style="@style/PlayPauseFab"
|
||||||
android:src="@drawable/ic_done_white_48dp"
|
android:layout_gravity="bottom|right"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:layout_gravity="bottom|right"/>
|
android:src="@drawable/ic_done_white_48dp"/>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,11 +88,11 @@
|
||||||
android:background="@android:color/transparent"/>
|
android:background="@android:color/transparent"/>
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<android.support.v7.widget.Toolbar
|
||||||
android:elevation="@dimen/toolbar_elevation"
|
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:background="@android:color/transparent"/>
|
android:background="@android:color/transparent"
|
||||||
|
android:elevation="@dimen/toolbar_elevation"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.melnykov.fab.FloatingActionButton
|
<com.melnykov.fab.FloatingActionButton
|
||||||
|
|
|
||||||
|
|
@ -6,21 +6,21 @@
|
||||||
tools:context="com.kabouzeid.materialmusic.ui.activities.AlbumDetailActivity$PlaceholderFragment">
|
tools:context="com.kabouzeid.materialmusic.ui.activities.AlbumDetailActivity$PlaceholderFragment">
|
||||||
|
|
||||||
<com.kabouzeid.materialmusic.view.SquareImageView
|
<com.kabouzeid.materialmusic.view.SquareImageView
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:background="@color/black"
|
|
||||||
android:id="@+id/album_art"
|
android:id="@+id/album_art"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/black"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/default_album_art"
|
android:src="@drawable/default_album_art"
|
||||||
android:transitionName="@string/transition_album_cover"/>
|
android:transitionName="@string/transition_album_cover"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/navigation_drawer_gradient"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_above="@+id/footer"
|
android:layout_above="@+id/footer"
|
||||||
android:layout_alignTop="@+id/progress_container"/>
|
android:layout_alignTop="@+id/progress_container"
|
||||||
|
android:background="@drawable/navigation_drawer_gradient"
|
||||||
|
android:orientation="vertical"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/progress_container"
|
android:id="@+id/progress_container"
|
||||||
|
|
@ -60,13 +60,13 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/album_art"
|
android:layout_below="@id/album_art"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
android:elevation="1dp"
|
||||||
|
android:orientation="vertical"
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
android:paddingLeft="72dp"
|
android:paddingLeft="72dp"
|
||||||
android:paddingRight="72dp"
|
android:paddingRight="72dp"
|
||||||
android:paddingTop="16dp"
|
android:paddingTop="16dp"
|
||||||
android:background="?attr/colorPrimary"
|
|
||||||
android:elevation="1dp"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:transitionName="@string/transition_album_text"
|
android:transitionName="@string/transition_album_text"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|
@ -74,8 +74,8 @@
|
||||||
android:id="@+id/song_title"
|
android:id="@+id/song_title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:singleLine="true"
|
|
||||||
android:fontFamily="sans-serif-medium"
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||||
android:textColor="?attr/title_text_color"/>
|
android:textColor="?attr/title_text_color"/>
|
||||||
|
|
||||||
|
|
@ -83,8 +83,8 @@
|
||||||
android:id="@+id/song_artist"
|
android:id="@+id/song_artist"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:singleLine="true"
|
|
||||||
android:fontFamily="sans-serif"
|
android:fontFamily="sans-serif"
|
||||||
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
android:textColor="?attr/caption_text_color"/>
|
android:textColor="?attr/caption_text_color"/>
|
||||||
|
|
||||||
|
|
@ -103,12 +103,11 @@
|
||||||
|
|
||||||
<com.melnykov.fab.FloatingActionButton
|
<com.melnykov.fab.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
android:layout_centerInParent="true"
|
|
||||||
style="@style/PlayPauseFab"
|
style="@style/PlayPauseFab"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:id="@+id/prev_button"
|
android:id="@+id/prev_button"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
|
@ -117,10 +116,10 @@
|
||||||
android:layout_toLeftOf="@+id/fab"
|
android:layout_toLeftOf="@+id/fab"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="14dp"
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_skip_previous_white_48dp"/>
|
android:src="@drawable/ic_skip_previous_white_48dp"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:id="@+id/next_button"
|
android:id="@+id/next_button"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
|
@ -129,30 +128,31 @@
|
||||||
android:layout_toRightOf="@+id/fab"
|
android:layout_toRightOf="@+id/fab"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="14dp"
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_skip_next_white_48dp"/>
|
android:src="@drawable/ic_skip_next_white_48dp"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:id="@+id/repeat_button"
|
android:id="@+id/repeat_button"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="14dp"
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_repeat_grey600_48dp"/>
|
android:src="@drawable/ic_repeat_grey600_48dp"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:id="@+id/shuffle_button"
|
android:id="@+id/shuffle_button"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="14dp"
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_shuffle_grey600_48dp"/>
|
android:src="@drawable/ic_shuffle_grey600_48dp"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:fab="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
|
|
@ -198,9 +197,9 @@
|
||||||
<com.melnykov.fab.FloatingActionButton
|
<com.melnykov.fab.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
style="@style/PlayPauseFab"
|
style="@style/PlayPauseFab"
|
||||||
android:src="@drawable/ic_done_white_48dp"
|
android:layout_gravity="bottom|right"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:layout_gravity="bottom|right"/>
|
android:src="@drawable/ic_done_white_48dp"/>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,49 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:padding="4dp"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:descendantFocusability="blocksDescendants"
|
android:descendantFocusability="blocksDescendants"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:padding="4dp">
|
||||||
|
|
||||||
<com.kabouzeid.materialmusic.view.SquareImageView
|
<com.kabouzeid.materialmusic.view.SquareImageView
|
||||||
android:transitionName="@string/transition_album_cover"
|
|
||||||
android:id="@+id/album_art"
|
android:id="@+id/album_art"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scaleType="centerCrop"/>
|
android:scaleType="centerCrop"
|
||||||
|
android:transitionName="@string/transition_album_cover"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:transitionName="@string/transition_album_text"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:background="?attr/colorPrimary"
|
|
||||||
android:id="@+id/footer"
|
android:id="@+id/footer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:transitionName="@string/transition_album_text">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
|
||||||
android:fontFamily="sans-serif-medium"
|
|
||||||
android:textColor="?attr/title_text_color"
|
|
||||||
android:id="@+id/album_title"
|
android:id="@+id/album_title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="sans-serif-medium"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||||
|
android:textColor="?attr/title_text_color"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
tools:text="Album Title"/>
|
tools:text="Album Title"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:textColor="?attr/caption_text_color"
|
|
||||||
android:id="@+id/album_interpret"
|
android:id="@+id/album_interpret"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
|
android:textColor="?attr/caption_text_color"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
tools:text="Interpret"/>
|
tools:text="Interpret"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<com.mobeta.android.dslv.DragSortListView
|
<com.mobeta.android.dslv.DragSortListView
|
||||||
app:max_drag_scroll_speed="2"
|
|
||||||
app:float_alpha="0.5"
|
|
||||||
app:drag_start_mode="onLongPress"
|
|
||||||
app:use_default_controller="true"
|
|
||||||
android:id="@+id/dragSortListView"
|
android:id="@+id/dragSortListView"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
app:drag_start_mode="onLongPress"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"/>
|
app:float_alpha="0.5"
|
||||||
|
app:max_drag_scroll_speed="2"
|
||||||
|
app:use_default_controller="true"/>
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
|
||||||
tools:context=".DrawerActivity$PlaceholderFragment">
|
tools:context=".DrawerActivity$PlaceholderFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:clickable="true"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?colorPrimary"
|
android:background="?colorPrimary"
|
||||||
|
android:clickable="true"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
|
||||||
android:fontFamily="sans-serif-medium"
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Comming soon!"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||||
android:textColor="?title_text_color"
|
android:textColor="?title_text_color"/>
|
||||||
android:text="Comming soon!"/>
|
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,23 @@
|
||||||
|
|
||||||
<com.kabouzeid.materialmusic.view.SquareImageView
|
<com.kabouzeid.materialmusic.view.SquareImageView
|
||||||
android:id="@+id/artist_image"
|
android:id="@+id/artist_image"
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:gravity="center"
|
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/artist_name"
|
android:id="@+id/artist_name"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:singleLine="true"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"/>
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/list_selector"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:background="?attr/list_selector"
|
|
||||||
android:padding="16dp">
|
android:padding="16dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
android:descendantFocusability="blocksDescendants"
|
android:descendantFocusability="blocksDescendants"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
>
|
>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/song_title"
|
android:id="@+id/song_title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:descendantFocusability="blocksDescendants"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="64dp"
|
android:layout_height="64dp"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:descendantFocusability="blocksDescendants"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -11,21 +11,21 @@
|
||||||
android:id="@+id/album_art"
|
android:id="@+id/album_art"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:gravity="center"
|
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/song_title"
|
android:id="@+id/song_title"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:singleLine="true"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"/>
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/menu"
|
android:id="@+id/menu"
|
||||||
|
|
|
||||||
|
|
@ -75,16 +75,16 @@
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/button_toggle_play_pause"
|
android:id="@+id/button_toggle_play_pause"
|
||||||
style="@style/NotificationButton"
|
style="@style/NotificationButton"
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
|
android:paddingTop="16dp"
|
||||||
android:src="@drawable/ic_play_arrow_white_48dp"
|
android:src="@drawable/ic_play_arrow_white_48dp"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/button_next"
|
android:id="@+id/button_next"
|
||||||
style="@style/NotificationButton"
|
style="@style/NotificationButton"
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
|
android:paddingTop="16dp"
|
||||||
android:src="@drawable/ic_skip_next_white_48dp"
|
android:src="@drawable/ic_skip_next_white_48dp"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView android:id="@android:id/text1"
|
||||||
android:id="@android:id/text1"
|
|
||||||
style="@style/ThemeOverlay.AppCompat.Light"
|
style="@style/ThemeOverlay.AppCompat.Light"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,21 @@
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_current_playing"
|
android:id="@+id/action_current_playing"
|
||||||
android:title="@string/action_current_playing"
|
|
||||||
android:icon="@drawable/music_box"
|
android:icon="@drawable/music_box"
|
||||||
|
android:title="@string/action_current_playing"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_search"
|
android:id="@+id/action_search"
|
||||||
android:title="@string/action_search"
|
|
||||||
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
|
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
|
||||||
app:showAsAction="collapseActionView|ifRoom"
|
android:title="@string/action_search"
|
||||||
app:actionViewClass="android.support.v7.widget.SearchView"/>
|
app:actionViewClass="android.support.v7.widget.SearchView"
|
||||||
|
app:showAsAction="collapseActionView|ifRoom"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:icon="@drawable/settings"
|
android:icon="@drawable/settings"
|
||||||
android:title="@string/action_settings"
|
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/action_settings"
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:title="@string/action_settings"
|
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/action_settings"
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_current_playing"
|
android:id="@+id/action_current_playing"
|
||||||
android:title="@string/action_current_playing"
|
|
||||||
android:icon="@drawable/music_box"
|
android:icon="@drawable/music_box"
|
||||||
|
android:title="@string/action_current_playing"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:title="@string/action_settings"
|
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/action_settings"
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_current_playing"
|
android:id="@+id/action_current_playing"
|
||||||
android:title="@string/action_current_playing"
|
|
||||||
android:icon="@drawable/music_box"
|
android:icon="@drawable/music_box"
|
||||||
|
android:title="@string/action_current_playing"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:title="@string/action_settings"
|
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/action_settings"
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
tools:context="com.kabouzeid.materialmusic.ui.activities.tageditor.SongTagEditorActivity">
|
tools:context="com.kabouzeid.materialmusic.ui.activities.tageditor.SongTagEditorActivity">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:title="@string/action_settings"
|
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/action_settings"
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
tools:context="com.kabouzeid.materialmusic.ui.activities.MusicControllerActivity">
|
tools:context="com.kabouzeid.materialmusic.ui.activities.MusicControllerActivity">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_playing_queue"
|
android:id="@+id/action_playing_queue"
|
||||||
android:title="@string/action_playing_queue"
|
|
||||||
android:icon="@drawable/playlist"
|
android:icon="@drawable/playlist"
|
||||||
|
android:title="@string/action_playing_queue"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_add_to_playlist"
|
android:id="@+id/action_add_to_playlist"
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:title="@string/action_settings"
|
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/action_settings"
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue