/*
This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2009 (C) Sindre Mehus
*/
package github.madmarty.madsonic.activity;
import static github.madmarty.madsonic.domain.PlayerState.COMPLETED;
import static github.madmarty.madsonic.domain.PlayerState.IDLE;
import static github.madmarty.madsonic.domain.PlayerState.PAUSED;
import static github.madmarty.madsonic.domain.PlayerState.STOPPED;
import github.madmarty.madsonic.R;
import github.madmarty.madsonic.domain.MusicDirectory;
import github.madmarty.madsonic.domain.MusicDirectory.Entry;
import github.madmarty.madsonic.domain.PlayerState;
import github.madmarty.madsonic.domain.RepeatMode;
import github.madmarty.madsonic.service.DownloadFile;
import github.madmarty.madsonic.service.DownloadService;
import github.madmarty.madsonic.service.MusicService;
import github.madmarty.madsonic.service.MusicServiceFactory;
import github.madmarty.madsonic.util.Constants;
import github.madmarty.madsonic.util.PopupMenuHelper;
import github.madmarty.madsonic.util.ShareUtil;
import github.madmarty.madsonic.util.SilentBackgroundTask;
import github.madmarty.madsonic.util.SongView;
import github.madmarty.madsonic.util.StarUtil;
import github.madmarty.madsonic.util.Util;
import github.madmarty.madsonic.view.VisualizerView;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.view.ContextMenu;
import android.view.Display;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ViewFlipper;
import com.mobeta.android.dslv.*;
public class DownloadActivity extends SubsonicTabActivity implements OnGestureListener {
private static final int DIALOG_SAVE_PLAYLIST = 100;
private static final int PERCENTAGE_OF_SCREEN_FOR_SWIPE = 5;
private static final int COLOR_BUTTON_DARK_ENABLED = Color.rgb(255, 175, 0);
private static final int COLOR_BUTTON_HOLO_ENABLED = Color.rgb(0, 191, 255);
private static final int COLOR_BUTTON_RED_ENABLED = Color.rgb(235, 30, 30);
private static final int COLOR_BUTTON_PINK_ENABLED = Color.rgb(250, 80, 240);
private static final int COLOR_BUTTON_GREEN_ENABLED = Color.rgb(162, 255, 0);
private static final int COLOR_BUTTON_DISABLED = Color.rgb(164, 166, 158);
private ViewFlipper playlistFlipper;
private ViewFlipper buttonBarFlipper;
private TextView emptyTextView;
private TextView songTitleTextView;
private TextView albumTextView;
private TextView artistTextView;
private ImageView albumArtImageView;
private DragSortListView playlistView; //
private TextView positionTextView;
private TextView durationTextView;
private TextView statusTextView;
private static SeekBar progressBar;
private View previousButton;
private View nextButton;
private View pauseButton;
private View stopButton;
private View startButton;
private View shuffleButton;
private ImageButton repeatButton;
private Button equalizerButton;
private Button visualizerButton;
private Button jukeboxButton;
private View toggleListButton;
private ImageButton starButton;
private ScheduledExecutorService executorService;
private DownloadFile currentPlaying;
private Entry currentSong;
private long currentRevision;
private EditText playlistNameView;
private GestureDetector gestureScanner;
private int swipeDistance;
private int swipeVelocity;
private VisualizerView visualizerView;
private boolean seekInProgress = false;
private boolean nowPlaying = true;
private SongListAdapter songListAdapter;
private View playerBackground;
private View sliderBackground;
private View flipperBackground;
private View playlistBackground;
/**
* Called when the activity is first created.
*/
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.download);
Util.changeLanguage(getBaseContext());
String theme = Util.getTheme(getBaseContext());
if ("Madsonic Flawless".equals(theme) || "Madsonic Flawless Fullscreen".equals(theme)) {
mainBar = findViewById(R.id.button_bar);
mainBar.setBackgroundResource(R.drawable.menubar_button_normal_green);
}
if ("Madsonic Pink".equals(theme) || "Madsonic Pink Fullscreen".equals(theme)) {
mainBar = findViewById(R.id.button_bar);
mainBar.setBackgroundResource(R.drawable.menubar_button_normal_pink);
}
if ("Madsonic Light".equals(theme) || "Madsonic Light Fullscreen".equals(theme)) {
mainBar = findViewById(R.id.button_bar);
mainBar.setBackgroundResource(R.drawable.menubar_button_light);
}
WindowManager w = getWindowManager();
Display d = w.getDefaultDisplay();
swipeDistance = (d.getWidth() + d.getHeight()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100;
swipeVelocity = (d.getWidth() + d.getHeight()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100;
gestureScanner = new GestureDetector(this);
playlistFlipper = (ViewFlipper) findViewById(R.id.download_playlist_flipper);
buttonBarFlipper = (ViewFlipper) findViewById(R.id.download_button_bar_flipper);
emptyTextView = (TextView) findViewById(R.id.download_empty);
songTitleTextView = (TextView) findViewById(R.id.download_song_title);
albumTextView = (TextView) findViewById(R.id.download_album);
artistTextView = (TextView) findViewById(R.id.download_artist);
albumArtImageView = (ImageView) findViewById(R.id.download_album_art_image);
positionTextView = (TextView) findViewById(R.id.download_position);
durationTextView = (TextView) findViewById(R.id.download_duration);
statusTextView = (TextView) findViewById(R.id.download_status);
progressBar = (SeekBar) findViewById(R.id.download_progress_bar);
playlistView = (DragSortListView) findViewById(R.id.download_list); //
previousButton = findViewById(R.id.download_previous);
nextButton = findViewById(R.id.download_next);
pauseButton = findViewById(R.id.download_pause);
stopButton = findViewById(R.id.download_stop);
startButton = findViewById(R.id.download_start);
shuffleButton = findViewById(R.id.download_shuffle);
repeatButton = (ImageButton) findViewById(R.id.download_repeat);
equalizerButton = (Button) findViewById(R.id.download_equalizer);
visualizerButton = (Button) findViewById(R.id.download_visualizer);
jukeboxButton = (Button) findViewById(R.id.download_jukebox);
LinearLayout visualizerViewLayout = (LinearLayout) findViewById(R.id.download_visualizer_view_layout);
toggleListButton = findViewById(R.id.download_toggle_list);
playerBackground = findViewById(R.id.download_control_layout);
sliderBackground = findViewById(R.id.download_progress_bar);
flipperBackground = findViewById(R.id.flipperBackground);
playlistBackground = findViewById(R.id.playlistBackground);
// playerBackground.setBackgroundResource(0);
// sliderBackground.setBackgroundResource(0);
// flipperBackground.setBackgroundResource(0);
// playlistBackground.setBackgroundResource(0);
playerBackground.setBackgroundResource(R.drawable.menubar_button_normal_alpha_blend);
// sliderBackground.setBackgroundResource(R.drawable.menubar_button_normal_alpha);
flipperBackground.setBackgroundResource(R.drawable.menubar_button_normal_alpha);
playlistBackground.setBackgroundResource(R.drawable.menubar_button_normal_alpha);
if (getDownloadService() != null) {
switch (getDownloadService().getThemeCode()) {
case DARK: case DARK_FULL: case LIGHT: case LIGHT_FULL:
((ImageButton) startButton).setImageResource(R.drawable.media_start);
((ImageButton) stopButton).setImageResource(R.drawable.media_stop);
((ImageButton) pauseButton).setImageResource(R.drawable.media_pause);
((ImageButton) nextButton).setImageResource(R.drawable.media_forward);
((ImageButton) previousButton).setImageResource(R.drawable.media_backward);
((ImageButton) shuffleButton).setImageResource(R.drawable.media_shuffle);
((ImageButton) toggleListButton).setImageResource(R.drawable.media_toggle_list);
break;
case HOLO: case HOLO_FULL:
((ImageButton) startButton).setImageResource(R.drawable.media_start_holo);
((ImageButton) stopButton).setImageResource(R.drawable.media_stop_holo);
((ImageButton) pauseButton).setImageResource(R.drawable.media_pause_holo);
((ImageButton) nextButton).setImageResource(R.drawable.media_forward_holo);
((ImageButton) previousButton).setImageResource(R.drawable.media_backward_holo);
((ImageButton) shuffleButton).setImageResource(R.drawable.media_shuffle_holo);
((ImageButton) toggleListButton).setImageResource(R.drawable.media_toggle_list_holo);
break;
case RED: case RED_FULL:
((ImageButton) startButton).setImageResource(R.drawable.media_start_red);
((ImageButton) stopButton).setImageResource(R.drawable.media_stop_red);
((ImageButton) pauseButton).setImageResource(R.drawable.media_pause_red);
((ImageButton) nextButton).setImageResource(R.drawable.media_forward_red);
((ImageButton) previousButton).setImageResource(R.drawable.media_backward_red);
((ImageButton) shuffleButton).setImageResource(R.drawable.media_shuffle_red);
((ImageButton) toggleListButton).setImageResource(R.drawable.media_toggle_list_red);
break;
case PINK: case PINK_FULL:
((ImageButton) startButton).setImageResource(R.drawable.media_start_pink);
((ImageButton) stopButton).setImageResource(R.drawable.media_stop_pink);
((ImageButton) pauseButton).setImageResource(R.drawable.media_pause_pink);
((ImageButton) nextButton).setImageResource(R.drawable.media_forward_pink);
((ImageButton) previousButton).setImageResource(R.drawable.media_backward_pink);
((ImageButton) shuffleButton).setImageResource(R.drawable.media_shuffle_pink);
((ImageButton) toggleListButton).setImageResource(R.drawable.media_toggle_list_pink);
break;
case GREEN: case GREEN_FULL:
((ImageButton) startButton).setImageResource(R.drawable.media_start_green);
((ImageButton) stopButton).setImageResource(R.drawable.media_stop_green);
((ImageButton) pauseButton).setImageResource(R.drawable.media_pause_green);
((ImageButton) nextButton).setImageResource(R.drawable.media_forward_green);
((ImageButton) previousButton).setImageResource(R.drawable.media_backward_green);
((ImageButton) shuffleButton).setImageResource(R.drawable.media_shuffle_green);
((ImageButton) toggleListButton).setImageResource(R.drawable.media_toggle_list_green);
break;
default:
((ImageButton) startButton).setImageResource(R.drawable.media_start);
((ImageButton) stopButton).setImageResource(R.drawable.media_stop);
((ImageButton) pauseButton).setImageResource(R.drawable.media_pause);
((ImageButton) nextButton).setImageResource(R.drawable.media_forward);
((ImageButton) previousButton).setImageResource(R.drawable.media_backward);
((ImageButton) shuffleButton).setImageResource(R.drawable.media_shuffle);
((ImageButton) toggleListButton).setImageResource(R.drawable.media_toggle_list);
break;
}
}
starButton = (ImageButton) findViewById(R.id.download_star);
starButton.setVisibility(Util.isOffline(this) ? View.GONE : View.VISIBLE);
starButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
DownloadFile currentDownload = getDownloadService().getCurrentPlaying();
if (currentDownload != null) {
MusicDirectory.Entry currentSong = currentDownload.getSong();
toggleStarredInBackground(currentSong, starButton);
}
}
});
setTitle("Media Player");
// Button 1: shuffle
ImageButton shuffleButton = (ImageButton) findViewById(R.id.action_button_0);
shuffleButton.setVisibility(View.VISIBLE);
shuffleButton.setImageResource(R.drawable.action_shuffle);
shuffleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getDownloadService().shuffle();
Util.toast(DownloadActivity.this, R.string.download_menu_shuffle_notification);
}
});
// Button 1: toggle Cover/Playlist
ImageButton playlistButton = (ImageButton)findViewById(R.id.action_button_1);
playlistButton.setImageResource(R.drawable.media_toggle_list_normal);
playlistButton.setVisibility(View.VISIBLE);
playlistButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toggleFullscreenAlbumArt();
}
});
// Button 2: home
ImageButton searchButton = (ImageButton)findViewById(R.id.action_button_2);
searchButton.setImageResource(R.drawable.ic_menu_home);
searchButton.setVisibility(View.VISIBLE);
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(DownloadActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Util.startActivityWithoutTransition(DownloadActivity.this, intent);
}
});
// Button 3: Settings
final ImageButton actionSettingsButton = (ImageButton)findViewById(R.id.action_button_3);
actionSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new PopupMenuHelper().showMenu(DownloadActivity.this, actionSettingsButton, R.menu.nowplaying);
}
});
View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent me) {
return gestureScanner.onTouchEvent(me);
}
};
previousButton.setOnTouchListener(touchListener);
nextButton.setOnTouchListener(touchListener);
pauseButton.setOnTouchListener(touchListener);
stopButton.setOnTouchListener(touchListener);
startButton.setOnTouchListener(touchListener);
equalizerButton.setOnTouchListener(touchListener);
visualizerButton.setOnTouchListener(touchListener);
jukeboxButton.setOnTouchListener(touchListener);
buttonBarFlipper.setOnTouchListener(touchListener);
emptyTextView.setOnTouchListener(touchListener);
albumArtImageView.setOnTouchListener(touchListener);
albumArtImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toggleFullscreenAlbumArt();
}
});
previousButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
warnIfNetworkOrStorageUnavailable();
getDownloadService().previous();
onCurrentChanged();
onProgressChanged();
}
});
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
warnIfNetworkOrStorageUnavailable();
if (getDownloadService().getCurrentPlayingIndex() < getDownloadService().size() - 1) {
getDownloadService().next();
onCurrentChanged();
onProgressChanged();
}
}
});
pauseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getDownloadService().pause();
onCurrentChanged();
onProgressChanged();
}
});
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getDownloadService().reset();
onCurrentChanged();
onProgressChanged();
}
});
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
warnIfNetworkOrStorageUnavailable();
start();
onCurrentChanged();
onProgressChanged();
}
});
shuffleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getDownloadService().shuffle();
Util.toast(DownloadActivity.this, R.string.download_menu_shuffle_notification);
}
});
repeatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
RepeatMode repeatMode = getDownloadService().getRepeatMode().next();
getDownloadService().setRepeatMode(repeatMode);
onDownloadListChanged();
switch (repeatMode) {
case OFF:
Util.toast(DownloadActivity.this, R.string.download_repeat_off);
break;
case ALL:
Util.toast(DownloadActivity.this, R.string.download_repeat_all);
break;
case SINGLE:
Util.toast(DownloadActivity.this, R.string.download_repeat_single);
break;
default:
break;
}
}
});
equalizerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DownloadService downloadService = getDownloadService();
if(downloadService != null && downloadService.getEqualizerController() != null
&& downloadService.getEqualizerController().getEqualizer() != null) {
startActivity(new Intent(DownloadActivity.this, EqualizerActivity.class));
} else {
Util.toast(DownloadActivity.this, "Failed to start equalizer. Try restarting.");
}
}
});
visualizerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean active = !visualizerView.isActive();
visualizerView.setActive(active);
boolean isActive = visualizerView.isActive();
getDownloadService().setShowVisualization(isActive);
updateButtons();
if(active == isActive) {
Util.toast(DownloadActivity.this, active ? R.string.download_visualizer_on : R.string.download_visualizer_off);
} else {
Util.toast(DownloadActivity.this, "Failed to start visualizer. Try restarting.");
}
}
});
jukeboxButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean jukeboxEnabled = !getDownloadService().isJukeboxEnabled();
getDownloadService().setJukeboxEnabled(jukeboxEnabled);
updateButtons();
Util.toast(DownloadActivity.this, jukeboxEnabled ? R.string.download_jukebox_on : R.string.download_jukebox_off, false);
}
});
toggleListButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toggleFullscreenAlbumArt();
}
});
progressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, final int position, boolean fromUser) {
if (fromUser) {
Util.toast(DownloadActivity.this, Util.formatDuration(position / 1000), true);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Notification that the user has started a touch gesture. Clients may want to use this to disable advancing the seekbar.
seekInProgress = true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Notification that the user has finished a touch gesture. Clients may want to use this to re-enable advancing the seekbar.
seekInProgress = false;
int position = seekBar.getProgress();
Util.toast(DownloadActivity.this, Util.formatDuration(position / 1000), true);
getDownloadService().seekTo(position);
}
});
playlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
warnIfNetworkOrStorageUnavailable();
getDownloadService().play(position);
onCurrentChanged();
onProgressChanged();
}
});
playlistView.setDropListener(new DragSortListView.DropListener() {
@Override
public void drop(int from, int to) {
getDownloadService().swap(nowPlaying, from, to);
onDownloadListChanged();
}
});
playlistView.setRemoveListener(new DragSortListView.RemoveListener() {
@Override
public void remove(int which) {
getDownloadService().remove(which);
onDownloadListChanged();
}
});
registerForContextMenu(playlistView);
DownloadService downloadService = getDownloadService();
if (downloadService != null && getIntent().getBooleanExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, false)) {
warnIfNetworkOrStorageUnavailable();
downloadService.setShufflePlayEnabled(true);
}
boolean visualizerAvailable = downloadService != null && downloadService.getVisualizerController() != null;
boolean equalizerAvailable = downloadService != null && downloadService.getEqualizerController() != null;
if (!equalizerAvailable) {
equalizerButton.setVisibility(View.GONE);
}
if (!visualizerAvailable) {
visualizerButton.setVisibility(View.GONE);
} else {
visualizerView = new VisualizerView(this);
visualizerViewLayout.addView(visualizerView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
visualizerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
visualizerView.setActive(!visualizerView.isActive());
getDownloadService().setShowVisualization(visualizerView.isActive());
updateButtons();
return true;
}
});
}
// TODO: Extract to utility method and cache.
Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/Storopia.ttf");
equalizerButton.setTypeface(typeface);
visualizerButton.setTypeface(typeface);
jukeboxButton.setTypeface(typeface);
}
@Override
protected void onResume() {
super.onResume();
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
update();
}
});
}
};
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(runnable, 0L, 1000L, TimeUnit.MILLISECONDS);
DownloadService downloadService = getDownloadService();
if (downloadService == null || downloadService.getCurrentPlaying() == null) {
playlistFlipper.setDisplayedChild(1);
buttonBarFlipper.setDisplayedChild(1);
}
onDownloadListChanged();
onCurrentChanged();
onProgressChanged();
scrollToCurrent();
if (downloadService != null && downloadService.getKeepScreenOn()) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
if (visualizerView != null) {
visualizerView.setActive(downloadService != null && downloadService.getShowVisualization());
}
updateButtons();
}
private void updateButtons() {
boolean eqEnabled = getDownloadService() != null && getDownloadService().getEqualizerController() != null &&
getDownloadService().getEqualizerController().isEnabled();
int COLOR_BUTTON_ENABLED = COLOR_BUTTON_DARK_ENABLED ;
if (getDownloadService() != null) {
switch (getDownloadService().getThemeCode()) {
case DARK: case DARK_FULL: case LIGHT: case LIGHT_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_DARK_ENABLED;
break;
case HOLO: case HOLO_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_HOLO_ENABLED;
break;
case RED: case RED_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_RED_ENABLED;
break;
case PINK: case PINK_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_PINK_ENABLED;
break;
case GREEN: case GREEN_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_GREEN_ENABLED;
break;
case BLACK: case BLACK_FULL:
}
}
equalizerButton.setTextColor(eqEnabled ? COLOR_BUTTON_ENABLED : COLOR_BUTTON_DISABLED);
if (visualizerView != null) {
visualizerButton.setTextColor(visualizerView.isActive() ? COLOR_BUTTON_ENABLED : COLOR_BUTTON_DISABLED);
}
boolean jukeboxEnabled = getDownloadService() != null && getDownloadService().isJukeboxEnabled();
jukeboxButton.setTextColor(jukeboxEnabled ? COLOR_BUTTON_ENABLED : COLOR_BUTTON_DISABLED);
}
// Scroll to current playing/downloading.
private void scrollToCurrent() {
if (getDownloadService() == null || songListAdapter == null) {
return;
}
for (int i = 0; i < songListAdapter.getCount(); i++) {
if (currentPlaying == playlistView.getItemAtPosition(i)) {
playlistView.setSelectionFromTop(i, 40);
return;
}
}
DownloadFile currentDownloading = getDownloadService().getCurrentDownloading();
for (int i = 0; i < songListAdapter.getCount(); i++) {
if (currentDownloading == playlistView.getItemAtPosition(i)) {
playlistView.setSelectionFromTop(i, 40);
return;
}
}
}
@Override
protected void onPause() {
super.onPause();
executorService.shutdown();
if (visualizerView != null) {
visualizerView.setActive(false);
}
}
@SuppressWarnings("deprecation")
@Override
protected Dialog onCreateDialog(int id) {
if (id == DIALOG_SAVE_PLAYLIST) {
AlertDialog.Builder builder;
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
final View layout = inflater.inflate(R.layout.save_playlist, (ViewGroup) findViewById(R.id.save_playlist_root));
playlistNameView = (EditText) layout.findViewById(R.id.save_playlist_name);
builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.download_playlist_title);
builder.setMessage(R.string.download_playlist_name);
builder.setPositiveButton(R.string.common_save, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
savePlaylistInBackground(String.valueOf(playlistNameView.getText()));
}
});
builder.setNegativeButton(R.string.common_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.setView(layout);
builder.setCancelable(true);
return builder.create();
} else {
return super.onCreateDialog(id);
}
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
if (id == DIALOG_SAVE_PLAYLIST) {
String playlistName = getDownloadService().getSuggestedPlaylistName();
if (playlistName != null) {
playlistNameView.setText(playlistName);
} else {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
playlistNameView.setText(dateFormat.format(new Date()));
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.nowplaying, menu);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem savePlaylist = menu.findItem(R.id.menu_save_playlist);
boolean savePlaylistEnabled = !Util.isOffline(this);
savePlaylist.setEnabled(savePlaylistEnabled);
savePlaylist.setVisible(savePlaylistEnabled);
MenuItem screenOption = menu.findItem(R.id.menu_screen_on_off);
if (getDownloadService().getKeepScreenOn()) {
screenOption.setTitle(R.string.download_menu_screen_off);
} else {
screenOption.setTitle(R.string.download_menu_screen_on);
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
if (view == playlistView) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
DownloadFile downloadFile = (DownloadFile) playlistView.getItemAtPosition(info.position);
boolean offline = Util.isOffline(this);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.nowplaying_context, menu);
// menu.findItem(R.id.song_menu_pin).setVisible(!offline && !downloadFile.isSaved());
// menu.findItem(R.id.song_menu_unpin).setVisible(!offline && downloadFile.isSaved());
menu.findItem(R.id.song_menu_star).setVisible(!offline && !downloadFile.getSong().isStarred());
menu.findItem(R.id.song_menu_unstar).setVisible(!offline && downloadFile.getSong().isStarred());
menu.findItem(R.id.song_menu_share).setVisible(!offline);
menu.findItem(R.id.menu_remove).setVisible(true);
menu.findItem(R.id.menu_show_album).setVisible(downloadFile.getSong().getParent() != null);
menu.findItem(R.id.menu_lyrics).setVisible(!Util.isOffline(this));
}
}
@Override
public boolean onContextItemSelected(MenuItem menuItem) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo();
DownloadFile downloadFile = (DownloadFile) playlistView.getItemAtPosition(info.position);
return menuItemSelected(menuItem.getItemId(), downloadFile) || super.onContextItemSelected(menuItem);
}
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
return menuItemSelected(menuItem.getItemId(), null) || super.onOptionsItemSelected(menuItem);
}
@SuppressWarnings("deprecation")
private boolean menuItemSelected(int menuItemId, DownloadFile song) {
switch (menuItemId) {
case R.id.song_menu_pin:
getDownloadService().pin(Arrays.asList(song.getSong()));
return true;
case R.id.song_menu_unpin:
getDownloadService().unpin(Arrays.asList(song.getSong()));
return true;
case R.id.song_menu_star:
StarUtil.starInBackground(this, song.getSong(), true);
starButton.setImageResource(android.R.drawable.btn_star_big_on );
onDownloadListChanged();
onCurrentChanged();
starButton.invalidate();
playlistView.invalidate();
return true;
case R.id.song_menu_unstar:
StarUtil.starInBackground(this, song.getSong(), false);
starButton.setImageResource(android.R.drawable.btn_star_big_off);
onDownloadListChanged();
onCurrentChanged();
starButton.invalidate();
playlistView.invalidate();
return false;
case R.id.song_menu_share:
ShareUtil.shareInBackground(this, song.getSong());
return true;
case R.id.menu_remove:
getDownloadService().remove(song);
onCurrentChanged();
return true;
case R.id.menu_show_album:
Intent intent = new Intent(this, SelectAlbumActivity.class);
intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, song.getSong().getParent());
intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, song.getSong().getAlbum());
Util.startActivityWithoutTransition(this, intent);
return true;
case R.id.menu_lyrics:
intent = new Intent(this, LyricsActivity.class);
intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, song.getSong().getId());
intent.putExtra(Constants.INTENT_EXTRA_NAME_ARTIST, song.getSong().getArtist());
intent.putExtra(Constants.INTENT_EXTRA_NAME_TITLE, song.getSong().getTitle());
Util.startActivityWithoutTransition(this, intent);
return true;
case R.id.menu_delete:
getDownloadService().remove(song);
List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>(1);
songs.add(song.getSong());
getDownloadService().delete(songs);
onDownloadListChanged();
return true;
case R.id.menu_remove_all:
getDownloadService().setShufflePlayEnabled(false);
getDownloadService().clear();
onDownloadListChanged();
return true;
case R.id.menu_screen_on_off:
if (getDownloadService().getKeepScreenOn()) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getDownloadService().setKeepScreenOn(false);
} else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getDownloadService().setKeepScreenOn(true);
Util.toast(this, R.string.download_screen_on);
}
return true;
case R.id.menu_shuffle:
getDownloadService().shuffle();
Util.toast(this, R.string.download_menu_shuffle_notification);
return true;
case R.id.menu_save_playlist:
showDialog(DIALOG_SAVE_PLAYLIST);
return true;
case R.id.menu_exit:
Intent intent1 = new Intent(this, MainActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent1.putExtra(Constants.INTENT_EXTRA_NAME_EXIT, true);
Util.startActivityWithoutTransition(this, intent1);
return true;
case R.id.menu_add_playlist:
songs = new ArrayList<MusicDirectory.Entry>(1);
songs.add(song.getSong());
addToPlaylist(songs);
return true;
case R.id.menu_settings:
startActivity(new Intent(this, SettingsActivity.class));
return true;
default:
return false;
}
}
private void update() {
if (getDownloadService() == null) {
return;
}
if (currentRevision != getDownloadService().getDownloadListUpdateRevision()) {
onDownloadListChanged();
}
if (currentPlaying != getDownloadService().getCurrentPlaying()) {
onCurrentChanged();
}
onProgressChanged();
}
private void savePlaylistInBackground(final String playlistName) {
Util.toast(DownloadActivity.this, getResources().getString(R.string.download_playlist_saving, playlistName));
getDownloadService().setSuggestedPlaylistName(playlistName, null);
new SilentBackgroundTask<Void>(this) {
@Override
protected Void doInBackground() throws Throwable {
List<MusicDirectory.Entry> entries = new LinkedList<MusicDirectory.Entry>();
for (DownloadFile downloadFile : getDownloadService().getDownloads()) {
entries.add(downloadFile.getSong());
}
MusicService musicService = MusicServiceFactory.getMusicService(DownloadActivity.this);
musicService.createPlaylist(null, playlistName, entries, DownloadActivity.this, null);
return null;
}
@Override
protected void done(Void result) {
Util.toast(DownloadActivity.this, R.string.download_playlist_done);
}
@Override
protected void error(Throwable error) {
String msg = getResources().getString(R.string.download_playlist_error) + " " + getErrorMessage(error);
Util.toast(DownloadActivity.this, msg);
}
}.execute();
}
private void toggleFullscreenAlbumArt() {
scrollToCurrent();
if (playlistFlipper.getDisplayedChild() == 1) {
playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_down_in));
playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_down_out));
playlistFlipper.setDisplayedChild(0);
buttonBarFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_down_in));
buttonBarFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_down_out));
buttonBarFlipper.setDisplayedChild(0);
} else {
playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_in));
playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_out));
playlistFlipper.setDisplayedChild(1);
buttonBarFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_in));
buttonBarFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_out));
buttonBarFlipper.setDisplayedChild(1);
}
}
private void start() {
DownloadService service = getDownloadService();
PlayerState state = service.getPlayerState();
if (state == PAUSED || state == COMPLETED || state == STOPPED) {
service.start();
} else if (state == STOPPED || state == IDLE) {
warnIfNetworkOrStorageUnavailable();
int current = service.getCurrentPlayingIndex();
// TODO: Use play() method.
if (current == -1) {
service.play(0);
} else {
service.play(current);
}
}
}
private void onDownloadListChanged() {
onDownloadListChanged(false);
}
private void onDownloadListChanged(boolean refresh) {
DownloadService downloadService = getDownloadService();
if (downloadService == null) {
return;
}
List<DownloadFile> list;
if(nowPlaying) {
list = downloadService.getSongs();
}
else {
list = downloadService.getBackgroundDownloads();
}
//### List<DownloadFile> list = downloadService.getDownloads();
if(songListAdapter == null || refresh) {
playlistView.setAdapter(songListAdapter = new SongListAdapter(list));
} else {
songListAdapter.notifyDataSetChanged();
}
emptyTextView.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE);
currentRevision = downloadService.getDownloadListUpdateRevision();
int MediaRepeatAll = R.drawable.media_repeat_all;
int MediaRepeatSingle = R.drawable.media_repeat_single;
if (getDownloadService() != null) {
switch (getDownloadService().getThemeCode()) {
case DARK: case DARK_FULL: case LIGHT: case LIGHT_FULL:
break;
case HOLO: case HOLO_FULL:
MediaRepeatAll = R.drawable.media_repeat_all_holo;
MediaRepeatSingle = R.drawable.media_repeat_single_holo;
break;
case RED: case RED_FULL:
MediaRepeatAll = R.drawable.media_repeat_all_red;
MediaRepeatSingle = R.drawable.media_repeat_single_red;
break;
case PINK: case PINK_FULL:
MediaRepeatAll = R.drawable.media_repeat_all_pink;
MediaRepeatSingle = R.drawable.media_repeat_single_pink;
break;
case GREEN: case GREEN_FULL:
MediaRepeatAll = R.drawable.media_repeat_all_green;
MediaRepeatSingle = R.drawable.media_repeat_single_green;
break;
case BLACK: case BLACK_FULL:
}
}
switch (downloadService.getRepeatMode()) {
case OFF:
repeatButton.setImageResource(R.drawable.media_repeat_off);
break;
case ALL:
repeatButton.setImageResource(MediaRepeatAll);
break;
case SINGLE:
repeatButton.setImageResource(MediaRepeatSingle);
break;
default:
break;
}
}
private void onCurrentChanged() {
if (getDownloadService() == null) {
return;
}
currentPlaying = getDownloadService().getCurrentPlaying();
if (currentPlaying != null) {
MusicDirectory.Entry song = currentPlaying.getSong();
songTitleTextView.setText(song.getTitle());
albumTextView.setText(song.getAlbum());
artistTextView.setText(song.getArtist());
getImageLoader().loadImage(albumArtImageView, song, true, false, true);
starButton.setImageResource(song.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
} else {
songTitleTextView.setText(null);
albumTextView.setText(null);
artistTextView.setText(null);
getImageLoader().loadImage(albumArtImageView, null, true, false, true);
starButton.setImageResource(android.R.drawable.btn_star_big_off);
}
}
private void onProgressChanged() {
if (getDownloadService() == null) {
return;
}
if (currentPlaying != null) {
int millisPlayed = Math.max(0, getDownloadService().getPlayerPosition());
Integer duration = getDownloadService().getPlayerDuration();
int millisTotal = duration == null ? 0 : duration;
positionTextView.setText(Util.formatDuration(millisPlayed / 1000));
durationTextView.setText(Util.formatDuration(millisTotal / 1000));
progressBar.setMax(millisTotal == 0 ? 100 : millisTotal); // Work-around for apparent bug.
if (!seekInProgress) {
progressBar.setProgress(millisPlayed);
}
progressBar.setEnabled(currentPlaying.isWorkDone() || getDownloadService().isJukeboxEnabled());
} else {
positionTextView.setText(R.string.util_zero_time);
durationTextView.setText(R.string.util_no_time);
progressBar.setProgress(0);
// progressBar.setMax(0);
progressBar.setEnabled(false);
}
PlayerState playerState = getDownloadService().getPlayerState();
switch (playerState) {
case DOWNLOADING:
long bytes = currentPlaying.getPartialFile().length();
statusTextView.setText(getResources().getString(R.string.download_playerstate_downloading, Util.formatLocalizedBytes(bytes, this)));
break;
case PREPARING:
statusTextView.setText(R.string.download_playerstate_buffering);
break;
case STARTED:
if (getDownloadService().isJukeboxEnabled()) {
statusTextView.setText(R.string.download_playerstate_playing_remote);
} else if (getDownloadService().isShufflePlayEnabled()) {
statusTextView.setText(R.string.download_playerstate_playing_shuffle);
} else {
statusTextView.setText(null);
}
break;
default:
statusTextView.setText(null);
break;
}
switch (playerState) {
case STARTED:
pauseButton.setVisibility(View.VISIBLE);
stopButton.setVisibility(View.GONE);
startButton.setVisibility(View.GONE);
break;
case DOWNLOADING:
case PREPARING:
pauseButton.setVisibility(View.GONE);
stopButton.setVisibility(View.VISIBLE);
startButton.setVisibility(View.GONE);
break;
default:
pauseButton.setVisibility(View.GONE);
stopButton.setVisibility(View.GONE);
startButton.setVisibility(View.VISIBLE);
break;
}
int COLOR_BUTTON_ENABLED = COLOR_BUTTON_DARK_ENABLED ;
if (getDownloadService() != null) {
switch (getDownloadService().getThemeCode()) {
case DARK: case DARK_FULL: case LIGHT: case LIGHT_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_DARK_ENABLED;
break;
case HOLO: case HOLO_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_HOLO_ENABLED;
break;
case RED: case RED_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_RED_ENABLED;
break;
case PINK: case PINK_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_PINK_ENABLED;
break;
case GREEN: case GREEN_FULL:
COLOR_BUTTON_ENABLED = COLOR_BUTTON_GREEN_ENABLED;
break;
case BLACK: case BLACK_FULL:
}
}
jukeboxButton.setTextColor(getDownloadService().isJukeboxEnabled() ? COLOR_BUTTON_ENABLED : COLOR_BUTTON_DISABLED);
}
private class SongListAdapter extends ArrayAdapter<DownloadFile> {
public SongListAdapter(List<DownloadFile> entries) {
super(DownloadActivity.this, android.R.layout.simple_list_item_1, entries);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
SongView view;
if (convertView != null && convertView instanceof SongView) {
view = (SongView) convertView;
} else {
view = new SongView(DownloadActivity.this);
}
DownloadFile downloadFile = getItem(position);
view.setSong(downloadFile.getSong(), false);
return view;
}
}
@Override
public boolean onTouchEvent(MotionEvent me) {
return gestureScanner.onTouchEvent(me);
}
@Override
public boolean onDown(MotionEvent me) {
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
DownloadService downloadService = getDownloadService();
if (downloadService == null) {
return false;
}
// Right to Left swipe
if (e1.getX() - e2.getX() > swipeDistance && Math.abs(velocityX) > swipeVelocity) {
warnIfNetworkOrStorageUnavailable();
if (downloadService.getCurrentPlayingIndex() < downloadService.size() - 1) {
downloadService.next();
onCurrentChanged();
onProgressChanged();
}
return true;
}
// Left to Right swipe
if (e2.getX() - e1.getX() > swipeDistance && Math.abs(velocityX) > swipeVelocity) {
warnIfNetworkOrStorageUnavailable();
downloadService.previous();
onCurrentChanged();
onProgressChanged();
return true;
}
// Top to Bottom swipe
if (e2.getY() - e1.getY() > swipeDistance && Math.abs(velocityY) > swipeVelocity) {
warnIfNetworkOrStorageUnavailable();
downloadService.seekTo(downloadService.getPlayerPosition() + 30000);
onProgressChanged();
return true;
}
// Bottom to Top swipe
if (e1.getY() - e2.getY() > swipeDistance && Math.abs(velocityY) > swipeVelocity) {
warnIfNetworkOrStorageUnavailable();
downloadService.seekTo(downloadService.getPlayerPosition() - 8000);
onProgressChanged();
return true;
}
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
public static SeekBar getProgressBar() {
return progressBar;
}
}