diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index db835c9430..a63673e627 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -3,8 +3,9 @@
diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java
index 7fab1c89b4..635383b24e 100644
--- a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java
+++ b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java
@@ -113,44 +113,36 @@ public MPD(final String server, final int port, final String password)
connect(server, port, password);
}
- private static MPDCommand getAlbumDetailsCommand(final Album album) {
+ private static String[] getAlbumArtistPair(final Album album) {
final Artist artist = album.getArtist();
- String artistCommand = null;
- String artistName = null;
-
- if (artist != null) {
- artistName = artist.getName();
+ final String[] artistPair;
+ if (artist == null) {
+ artistPair = new String[]{null, null};
+ } else {
if (album.hasAlbumArtist()) {
- artistCommand = MPDCommand.MPD_TAG_ALBUM_ARTIST;
+ artistPair = new String[]{MPDCommand.MPD_TAG_ALBUM_ARTIST, artist.getName()};
} else {
- artistCommand = MPDCommand.MPD_FIND_ARTIST;
+ artistPair = new String[]{MPDCommand.MPD_TAG_ARTIST, artist.getName()};
}
}
+ return artistPair;
+ }
+
+ private static MPDCommand getAlbumDetailsCommand(final Album album) {
+ final String[] artistPair = getAlbumArtistPair(album);
+
return new MPDCommand(MPDCommand.MPD_CMD_COUNT,
MPDCommand.MPD_TAG_ALBUM, album.getName(),
- artistCommand, artistName);
+ artistPair[0], artistPair[1]);
}
private static MPDCommand getSongsCommand(final Album album) {
- final String albumName = album.getName();
- final Artist artist = album.getArtist();
- String artistName = null;
- String artistCommand = null;
+ final String[] artistPair = getAlbumArtistPair(album);
- if (artist != null) {
- artistName = artist.getName();
-
- if (album.hasAlbumArtist()) {
- artistCommand = MPDCommand.MPD_TAG_ALBUM_ARTIST;
- } else {
- artistCommand = MPDCommand.MPD_TAG_ARTIST;
- }
- }
-
- return new MPDCommand(MPDCommand.MPD_CMD_FIND, MPDCommand.MPD_TAG_ALBUM, albumName,
- artistCommand, artistName);
+ return new MPDCommand(MPDCommand.MPD_CMD_FIND, MPDCommand.MPD_TAG_ALBUM, album.getName(),
+ artistPair[0], artistPair[1]);
}
/*
@@ -213,8 +205,20 @@ public void add(final Album album) throws IOException, MPDException {
*/
public void add(final Album album, final boolean replace, final boolean play)
throws IOException, MPDException {
- final List songs = getSongs(album);
- final CommandQueue commandQueue = MPDPlaylist.addAllCommand(songs);
+ final CommandQueue commandQueue;
+
+ if (isCommandAvailable(MPDCommand.MPD_CMD_FIND_ADD)) {
+ final String[] artistPair = getAlbumArtistPair(album);
+
+ commandQueue = new CommandQueue();
+
+ commandQueue
+ .add(MPDCommand.MPD_CMD_FIND_ADD, MPDCommand.MPD_TAG_ALBUM, album.getName(),
+ artistPair[0], artistPair[1]);
+ } else {
+ final List songs = getSongs(album);
+ commandQueue = MPDPlaylist.addAllCommand(songs);
+ }
add(commandQueue, replace, play);
}
@@ -241,8 +245,17 @@ public void add(final Artist artist) throws IOException, MPDException {
*/
public void add(final Artist artist, final boolean replace, final boolean play)
throws IOException, MPDException {
- final List songs = getSongs(artist);
- final CommandQueue commandQueue = MPDPlaylist.addAllCommand(songs);
+ final CommandQueue commandQueue;
+
+ if (isCommandAvailable(MPDCommand.MPD_CMD_FIND_ADD)) {
+ commandQueue = new CommandQueue();
+
+ commandQueue
+ .add(MPDCommand.MPD_CMD_FIND_ADD, MPDCommand.MPD_TAG_ARTIST, artist.getName());
+ } else {
+ final List songs = getSongs(artist);
+ commandQueue = MPDPlaylist.addAllCommand(songs);
+ }
add(commandQueue, replace, play);
}
@@ -261,7 +274,11 @@ public void add(final FilesystemTreeEntry music, final boolean replace, final bo
throws IOException, MPDException {
final CommandQueue commandQueue = new CommandQueue();
- commandQueue.add(MPDPlaylist.addCommand(music.getFullPath()));
+ if (music instanceof PlaylistFile) {
+ commandQueue.add(MPDPlaylist.loadCommand(music.getFullPath()));
+ } else {
+ commandQueue.add(MPDPlaylist.addCommand(music.getFullPath()));
+ }
add(commandQueue, replace, play);
}
@@ -277,6 +294,24 @@ public void add(final FilesystemTreeEntry music) throws IOException, MPDExceptio
add(music, false, false);
}
+ public void add(final Genre genre, final boolean replace, final boolean play)
+ throws IOException, MPDException {
+ final CommandQueue commandQueue;
+
+ if (isCommandAvailable(MPDCommand.MPD_CMD_FIND_ADD)) {
+ commandQueue = new CommandQueue();
+
+ commandQueue
+ .add(MPDCommand.MPD_CMD_FIND_ADD, MPDCommand.MPD_TAG_GENRE, genre.getName());
+ } else {
+ final Collection music = find(MPDCommand.MPD_TAG_GENRE, genre.getName());
+
+ commandQueue = MPDPlaylist.addAllCommand(music);
+ }
+
+ add(commandQueue, replace, play);
+ }
+
/**
* Adds songs to the queue. Optionally, clears the queue prior to the addition. Optionally,
* play the added songs afterward.
@@ -394,12 +429,24 @@ public void addStream(final String stream, final boolean replace, final boolean
public void addToPlaylist(final String playlistName, final Album album)
throws IOException, MPDException {
- addToPlaylist(playlistName, new ArrayList<>(getSongs(album)));
+ if (mIdleConnection.isCommandAvailable(MPDCommand.MPD_CMD_SEARCH_ADD_PLAYLIST)) {
+ final String[] artistPair = getAlbumArtistPair(album);
+
+ mConnection.sendCommand(MPDCommand.MPD_CMD_SEARCH_ADD_PLAYLIST, playlistName,
+ MPDCommand.MPD_SEARCH_ALBUM, album.getName(), artistPair[0], artistPair[1]);
+ } else {
+ addToPlaylist(playlistName, new ArrayList<>(getSongs(album)));
+ }
}
public void addToPlaylist(final String playlistName, final Artist artist)
throws IOException, MPDException {
- addToPlaylist(playlistName, new ArrayList<>(getSongs(artist)));
+ if (mIdleConnection.isCommandAvailable(MPDCommand.MPD_CMD_SEARCH_ADD_PLAYLIST)) {
+ mConnection.sendCommand(MPDCommand.MPD_CMD_SEARCH_ADD_PLAYLIST, playlistName,
+ MPDCommand.MPD_SEARCH_ARTIST, artist.getName());
+ } else {
+ addToPlaylist(playlistName, new ArrayList<>(getSongs(artist)));
+ }
}
public void addToPlaylist(final String playlistName, final Collection musicCollection)
@@ -421,6 +468,18 @@ public void addToPlaylist(final String playlistName, final FilesystemTreeEntry e
entry.getFullPath());
}
+ public void addToPlaylist(final String playlistName, final Genre genre)
+ throws IOException, MPDException {
+ if (mIdleConnection.isCommandAvailable(MPDCommand.MPD_CMD_SEARCH_ADD_PLAYLIST)) {
+ mConnection.sendCommand(MPDCommand.MPD_CMD_SEARCH_ADD_PLAYLIST, playlistName,
+ MPDCommand.MPD_SEARCH_GENRE, genre.getName());
+ } else {
+ final Collection music = find(MPDCommand.MPD_TAG_GENRE, genre.getName());
+
+ addToPlaylist(playlistName, music);
+ }
+ }
+
public void addToPlaylist(final String playlistName, final Music music)
throws IOException, MPDException {
final Collection songs = new ArrayList<>(1);
@@ -1547,6 +1606,26 @@ public void refreshDirectory(final Directory directory) throws IOException, MPDE
directory.refresh(mConnection);
}
+ /**
+ * Removes a list of tracks from a playlist file, by position.
+ *
+ * @param playlistName The playlist file to remove tracks from.
+ * @param positions The positions of the tracks to remove from the playlist file.
+ * @throws IOException Thrown upon a communication error with the server.
+ * @throws MPDException Thrown if an error occurs as a result of command execution.
+ */
+ public void removeFromPlaylist(final String playlistName, final List positions)
+ throws IOException, MPDException {
+ Collections.sort(positions, Collections.reverseOrder());
+ final CommandQueue commandQueue = new CommandQueue(positions.size());
+
+ for (final Integer position : positions) {
+ commandQueue.add(MPDCommand.MPD_CMD_PLAYLIST_DEL, playlistName, position.toString());
+ }
+
+ commandQueue.send(mConnection);
+ }
+
public void removeFromPlaylist(final String playlistName, final Integer pos)
throws IOException, MPDException {
mConnection.sendCommand(MPDCommand.MPD_CMD_PLAYLIST_DEL, playlistName,
diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPDCommand.java b/JMPDComm/src/main/java/org/a0z/mpd/MPDCommand.java
index 628cd5f68e..195507c915 100644
--- a/JMPDComm/src/main/java/org/a0z/mpd/MPDCommand.java
+++ b/JMPDComm/src/main/java/org/a0z/mpd/MPDCommand.java
@@ -56,6 +56,9 @@ public class MPDCommand {
public static final String MPD_CMD_FIND = "find";
+ /** Added in MPD protocol 0.16.0 */
+ public static final String MPD_CMD_FIND_ADD = "findadd";
+
public static final String MPD_CMD_GROUP = "group";
public static final String MPD_CMD_IDLE = "idle";
@@ -115,6 +118,9 @@ public class MPDCommand {
public static final String MPD_CMD_SEARCH = "search";
+ /** Added in MPD protocol 0.17.0. */
+ public static final String MPD_CMD_SEARCH_ADD_PLAYLIST = "searchaddpl";
+
public static final String MPD_CMD_SEEK = "seek";
public static final String MPD_CMD_SEEK_ID = "seekid";
@@ -132,10 +138,6 @@ public class MPDCommand {
// deprecated commands
public static final String MPD_CMD_VOLUME = "volume";
- public static final String MPD_FIND_ALBUM = "album";
-
- public static final String MPD_FIND_ARTIST = "artist";
-
public static final String MPD_LIST_RESPONSE_ARTIST = "Artist";
public static final String MPD_SEARCH_ALBUM = "album";
diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPDPlaylist.java b/JMPDComm/src/main/java/org/a0z/mpd/MPDPlaylist.java
index 68a9d58286..68869df24f 100644
--- a/JMPDComm/src/main/java/org/a0z/mpd/MPDPlaylist.java
+++ b/JMPDComm/src/main/java/org/a0z/mpd/MPDPlaylist.java
@@ -390,6 +390,23 @@ public void removeById(final int... songIds) throws IOException, MPDException {
commandQueue.send(mConnection);
}
+ /**
+ * Removes entries from playlist.
+ *
+ * @param songIds Playlist songIDs to remove.
+ * @throws IOException Thrown upon a communication error with the server.
+ * @throws MPDException Thrown if an error occurs as a result of command execution.
+ */
+ public void removeById(final Collection songIds) throws IOException, MPDException {
+ final CommandQueue commandQueue = new CommandQueue(songIds.size());
+
+ for (final Integer id : songIds) {
+ commandQueue.add(MPD_CMD_PLAYLIST_REMOVE_ID, id.toString());
+ }
+
+ commandQueue.send(mConnection);
+ }
+
/**
* Removes entries from playlist.
*
diff --git a/MPDroid/build.gradle b/MPDroid/build.gradle
index 9412ba48d7..549137fca4 100644
--- a/MPDroid/build.gradle
+++ b/MPDroid/build.gradle
@@ -27,8 +27,8 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
- versionCode 51
- versionName "1.07 RC3 " + gitShortHash()
+ versionCode 52
+ versionName "1.07 RC4 " + gitShortHash()
}
lintOptions {
diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/FSFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/FSFragment.java
index fe0016b729..8fbc1e4143 100644
--- a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/FSFragment.java
+++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/FSFragment.java
@@ -69,7 +69,11 @@ protected void add(final Item item, final boolean replace, final boolean play) {
final Directory toAdd = mCurrentDirectory.getDirectory(item.getName());
if (toAdd == null) {
mApp.oMPDAsyncHelper.oMPD.add((FilesystemTreeEntry) item, replace, play);
- Tools.notifyUser(R.string.songAdded, item);
+ if (item instanceof PlaylistFile) {
+ Tools.notifyUser(R.string.playlistAdded, item);
+ } else {
+ Tools.notifyUser(R.string.songAdded, item);
+ }
} else {
// Valid directory
mApp.oMPDAsyncHelper.oMPD.add(toAdd, replace, play);
diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/GenresFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/GenresFragment.java
index 0b67d0ebf0..a16689622a 100644
--- a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/GenresFragment.java
+++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/GenresFragment.java
@@ -43,8 +43,7 @@ public GenresFragment() {
@Override
protected void add(final Item item, final boolean replace, final boolean play) {
try {
- mApp.oMPDAsyncHelper.oMPD.getPlaylist().addAll(
- mApp.oMPDAsyncHelper.oMPD.find("genre", item.getName()));
+ mApp.oMPDAsyncHelper.oMPD.add((Genre) item, replace, play);
Tools.notifyUser(mIrAdded, item);
} catch (final IOException | MPDException e) {
Log.e(TAG, "Failed to add all from playlist.", e);
@@ -54,8 +53,7 @@ protected void add(final Item item, final boolean replace, final boolean play) {
@Override
protected void add(final Item item, final String playlist) {
try {
- mApp.oMPDAsyncHelper.oMPD.addToPlaylist(playlist,
- mApp.oMPDAsyncHelper.oMPD.find("genre", item.getName()));
+ mApp.oMPDAsyncHelper.oMPD.addToPlaylist(playlist, (Genre) item);
Tools.notifyUser(mIrAdded, item);
} catch (final IOException | MPDException e) {
Log.e(TAG, "Failed to add all genre to playlist.", e);
diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/StoredPlaylistFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/StoredPlaylistFragment.java
index f5ba84e8b8..6a616bc432 100644
--- a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/StoredPlaylistFragment.java
+++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/StoredPlaylistFragment.java
@@ -163,6 +163,13 @@ public boolean onOptionsItemSelected(final MenuItem item) {
}
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ updateList();
+ }
+
@Override
public void onSaveInstanceState(final Bundle outState) {
outState.putString(EXTRA_PLAYLIST_NAME, mPlaylistName);
diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/library/PlaylistEditActivity.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/library/PlaylistEditActivity.java
index 9212ac75ad..6faa58d8ba 100644
--- a/MPDroid/src/main/java/com/namelessdev/mpdroid/library/PlaylistEditActivity.java
+++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/library/PlaylistEditActivity.java
@@ -42,7 +42,7 @@
import java.io.IOException;
import java.util.AbstractMap;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -109,27 +109,20 @@ public void onClick(final View v) {
int count = 0;
try {
- final ArrayList> copy = new ArrayList<>(mSongList);
+ final Collection> copy = new ArrayList<>(mSongList);
final List positions = new LinkedList<>();
- for (final HashMap item : copy) {
+ for (final AbstractMap item : copy) {
if (item.get("marked").equals(Boolean.TRUE)) {
positions.add((Integer) item.get("songid"));
- mSongList.remove(copy.indexOf(item) - count);
count++;
}
}
- Collections.sort(positions);
if (mIsPlayQueue) {
- for (count = 0; count < positions.size(); ++count) {
- mApp.oMPDAsyncHelper.oMPD.getPlaylist().removeById(positions.get(count));
- }
+ mApp.oMPDAsyncHelper.oMPD.getPlaylist().removeById(positions);
} else {
- for (count = 0; count < positions.size(); ++count) {
- mApp.oMPDAsyncHelper.oMPD.removeFromPlaylist(mPlaylistName,
- positions.get(count) - count);
- }
+ mApp.oMPDAsyncHelper.oMPD.removeFromPlaylist(mPlaylistName, positions);
}
if (copy.size() != mSongList.size()) {
((BaseAdapter) getListAdapter()).notifyDataSetChanged();
@@ -137,8 +130,8 @@ public void onClick(final View v) {
Tools.notifyUser(R.string.removeCountSongs, count);
} catch (final Exception e) {
Log.e(TAG, "General Error.", e);
- update();
}
+ update();
}
}
@@ -284,10 +277,17 @@ protected void update() {
final View view = null == getListView() ? null : getListView().getChildAt(0);
final int top = null == view ? -1 : view.getTop();
int listPlayingId = 0;
+ int playlistPosition = 0;
+
// Copy list to avoid concurrent exception
for (final Music music : new ArrayList<>(musics)) {
final HashMap item = new HashMap<>();
- item.put("songid", music.getSongId());
+ if (mIsPlayQueue) {
+ item.put("songid", music.getSongId());
+ } else {
+ item.put("songid", playlistPosition);
+ }
+ playlistPosition++;
item.put("artist", music.getArtist());
item.put("title", music.getTitle());
item.put("marked", false);
diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/service/MPDroidService.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/service/MPDroidService.java
index da2f87a7ff..0405d5a95c 100644
--- a/MPDroid/src/main/java/com/namelessdev/mpdroid/service/MPDroidService.java
+++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/service/MPDroidService.java
@@ -435,6 +435,7 @@ public int onStartCommand(final Intent intent, final int flags, final int startI
initializeAsyncHelper();
}
MPDControl.run(MPD_ASYNC_HELPER.oMPD, MPDControl.ACTION_PAUSE);
+ stopStream();
}
break;
case Intent.ACTION_BOOT_COMPLETED:
diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/service/StreamHandler.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/service/StreamHandler.java
index a296216963..d33f45005c 100644
--- a/MPDroid/src/main/java/com/namelessdev/mpdroid/service/StreamHandler.java
+++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/service/StreamHandler.java
@@ -475,7 +475,7 @@ public void onPrepared(final MediaPlayer mp) {
Log.d(TAG, "StreamHandler.onPrepared()");
}
- if (mIsPlaying) {
+ if (mIsPlaying && mIsActive) {
focusResult = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
} else {
@@ -486,7 +486,9 @@ public void onPrepared(final MediaPlayer mp) {
mServiceHandler.sendEmptyMessage(BUFFERING_END);
mMediaPlayer.start();
} else {
- showErrorToUser(R.string.audioFocusFailed);
+ if (mIsActive && mIsPlaying) {
+ showErrorToUser(R.string.audioFocusFailed);
+ }
/** Because mPreparingStream is still set, this will reset the stream. */
windDownResources(STREAMING_STOP);
diff --git a/MPDroid/src/main/res/drawable-xxxhdpi/icon.png b/MPDroid/src/main/res/drawable-xxxhdpi/icon.png
index 58284f029d..ceb6124a1f 100644
Binary files a/MPDroid/src/main/res/drawable-xxxhdpi/icon.png and b/MPDroid/src/main/res/drawable-xxxhdpi/icon.png differ
diff --git a/dmix.iml b/dmix.iml
index 0bb6048ae0..62553dc526 100644
--- a/dmix.iml
+++ b/dmix.iml
@@ -7,12 +7,14 @@
-
+
+
+
-
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 716e0f257b..52bf988e77 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Oct 31 13:25:32 PDT 2014
+#Wed Nov 26 12:20:56 PST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip