package com.ideabag.playtunes.fragment;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.ideabag.playtunes.PlaylistManager;
import com.ideabag.playtunes.R;
import com.ideabag.playtunes.activity.MainActivity;
import com.ideabag.playtunes.database.MediaQuery;
import com.ideabag.playtunes.dialog.SongMenuDialogFragment;
import com.ideabag.playtunes.media.PlaylistMediaPlayer;
import com.ideabag.playtunes.media.PlaylistMediaPlayer.PlaybackListener;
import com.ideabag.playtunes.slidinguppanel.SlidingUpPanelLayout;
import com.ideabag.playtunes.slidinguppanel.SlidingUpPanelLayout.PanelSlideListener;
import com.ideabag.playtunes.slidinguppanel.SlidingUpPanelLayout.PanelState;
import com.ideabag.playtunes.util.GAEvent.AudioControls;
import com.ideabag.playtunes.util.GAEvent.Categories;
import com.ideabag.playtunes.util.AsyncDrawable;
import com.ideabag.playtunes.util.BitmapWorkerTask;
import com.ideabag.playtunes.util.StarToggleTask;
import com.ideabag.playtunes.util.TrackerSingleton;
import com.ideabag.playtunes.widget.StarButton;
import com.ideabag.playtunes.widget.TimeProgressBar;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewCompat;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ToggleButton;
public class FooterControlsFragment extends Fragment {
public static final String TAG = "FooterControlsFragment";
private MainActivity mActivity;
private Tracker mTracker;
private String lastAlbumUri = null;
private String current_media_id;
private boolean isPlaying = false;
private boolean isShowing = false;
SlidingUpPanelLayout mSlidingPanel;
//
// Views from fragment_footer_controls_expanded.xml
//
//
//
//
private ImageButton mCompactPlayPauseButton;
private ImageButton mCompactNextButton;
private ImageButton mCompactPrevButton;
private ImageView mCompactAlbumCover;
//
// Compact controls: album thumbnail, song title, song artist, mini progress bar
// This also includes the star button and song menu button for the expanded view
//
private RelativeLayout mCompactAlbumArtContainer;
private StarButton mStarButton;
private TextView mTitle, mArtist;
private LinearLayout mCompactPlaybackControls;
private ImageButton mSongMenuButton;
//
// Expanded control views: repeat, back, play/pause, next, and shuffle
//
private ImageButton mExpControlsRepeatButton;
private ImageButton mExpControlsShuffleButton;
private ImageButton mExpControlsPrevButton;
private ImageButton mExpControlsNextButton;
private ImageButton mExpControlsPlayPauseButton;
//
//
//
private ImageView mFullAlbumArt;
RelativeLayout mFullAlbumArtContainer;
ImageView mAlbumArtBackground;
private TrackProgressFragment mProgressFragment;
private TimeProgressBar mCompactProgressBar;
private Fragment mFragmentSelf;
private PlaylistManager mPlaylistManager;
@Override public void onAttach( Activity activity ) {
super.onAttach( activity );
mActivity = ( MainActivity ) activity;
mTracker = TrackerSingleton.getDefaultTracker( mActivity );
mFragmentSelf = this;
mPlaylistManager = new PlaylistManager( activity );
}
@SuppressLint("NewApi")
@Override public void onActivityCreated( Bundle savedInstanceState ) {
super.onActivityCreated( savedInstanceState );
mSlidingPanel = ( SlidingUpPanelLayout ) getActivity().findViewById( R.id.sliding_layout );
mSlidingPanel.setPanelSlideListener( new PanelSlideListener() {
float mPreviousOffset = 0f;
// offset of 1.0 = top, offset of 0 = bottom
@Override public void onPanelSlide(View panel, float slideOffset) {
if ( slideOffset > mPreviousOffset && slideOffset > 0.5f ) {
showFull();
} else if ( mPreviousOffset > slideOffset && slideOffset < 0.5f ) {
showCollapsed();
}
mPreviousOffset = slideOffset;
}
@Override public void onPanelCollapsed( View panel ) {
showCollapsed();
}
@Override public void onPanelExpanded( View panel ) {
showFull();
}
@Override public void onPanelAnchored( View panel ) { }
@Override public void onPanelHidden( View panel ) { }
});
//getView().findViewById( R.id.FooterControls ).setOnClickListener( controlsClickListener );
//
// Compact media controls
//
mTitle = ( TextView ) getView().findViewById( R.id.ControlsTitle );
mArtist = ( TextView ) getView().findViewById( R.id.ControlsSubtitle );
mCompactAlbumCover = ( ImageView ) getView().findViewById( R.id.CompactAlbumArt );
mStarButton = ( StarButton ) getView().findViewById( R.id.StarButton );
mSongMenuButton = ( ImageButton ) getView().findViewById( R.id.MenuButton );
mCompactProgressBar = (TimeProgressBar) getView().findViewById( R.id.CompactProgressBar );
mCompactPlaybackControls = ( LinearLayout ) getView().findViewById( R.id.CompactPlaybackControls );
mCompactAlbumArtContainer = ( RelativeLayout ) getView().findViewById( R.id.CompactAlbumArtContainer );
mCompactPlayPauseButton = ( ImageButton ) getView().findViewById( R.id.CompactPlayPauseButton );
// Previous and Next may be null, they only appear on larger screen devices
mCompactNextButton = ( ImageButton ) getView().findViewById( R.id.CompactNextButton );
mCompactPrevButton = ( ImageButton ) getView().findViewById( R.id.CompactPrevButton );
if ( null != mCompactPrevButton ) {
mCompactPrevButton.setOnClickListener( controlsClickListener );
}
if ( null != mCompactNextButton ) {
mCompactNextButton.setOnClickListener( controlsClickListener );
}
mSongMenuButton.setOnClickListener( controlsClickListener );
mStarButton.setOnClickListener( controlsClickListener );
mCompactPlayPauseButton.setOnClickListener( controlsClickListener );
//
// Expanded media controls
//
mExpControlsRepeatButton = ( ImageButton ) getView().findViewById( R.id.NowPlayingRepeatButton );
mExpControlsShuffleButton = ( ImageButton ) getView().findViewById( R.id.NowPlayingShuffleButton );
mExpControlsPrevButton = ( ImageButton ) getView().findViewById( R.id.NowPlayingPrevButton );
mExpControlsNextButton = ( ImageButton ) getView().findViewById( R.id.NowPlayingNextButton );
mExpControlsPlayPauseButton = ( ImageButton ) getView().findViewById( R.id.NowPlayingPlayPauseButton );
mExpControlsPrevButton.setOnClickListener( controlsClickListener );
mExpControlsShuffleButton.setOnClickListener( controlsClickListener );
mExpControlsRepeatButton.setOnClickListener( controlsClickListener );
mExpControlsNextButton.setOnClickListener( controlsClickListener );
mExpControlsPlayPauseButton.setOnClickListener( controlsClickListener );
mExpControlsNextButton.setOnClickListener( controlsClickListener );
//
// Full controls, with large album art and SeekBar
//
mFullAlbumArtContainer = (RelativeLayout) getView().findViewById( R.id.FullAlbumArtContainer );
mFullAlbumArt = ( ImageView ) getView().findViewById( R.id.FullAlbumArt );
mProgressFragment = ( TrackProgressFragment ) getChildFragmentManager().findFragmentById( R.id.TrackProgressFragment );
mAlbumArtBackground = ( ImageView ) getView().findViewById( R.id.AlbumArtBackground );
mAlbumArtBackground.setColorFilter( getResources().getColor( R.color.textColorPrimary ), PorterDuff.Mode.MULTIPLY );
mCompactPlaybackControls.setOnClickListener( controlsClickListener );
//showCollapsed();
ViewCompat.setElevation(mCompactPlaybackControls, 8 );
}
@Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
return inflater.inflate( R.layout.fragment_footer_controls_expanded, container, false );
}
@Override public void onResume() {
super.onResume();
PanelState state = mSlidingPanel.getPanelState();
if ( state == PanelState.COLLAPSED ) {
showCollapsed();
} else if ( state == PanelState.EXPANDED ) {
showFull();
}
mActivity.addPlaybackListener( PlaybackListener );
}
@Override public void onPause() {
super.onPause();
}
@Override public void onDestroyView() {
super.onDestroyView();
//recycleAlbumArt();
}
View.OnClickListener controlsClickListener = new View.OnClickListener() {
@Override public void onClick( View v ) {
int id = v.getId();
if ( id == R.id.CompactPlaybackControls ) {
PanelState state = mSlidingPanel.getPanelState();
if ( state == PanelState.COLLAPSED ) {
mSlidingPanel.setPanelState( PanelState.EXPANDED );
} else if ( state == PanelState.EXPANDED ) {
mSlidingPanel.setPanelState( PanelState.COLLAPSED );
}
} else if ( id == R.id.NowPlayingPlayPauseButton || id == R.id.CompactPlayPauseButton ) {
if ( isPlaying ) {
mActivity.mBoundService.pause();
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( Categories.FOOTER_CONTROLS )
.setAction( AudioControls.ACTION_PAUSE )
.build());
} else {
mActivity.mBoundService.play();
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( Categories.FOOTER_CONTROLS )
.setAction( AudioControls.ACTION_PLAY )
.build());
}
} else if ( id == R.id.NowPlayingNextButton || id == R.id.CompactNextButton ) {
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "next" )
.build());
mActivity.mBoundService.next();
} else if ( id == R.id.NowPlayingPrevButton || id == R.id.CompactPrevButton ) {
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "previous" )
.build());
mActivity.mBoundService.prev();
} else if ( id == R.id.StarButton ) {
//current_media_id
ToggleButton starButton = (ToggleButton) v;
if ( starButton.isChecked() ) {
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "star" )
.setValue( 1 )
.build());
mPlaylistManager.addFavorite( current_media_id );
} else {
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "star" )
.setValue( 0 )
.build());
mPlaylistManager.removeFavorite( current_media_id );
}
} else if ( id == R.id.MenuButton ) {
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "song menu" )
.build());
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
Fragment prev = getActivity().getSupportFragmentManager().findFragmentByTag("dialog");
if ( prev != null ) {
ft.remove( prev );
}
SongMenuDialogFragment newFragment = new SongMenuDialogFragment();
newFragment.setMediaID( current_media_id );
newFragment.show( ft, "dialog" );
} else if ( id == R.id.NowPlayingRepeatButton ) {
String repeatState = (String) v.getTag( R.id.tag_repeat_state );
if ( null == repeatState || repeatState.equals( "0" ) ) {
mActivity.mBoundService.setLooping( PlaylistMediaPlayer.LOOP_ALL );
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "repeat" )
.setValue( 1 )
.build());
} else if ( repeatState.equals( "1" ) ) {
mActivity.mBoundService.setLooping( PlaylistMediaPlayer.LOOP_ONE );
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "repeat" )
.setValue( 2 )
.build());
} else {
mActivity.mBoundService.setLooping( PlaylistMediaPlayer.LOOP_NO );
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "repeat" )
.setValue( 0 )
.build());
}
} else if ( id == R.id.NowPlayingShuffleButton ) {
//ImageButton ib = ( ImageButton ) v;
String shuffleState = (String) v.getTag( R.id.tag_shuffle_state );
if ( null == shuffleState || shuffleState.equals( "0" ) ) {
mActivity.mBoundService.setShuffle( true );
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "shuffle" )
.setValue( 1 )
.build());
} else {
mActivity.mBoundService.setShuffle( false );
mTracker.send( new HitBuilders.EventBuilder()
.setCategory( "now playing button" )
.setAction( "click" )
.setLabel( "shuffle" )
.setValue( 0 )
.build());
}
}
}
};
private void recycleAlbumArt() {
BitmapDrawable bd = ( BitmapDrawable ) mCompactAlbumCover.getDrawable();
if ( null != bd && null != bd.getBitmap() ) {
bd.getBitmap().recycle();
mCompactAlbumCover.setImageBitmap( null );
}
}
public PlaybackListener PlaybackListener = new PlaybackListener() {
@Override public void onTrackChanged( String media_id ) {
if ( null == media_id ) {
if ( isShowing ) {
// Hide the fragment
//AnimationSet mSlideDown = ( AnimationSet ) AnimationUtils.loadAnimation( getActivity(), R.anim.slide_down );
//mSlideDown.setFillAfter( true );
//getView().setAnimation( );
//getView().startAnimation( mSlideDown );
isShowing = false;
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.beginTransaction()
.setCustomAnimations( R.anim.slide_up, R.anim.slide_down )
.hide( mFragmentSelf )
.commitAllowingStateLoss();
} else {
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.beginTransaction()
//.setCustomAnimations( R.anim.slide_up, R.anim.slide_down )
.hide( mFragmentSelf )
.commitAllowingStateLoss();
//getView().setVisibility( View.GONE );
}
} else if ( media_id != current_media_id ) {
current_media_id = media_id;
new StarToggleTask( mStarButton ).execute( current_media_id );
MediaQuery mSongQuery = new MediaQuery(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[] {
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media._ID
},
MediaStore.Audio.Media._ID + "=?",
new String[] {
media_id
},
null
);
MediaQuery.executeAsync( mActivity, mSongQuery, new MediaQuery.OnQueryCompletedListener() {
@Override public void onQueryCompleted( MediaQuery mQuery, Cursor mResult ) {
mResult.moveToFirst();
String title = mResult.getString( mResult.getColumnIndexOrThrow( MediaStore.Audio.Media.TITLE ) );
String artist = mResult.getString( mResult.getColumnIndexOrThrow( MediaStore.Audio.Media.ARTIST ) );
String album_id = mResult.getString( mResult.getColumnIndexOrThrow( MediaStore.Audio.Media.ALBUM_ID ) );
mResult.close();
//
// This tests if we loaded previous album art and that it wasn't null
// If the nextAlbumUri is null, it means there's no album art and
// we load from an image resource.
//
/*
if ( null == nextAlbumUri && null != lastAlbumUri) {
recycleAlbumArt();
} else if ( null != nextAlbumUri && null != lastAlbumUri && !lastAlbumUri.equals( nextAlbumUri ) ) {
recycleAlbumArt();
}
*/
// Otherwise, nextAlbumUri and lastAlbumUri are the same, we leave the ImageView alone
// and don't recycle the backing bitmap;
//lastAlbumUri = nextAlbumUri;
//albumCursor.close();
//mSongCursor.close();
MediaQuery albumQuery = new MediaQuery(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[] {
MediaStore.Audio.Albums.ALBUM_ART,
MediaStore.Audio.Albums._ID
},
MediaStore.Audio.Albums._ID + "=?",
new String[] {
album_id
},
null
);
MediaQuery.executeAsync(getActivity(), albumQuery, new MediaQuery.OnQueryCompletedListener() {
@Override public void onQueryCompleted( MediaQuery mQuery, Cursor mResult ) {
mResult.moveToFirst();
String nextAlbumUri = mResult.getString( mResult.getColumnIndexOrThrow( MediaStore.Audio.Albums.ALBUM_ART ) );
if ( null != nextAlbumUri) {
if ( !nextAlbumUri.equals( lastAlbumUri ) ) {
lastAlbumUri = nextAlbumUri;
final BitmapWorkerTask albumThumbTask = new BitmapWorkerTask( mCompactAlbumCover, getResources().getDimensionPixelSize( R.dimen.footer_height ) );
final BitmapWorkerTask albumFullTask = new BitmapWorkerTask( mFullAlbumArt );
final BitmapWorkerTask albumBackgroundTask = new BitmapWorkerTask( mAlbumArtBackground );
final AsyncDrawable asyncThumbDrawable =
new AsyncDrawable( getResources(),
null, // BitmapFactory.decodeResource( mContext.getResources(), R.drawable.no_album_art_thumb )
albumThumbTask );
final AsyncDrawable asyncFullDrawable =
new AsyncDrawable( getResources(),
null, // BitmapFactory.decodeResource( mContext.getResources(), R.drawable.no_album_art_thumb )
albumFullTask );
final AsyncDrawable asyncBackgroundDrawable =
new AsyncDrawable( getResources(),
null, // BitmapFactory.decodeResource( mContext.getResources(), R.drawable.no_album_art_thumb )
albumBackgroundTask );
mCompactAlbumCover.setImageDrawable( asyncThumbDrawable );
mFullAlbumArt.setImageDrawable( asyncFullDrawable );
mAlbumArtBackground.setImageDrawable( asyncBackgroundDrawable );
albumThumbTask.execute( nextAlbumUri );
albumFullTask.execute( nextAlbumUri );
albumBackgroundTask.execute( nextAlbumUri );
}
} else {
mCompactAlbumCover.setImageResource( R.drawable.no_album_art_thumb );
mFullAlbumArt.setImageResource( R.drawable.no_album_art_full );
}
}
});
mTitle.setText( title );
mArtist.setText( artist );
// Show the footer controls
if ( !isShowing ) {
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.beginTransaction()
.setCustomAnimations( R.anim.slide_up, R.anim.slide_down )
.show( mFragmentSelf )
.commit();
//getActivity().findViewById( R.id.FooterShadow ).setVisibility( View.VISIBLE );
isShowing = true;
}
}
});
}
}
@Override public void onPlay() {
isPlaying = true;
mExpControlsPlayPauseButton.setImageResource( R.drawable.ic_action_playback_pause_white );
mCompactPlayPauseButton.setImageResource( R.drawable.ic_action_playback_pause_white );
mTitle.setSelected( true );
mTitle.setSingleLine( true );
mTitle.setEllipsize( TextUtils.TruncateAt.MARQUEE );
mProgressFragment.startProgress();
mCompactProgressBar.start();
}
@Override public void onPause() {
isPlaying = false;
mProgressFragment.stopProgress();
mExpControlsPlayPauseButton.setImageResource( R.drawable.ic_action_playback_play_white );
if ( null != mCompactPlayPauseButton ) {
mCompactPlayPauseButton.setImageResource( R.drawable.ic_action_playback_play_white );
}
mTitle.setEllipsize( TextUtils.TruncateAt.END );
mCompactProgressBar.stop();
}
@Override public void onPlaylistDone() { }
@Override public void onLoopingChanged( int loopState ) {
if ( loopState == PlaylistMediaPlayer.LOOP_ALL ) {
mExpControlsRepeatButton.setTag( R.id.tag_repeat_state, "1" );
mExpControlsRepeatButton.setImageResource( R.drawable.ic_action_playback_repeat_orange_dark );
} else if ( loopState == PlaylistMediaPlayer.LOOP_ONE ) {
mExpControlsRepeatButton.setTag( R.id.tag_repeat_state, "2" );
mExpControlsRepeatButton.setImageResource( R.drawable.ic_action_playback_repeat_1_orange_dark );
} else {
mExpControlsRepeatButton.setTag( R.id.tag_repeat_state, "0" );
mExpControlsRepeatButton.setImageResource( R.drawable.ic_action_playback_repeat_white );
}
}
@Override public void onShuffleChanged( boolean isShuffling ) {
if ( !isShuffling ) {
mExpControlsShuffleButton.setTag( R.id.tag_shuffle_state, "0" );
mExpControlsShuffleButton.setImageResource( R.drawable.ic_action_playback_schuffle_white );
} else {
mExpControlsShuffleButton.setTag( R.id.tag_shuffle_state, "1" );
mExpControlsShuffleButton.setImageResource( R.drawable.ic_action_playback_schuffle_orange_dark );
}
}
@Override public void onDurationChanged( int position, int duration ) {
mProgressFragment.setDuration( duration );
mProgressFragment.setProgress( position );
mCompactProgressBar.setMax( duration );
mCompactProgressBar.setProgress( position );
}
};
//
// Logic to control the transitions between the states of the fragment
// And state animation
//
// There are four animations needed:
// Compact to full
// Expanded to full
// and Full to Compact
//
// Also needs to drag between these discrete states
//
private void showFull() {
mCompactPlayPauseButton.setVisibility( View.GONE );
mSongMenuButton.setVisibility( View.VISIBLE );
mStarButton.setVisibility( View.VISIBLE );
//mFullAlbumArt.setVisibility( View.VISIBLE );
mCompactAlbumCover.setVisibility( View.GONE );
//mFullPlaybackControls.setVisibility( View.VISIBLE );
//mProgressFragment.getView().setVisibility( View.VISIBLE );
mCompactAlbumArtContainer.setVisibility( View.GONE );
mCompactProgressBar.setVisibility( View.GONE );
//mFullAlbumArtContainer.setVisibility( View.VISIBLE );
}
private void showCollapsed() {
//
mCompactProgressBar.setVisibility( View.VISIBLE );
mCompactPlayPauseButton.setVisibility( View.VISIBLE );
mSongMenuButton.setVisibility( View.GONE );
mStarButton.setVisibility( View.GONE );
//mFullAlbumArt.setVisibility( View.GONE );
mCompactAlbumCover.setVisibility( View.VISIBLE );
//mFullPlaybackControls.setVisibility( View.GONE );
//mProgressFragment.getView().setVisibility( View.GONE );
mCompactAlbumArtContainer.setVisibility( View.VISIBLE );
//mFullAlbumArtContainer.setVisibility( View.GONE );
}
ContentObserver mediaStoreChanged = new ContentObserver( new Handler() ) {
@Override public void onChange( boolean selfChange ) {
getActivity().runOnUiThread( new Runnable() {
@Override public void run() {
new StarToggleTask( mStarButton ).execute( current_media_id );
}
});
super.onChange( selfChange );
}
};
}