From 69da7071a9254a7d96baf40365a9acb40a581c0b Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Tue, 4 Nov 2014 20:03:33 -0800 Subject: [PATCH 01/33] SettingsActivity: Don't update connection settings if disconnected. --- .../org/a0z/mpd/connection/MPDConnection.java | 2 +- .../namelessdev/mpdroid/SettingsFragment.java | 44 ++++++++++--------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java b/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java index 297c7afc04..346157c6ed 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java @@ -98,7 +98,7 @@ public abstract class MPDConnection { private boolean mIsConnected = false; /** Current media server's major/minor/micro version. */ - private int[] mMPDVersion = null; + private int[] mMPDVersion = { 0, 0, 0 }; /** Current media server password. */ private String mPassword = null; diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/SettingsFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/SettingsFragment.java index a621091f6f..19e23a9922 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/SettingsFragment.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/SettingsFragment.java @@ -86,26 +86,30 @@ public void onAttach(final Activity activity) { public void onConnectionStateChanged() { final MPD mpd = mApp.oMPDAsyncHelper.oMPD; - mInformationScreen.setEnabled(mpd.isConnected()); - - new Thread(new Runnable() { - @Override - public void run() { - final String versionText = mpd.getMpdVersion(); - final MPDStatistics mpdStatistics = mpd.getStatistics(); - - mHandler.post(new Runnable() { - - @Override - public void run() { - mVersion.setSummary(versionText); - mArtists.setSummary(String.valueOf(mpdStatistics.getArtists())); - mAlbums.setSummary(String.valueOf(mpdStatistics.getAlbums())); - mSongs.setSummary(String.valueOf(mpdStatistics.getSongs())); - } - }); - } - }).start(); + final boolean isConnected = mpd.isConnected(); + + mInformationScreen.setEnabled(isConnected); + + if (isConnected) { + new Thread(new Runnable() { + @Override + public void run() { + final String versionText = mpd.getMpdVersion(); + final MPDStatistics mpdStatistics = mpd.getStatistics(); + + mHandler.post(new Runnable() { + + @Override + public void run() { + mVersion.setSummary(versionText); + mArtists.setSummary(String.valueOf(mpdStatistics.getArtists())); + mAlbums.setSummary(String.valueOf(mpdStatistics.getAlbums())); + mSongs.setSummary(String.valueOf(mpdStatistics.getSongs())); + } + }); + } + }).start(); + } } @Override From 53a74be875a123669e406d6c75275d230fda81a6 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Wed, 5 Nov 2014 12:04:11 -0800 Subject: [PATCH 02/33] MPD: Fix Album Artist setting regression from 51cecb7. Second attempt to fix this one. --- JMPDComm/src/main/java/org/a0z/mpd/MPD.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java index 09104424f3..ba823211c6 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java @@ -1303,13 +1303,13 @@ public List listAllAlbumsGrouped(final boolean useAlbumArtist, // Don't make the check with the other so we don't waste time doing string // comparisons for nothing. if (currentAlbum != null) { - currentAlbum.setAlbumArtist(new Artist(pair[VALUE])); + final Album newAlbum = currentAlbum.setAlbumArtist(new Artist(pair[VALUE])); + result.add(newAlbum); } } else if (albumResponse.equals(pair[KEY])) { if (!pair[VALUE].isEmpty() || includeUnknownAlbum) { currentAlbum = new Album(pair[VALUE], null); currentAlbum.setHasAlbumArtist(useAlbumArtist); - result.add(currentAlbum); } else { currentAlbum = null; } From 686e8a2c9b4ac868d6b40d8c2d3cc3ba31b4e506 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Wed, 5 Nov 2014 12:43:40 -0800 Subject: [PATCH 03/33] MPD: Generalize parseResponse, add it to Tools. This method caused an automated crash report, cleaned it up to use Tools.splitResponse() which should fix the source of the crash, then generalized it as it will be useful at a later time. --- JMPDComm/src/main/java/org/a0z/mpd/MPD.java | 32 +++----------- JMPDComm/src/main/java/org/a0z/mpd/Tools.java | 43 +++++++++++++++++++ 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java index ba823211c6..df99d58976 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java @@ -187,28 +187,6 @@ private static MPDCommand nextCommand() { return new MPDCommand(MPDCommand.MPD_CMD_NEXT); } - /** - * Parse the response from tag list command for album artists. - * - * @param response The album artist list response from the MPD server database. - * @param substring The substring from the response to remove. - * @param sortInsensitive Whether to sort insensitively. - * @return Returns a parsed album artist list. - */ - private static List parseResponse(final Collection response, - final String substring, final boolean sortInsensitive) { - final List result = new ArrayList<>(response.size()); - for (final String line : response) { - result.add(line.substring((substring + ": ").length())); - } - if (sortInsensitive) { - Collections.sort(result, String.CASE_INSENSITIVE_ORDER); - } else { - Collections.sort(result); - } - return result; - } - private static MPDCommand skipToPositionCommand(final int position) { return new MPDCommand(MPDCommand.MPD_CMD_PLAY, Integer.toString(position)); } @@ -1110,7 +1088,7 @@ public List listAlbumArtists(final boolean sortInsensitive) final List response = mConnection.sendCommand(MPDCommand.MPD_CMD_LIST_TAG, MPDCommand.MPD_TAG_ALBUM_ARTIST); - return parseResponse(response, "albumartist", sortInsensitive); + return Tools.parseResponse(response, "albumartist", sortInsensitive); } public List listAlbumArtists(final Genre genre) throws IOException, MPDException { @@ -1130,7 +1108,7 @@ public List listAlbumArtists(final Genre genre, final boolean sortInsens MPDCommand.MPD_CMD_LIST_TAG, MPDCommand.MPD_TAG_ALBUM_ARTIST, MPDCommand.MPD_TAG_GENRE, genre.getName()); - return parseResponse(response, MPDCommand.MPD_TAG_ALBUM_ARTIST, sortInsensitive); + return Tools.parseResponse(response, MPDCommand.MPD_TAG_ALBUM_ARTIST, sortInsensitive); } public List listAlbumArtists(final List albums) @@ -1359,7 +1337,7 @@ public List listArtists(final boolean sortInsensitive) final List response = mConnection.sendCommand(MPDCommand.MPD_CMD_LIST_TAG, MPDCommand.MPD_TAG_ARTIST); - return parseResponse(response, "Artist", sortInsensitive); + return Tools.parseResponse(response, "Artist", sortInsensitive); } /** @@ -1435,7 +1413,7 @@ public List listArtists(final String genre, final boolean sortInsensitiv final List response = mConnection.sendCommand(MPDCommand.MPD_CMD_LIST_TAG, MPDCommand.MPD_TAG_ARTIST, MPDCommand.MPD_TAG_GENRE, genre); - return parseResponse(response, "Artist", sortInsensitive); + return Tools.parseResponse(response, "Artist", sortInsensitive); } private List listArtistsCommand(final Iterable albums, @@ -1489,7 +1467,7 @@ public List listGenres(final boolean sortInsensitive) throws IOException final List response = mConnection.sendCommand(MPDCommand.MPD_CMD_LIST_TAG, MPDCommand.MPD_TAG_GENRE); - return parseResponse(response, "Genre", sortInsensitive); + return Tools.parseResponse(response, "Genre", sortInsensitive); } public void movePlaylistSong(final String playlistName, final int from, final int to) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/Tools.java b/JMPDComm/src/main/java/org/a0z/mpd/Tools.java index 46fc844b43..c2a48136d9 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/Tools.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/Tools.java @@ -28,7 +28,10 @@ package org.a0z.mpd; import java.security.MessageDigest; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.List; public final class Tools { @@ -162,6 +165,46 @@ public static boolean isNotEqual(final int[][] arrays) { return result; } + /** + * Parse a media server response for one entry type. + * + * @param response The media server response. + * @param type The entry type in the response to add to the collection. + * @return A collection of entries of one type in a media server response. + */ + public static List parseResponse(final Collection response, final String type) { + final List result = new ArrayList<>(response.size()); + + for (final String[] lines : splitResponse(response)) { + if (lines[KEY].equals(type)) { + result.add(lines[VALUE]); + } + } + + return result; + } + + /** + * Parse a media server response for one entry type, then sort the resulting list. + * + * @param response The media server response. + * @param substring The entry type in the response to add to the collection. + * @param sortInsensitive Whether to sort insensitively. + * @return A sorted collection of entries of one type in a media server response. + */ + public static List parseResponse(final Collection response, + final String substring, final boolean sortInsensitive) { + final List result = parseResponse(response, substring); + + if (sortInsensitive) { + Collections.sort(result, String.CASE_INSENSITIVE_ORDER); + } else { + Collections.sort(result); + } + + return result; + } + /** * Split the standard MPD protocol response into a three dimensional array consisting of a * two element String array key / value pairs. From 8594d8dae6671caa1beae04c9cd79337efb932bb Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Wed, 5 Nov 2014 13:23:59 -0800 Subject: [PATCH 04/33] MPD: Don't suppress/log exception in the library for no reason. --- JMPDComm/src/main/java/org/a0z/mpd/MPD.java | 12 ++++-------- .../com/namelessdev/mpdroid/helpers/CachedMPD.java | 4 +++- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java index df99d58976..9ba73ade3c 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java @@ -366,16 +366,12 @@ public void add(final PlaylistFile databasePlaylist, final boolean replace, fina add(commandQueue, replace, play); } - protected void addAlbumPaths(final List albums) { + protected void addAlbumPaths(final List albums) throws IOException, MPDException { if (albums != null && !albums.isEmpty()) { for (final Album album : albums) { - try { - final List songs = getFirstTrack(album); - if (!songs.isEmpty()) { - album.setPath(songs.get(0).getPath()); - } - } catch (final IOException | MPDException e) { - Log.error(TAG, "Failed to add an album path.", e); + final List songs = getFirstTrack(album); + if (!songs.isEmpty()) { + album.setPath(songs.get(0).getPath()); } } } diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/helpers/CachedMPD.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/helpers/CachedMPD.java index 46ed5e81a3..8aabf0c07e 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/helpers/CachedMPD.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/helpers/CachedMPD.java @@ -79,9 +79,11 @@ private static String getArtistName(final Artist artist) { * Adds path information to all album objects in a list. * * @param albums List of Album objects to add path information. + * @throws IOException Thrown upon a communication error with the server. + * @throws MPDException Thrown if an error occurs as a result of command execution. */ @Override - protected void addAlbumPaths(final List albums) { + protected void addAlbumPaths(final List albums) throws IOException, MPDException { if (!isCached()) { super.addAlbumPaths(albums); return; From 351a56d97c11060ec4f76629374dbbc80dcc02a9 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Thu, 6 Nov 2014 07:23:23 -0800 Subject: [PATCH 05/33] StreamsFragment: Check for the listplaylist command availablility before run. This is like a96a211, but for StreamsFragment as it often asks for it in FSFragment. Like a96a211, this only works on the standard MPD implementation for 0.19.2 and greater. --- .../mpdroid/fragments/StreamsFragment.java | 15 +++++++++++---- .../mpdroid/tools/LibraryTabsUtil.java | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/StreamsFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/StreamsFragment.java index 66a8ba0c34..1790aac81c 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/StreamsFragment.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/StreamsFragment.java @@ -20,6 +20,7 @@ import com.namelessdev.mpdroid.tools.StreamFetcher; import com.namelessdev.mpdroid.tools.Tools; +import org.a0z.mpd.MPDCommand; import org.a0z.mpd.exception.MPDException; import org.a0z.mpd.item.Item; import org.a0z.mpd.item.Music; @@ -229,10 +230,16 @@ private void loadStreams() { List mpdStreams = null; int iterator = 0; - try { - mpdStreams = mApp.oMPDAsyncHelper.oMPD.getSavedStreams(); - } catch (final IOException | MPDException e) { - Log.e(TAG, "Failed to retrieve saved streams.", e); + /** Many users have playlist support disabled, no need for an exception. */ + if (mApp.oMPDAsyncHelper.oMPD.isCommandAvailable(MPDCommand.MPD_CMD_LISTPLAYLISTS)) { + try { + mpdStreams = mApp.oMPDAsyncHelper.oMPD.getSavedStreams(); + } catch (final IOException | MPDException e) { + Log.e(TAG, "Failed to retrieve saved streams.", e); + } + } else { + Log.w(TAG, "Streams fragment can't load streams, playlist support not enabled."); + mpdStreams = Collections.emptyList(); } if (null != mpdStreams) { diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/tools/LibraryTabsUtil.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/tools/LibraryTabsUtil.java index a2ee269429..4bc35b94b1 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/tools/LibraryTabsUtil.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/tools/LibraryTabsUtil.java @@ -21,6 +21,7 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; +import android.support.annotation.StringRes; import java.util.ArrayList; import java.util.Arrays; @@ -83,6 +84,7 @@ public static ArrayList getCurrentLibraryTabs() { + LIBRARY_TABS_DELIMITER))); } + @StringRes public static int getTabTitleResId(final String tab) { return TABS.get(tab); } From 83dc28e910b4943aaa15857a258759a404b084fb Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Thu, 6 Nov 2014 13:11:19 -0800 Subject: [PATCH 06/33] MPDConnection: Throw IOException if no response and no error. We've received a couple of automated crash reports which no exception was thrown and no result was received. This is probably a bug of some sort. Having the user crash isn't going to help, throw an IOException for now, until the bug is either found or the code is replaced. --- .../main/java/org/a0z/mpd/MPDStatusMonitor.java | 5 ++++- .../org/a0z/mpd/connection/CommandResult.java | 11 +++++++++++ .../org/a0z/mpd/connection/MPDConnection.java | 16 ++++++++++------ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java b/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java index d03ad9f617..5719e1966f 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java @@ -309,8 +309,11 @@ public void run() { // connection lost connectionState = Boolean.FALSE; connectionLost = true; + if (mMPD.isConnected()) { + Log.error(TAG, "Exception caught while looping.", e); + } } catch (final MPDException e) { - e.printStackTrace(); + Log.error(TAG, "Exception caught while looping.", e); } } try { diff --git a/JMPDComm/src/main/java/org/a0z/mpd/connection/CommandResult.java b/JMPDComm/src/main/java/org/a0z/mpd/connection/CommandResult.java index f526e3c01e..ac97aff9fb 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/connection/CommandResult.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/connection/CommandResult.java @@ -49,6 +49,17 @@ final IOException getIOException() { return mIOException; } + /** + * Returns the first string response from the media server after connection. This method is + * mainly for debugging. + * + * @return A string representation of the connection result. + * @see #getMPDVersion() Use of this method is preferred. + */ + public String getConnectionResult() { + return mConnectionResult; + } + final MPDException getLastException() { return mLastException; } diff --git a/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java b/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java index 346157c6ed..1d16a21224 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java @@ -313,12 +313,16 @@ private CommandResult processCommand(final MPDCommand command) final IOException e = result.getIOException(); if (e == null) { - if (!mCancelled) { - Log.error(mTag, "There was no result, command was not cancelled, and no " + - "exception generated. This is probably a problem."); - } - } else if (!(mCancelled && e instanceof SocketException && - command.toString().contains(MPDCommand.MPD_CMD_IDLE))) { + /** + * This should not occur, and this exception should extend RuntimeException, + * BUT a RuntimeException would most likely not help the situation. + */ + throw new IOException( + "No result, no exception. This is a bug. Please report." + '\n' + + "Command: " + command + '\n' + + "Connected: " + mIsConnected + '\n' + + "Connection result: " + result.getConnectionResult() + '\n'); + } else { /** Don't throw if it's just about a cancelled command. That's expected. */ throw e; } From d7607ec4f1c0bd1732ff3bf90824f9db83482a01 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Thu, 6 Nov 2014 17:17:46 -0800 Subject: [PATCH 07/33] MPDConnection: Add yet more debug information to the no exception error. --- JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java | 1 + 1 file changed, 1 insertion(+) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java b/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java index 1d16a21224..0d47929e21 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java @@ -319,6 +319,7 @@ private CommandResult processCommand(final MPDCommand command) */ throw new IOException( "No result, no exception. This is a bug. Please report." + '\n' + + "Cancelled: " + mCancelled + '\n' + "Command: " + command + '\n' + "Connected: " + mIsConnected + '\n' + "Connection result: " + result.getConnectionResult() + '\n'); From 25ae7aa88e716f53bfefe7a1d50765d4f7d2566d Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Sat, 8 Nov 2014 14:04:15 -0800 Subject: [PATCH 08/33] MusicList: Refactor. This refactoring fixes quite a few issues, some causing internal inconsistency which has been in this class since existance. * When the inner list is manipulated, do not remove the old music entry from the inner list. This removal will occur at a later iteration of the changeset, if it needs be. This caused a bug which would cause an exception when adding or changing in the middle of the inner list. * Remove unused methods and constructors. There were a lot of unused methods that would no longer have any use and would add to the maintenance of this class. Since this class is for internal use only, we don't need to worry about feature methods. * Move the list iteration to manipulate(), it's better suited for the task. * Cleanups everywhere, including the workaround from f232f5f has been refactored. * Replace map with list. Our songID map has /never/ worked correctly, due to the way it was constructed. Replace it with an easier to maintain list. * Use sublist() to clear ranges. * Implement Iterable. --- .../main/java/org/a0z/mpd/MPDPlaylist.java | 79 +++---- .../src/main/java/org/a0z/mpd/MusicList.java | 207 +++++++----------- 2 files changed, 117 insertions(+), 169 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPDPlaylist.java b/JMPDComm/src/main/java/org/a0z/mpd/MPDPlaylist.java index cfeef5013f..68a9d58286 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPDPlaylist.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPDPlaylist.java @@ -34,6 +34,7 @@ import java.io.IOException; import java.util.Arrays; +import java.util.Collection; import java.util.List; /** @@ -187,20 +188,6 @@ public void clear() throws IOException, MPDException { mConnection.sendCommand(clearCommand()); } - /** - * This replaces the entire {@code MusicList} with a full playlist response from the media - * server. - * - * @throws IOException Thrown upon a communication error with the server. - * @throws MPDException Thrown if an error occurs as a result of command execution. - */ - private void fullPlaylistRefresh() throws IOException, MPDException { - final List response = mConnection.sendCommand(MPD_CMD_PLAYLIST_LIST); - final List playlist = Music.getMusicFromList(response, false); - - mList.replace(playlist); - } - /** * Retrieves music at position index in playlist. Operates on local copy of * playlist, may not reflect server's current playlist. @@ -212,6 +199,18 @@ public Music getByIndex(final int index) { return mList.getByIndex(index); } + /** + * This replaces the entire {@code MusicList} with a full playlist response from the media + * server. + * + * @throws IOException Thrown upon a communication error with the server. + * @throws MPDException Thrown if an error occurs as a result of command execution. + */ + private Collection getFullPlaylist() throws IOException, MPDException { + final List response = mConnection.sendCommand(MPD_CMD_PLAYLIST_LIST); + return Music.getMusicFromList(response, false); + } + /** * Retrieves all songs as an {@code List} of {@code Music}. * @@ -283,7 +282,8 @@ public void moveByPosition(final int start, final int number, final int to) } /** - * Reloads the playlist content. + * Reloads the playlist content. This is the only place the {@link org.a0z.mpd.MusicList} + * should be modified. * * @param mpdStatus A current {@code MPDStatus} object. * @throws IOException Thrown upon a communication error with the server. @@ -295,26 +295,18 @@ void refresh(final MPDStatus mpdStatus) throws IOException, MPDException { final int newPlaylistVersion = mpdStatus.getPlaylistVersion(); if (mLastPlaylistVersion == -1 || mList.size() == 0) { - fullPlaylistRefresh(); + mList.replace(getFullPlaylist()); } else if (mLastPlaylistVersion != newPlaylistVersion) { final List response = mConnection.sendCommand(MPD_CMD_PLAYLIST_CHANGES, Integer.toString(mLastPlaylistVersion)); - final List changes = Music.getMusicFromList(response, false); - final int playlistLength = mpdStatus.getPlaylistLength(); - final int listSize; - - for (final Music song : changes) { - mList.manipulate(song); - } + final Collection changes = Music.getMusicFromList(response, false); - listSize = mList.size(); - if (playlistLength > listSize) { - Log.warning(TAG, "Race detected, status playlist length > playlist length " + - "after changes have been applied. Reverting to full update."); - fullPlaylistRefresh(); - } else { - mList.removeByRange(mpdStatus.getPlaylistLength(), listSize); + try { + mList.manipulate(changes, mpdStatus.getPlaylistLength()); + } catch (final IllegalStateException e) { + Log.error(TAG, "Partial update failed, running full update.", e); + mList.replace(getFullPlaylist()); } } @@ -332,21 +324,22 @@ void refresh(final MPDStatus mpdStatus) throws IOException, MPDException { */ public void removeAlbumById(final int songId) throws IOException, MPDException { // Better way to get artist of given songId? - final List songs = mList.getMusic(); String artist = ""; String album = ""; int num = 0; boolean usingAlbumArtist = true; - for (final Music song : songs) { - if (song.getSongId() == songId) { - artist = song.getAlbumArtist(); - if (artist == null || artist.isEmpty()) { - usingAlbumArtist = false; - artist = song.getArtist(); + synchronized (mList) { + for (final Music song : mList) { + if (song.getSongId() == songId) { + artist = song.getAlbumArtist(); + if (artist == null || artist.isEmpty()) { + usingAlbumArtist = false; + artist = song.getArtist(); + } + album = song.getAlbum(); + break; } - album = song.getAlbum(); - break; } } @@ -358,9 +351,7 @@ public void removeAlbumById(final int songId) throws IOException, MPDException { /** Don't allow the list to change before we've computed the CommandList. */ synchronized (mList) { - final List tracks = mList.getMusic(); - - for (final Music track : tracks) { + for (final Music track : mList) { if (album.equals(track.getAlbum())) { final boolean songIsAlbumArtist = usingAlbumArtist && artist.equals(track.getAlbumArtist()); @@ -492,9 +483,9 @@ public void swapByPosition(final int song1, final int song2) throws IOException, * @return a string representation of the object. */ public String toString() { - final StringBuilder stringBuilder = new StringBuilder(mList.toString().length()); + final StringBuilder stringBuilder = new StringBuilder(); synchronized (mList) { - for (final Music music : mList.getMusic()) { + for (final Music music : mList) { stringBuilder.append(music); stringBuilder.append(MPDCommand.MPD_CMD_NEWLINE); } diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MusicList.java b/JMPDComm/src/main/java/org/a0z/mpd/MusicList.java index 04394bc2ea..da6ad2269a 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MusicList.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MusicList.java @@ -29,43 +29,39 @@ import org.a0z.mpd.item.Music; -import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; +import java.util.Iterator; import java.util.List; /** * @author Felipe Gustavo de Almeida, Stefan Agner */ -/** The skeleton of the playlist. */ -final class MusicList { +/** + * These lists store the internal structure store of the playlist. All modifications are + * synchronized, iterating over the list will still require manual locking. + */ +final class MusicList implements Iterable { + /** The debug flag, change to true for debugging log output. */ + private static final boolean DEBUG = false; + + /** The debug log identifier. */ private static final String TAG = "MusicList"; + /** The playlist store in positional order. */ private final List mList; - private final AbstractMap mSongIDMap; + /** A list of songIDs in songPos order. */ + private final List mSongID; MusicList() { super(); - mSongIDMap = new HashMap<>(); mList = Collections.synchronizedList(new ArrayList()); - } - - /** - * Constructs a new {@code MusicList} containing all music from - * {@code list}. - * - * @param list a {@code MusicList} - */ - MusicList(final MusicList list) { - this(); - - addAll(list.getMusic()); + mSongID = Collections.synchronizedList(new ArrayList()); } /** @@ -73,37 +69,37 @@ final class MusicList { * * @param music music to be added. */ - void add(final Music music) { - if (getById(music.getSongId()) != null) { - throw new IllegalArgumentException("Music is already on list"); - } - - // add it to the map and at the right position to the list - mSongIDMap.put(Integer.valueOf(music.getSongId()), music); - while (mList.size() < music.getPos() + 1) { - mList.add(null); - } - mList.set(music.getPos(), music); - } - - /** - * Adds all Musics from {@code playlist} to this {@code MusicList} - * . - * - * @param playlist {@code Collection} of {@code Music} to be added - * to this {@code MusicList}. - * @throws ClassCastException when {@code playlist} contains elements - * not assignable to {@code Music}. - */ - void addAll(final Collection playlist) { - mList.addAll(playlist); - } - - /** Removes all {@code Music} objects from this {@code MusicList}. */ - void clear() { + private void add(final Music music) { synchronized (mList) { - mList.clear(); - mSongIDMap.clear(); + final int songPos = music.getPos(); + + if (DEBUG) { + Log.debug(TAG, "listSize: " + mList.size() + " songPos: " + songPos); + } + if (mList.size() == songPos) { + if (DEBUG) { + Log.debug(TAG, "Adding music to the end"); + } + mList.add(music); + mSongID.add(music.getSongId()); + } else { + if (DEBUG) { + Log.debug(TAG, + "Adding beyond the end, or setting within the current playlist."); + } + /** + * Grow the list to the size of the songPos, THEN set it to the position necessary. + * The while loop shouldn't be necessary at all, unless, the result response is out + * of positional order. + */ + while (mList.size() <= songPos) { + mList.add(null); + mSongID.add(null); + } + + mList.set(songPos, music); + mSongID.set(songPos, music.getSongId()); + } } } @@ -114,8 +110,10 @@ void clear() { * @return a Music with given songId or {@code null} if it is not * present on this {@code MusicList}. */ - Music getById(final int songId) { - return mSongIDMap.get(Integer.valueOf(songId)); + Music getById(final int songId) { + final int songPos = Integer.valueOf(mSongID.indexOf(songId)); + + return mList.get(songPos); } /** @@ -145,107 +143,66 @@ List getMusic() { } /** - * Remove a {@code Music} object with given {@code songId} - * from this {@code MusicList}, if it is present. - * Adds or moves a Music item on the {@code MusicList}. + * Returns an {@link java.util.Iterator} for the music list. * - * @param music {@code Music} to be added or moved. + * @return An {@code Iterator} instance. */ - void manipulate(final Music music) { - final int songId = music.getSongId(); - final Integer songIdInteger = Integer.valueOf(songId); - final int songPos = music.getPos(); - - /** SongIDs can't exist in two places at the same time, remove it prior to adding it. */ - if (getById(songId) != null) { - mSongIDMap.remove(songIdInteger); - mList.remove(music); - } - - synchronized (mList) { - // add it to the map and at the right position to the list - mSongIDMap.put(songIdInteger, music); - while (mList.size() < songPos + 1) { - mList.add(null); - } - mList.set(songPos, music); - } + @Override + public Iterator iterator() { + return mList.iterator(); } /** - * Remove music with given {@code songId} from this - * {@code MusicList}, if it is present. + * Modifies the list to reflect the changes coming in from the {@code playlist}. Lock to an + * object prior to running this method. * - * @param songId songId of the {@code Music} to be removed from this - * {@code MusicList}. + * @param musicList The changes to make to the backing stores. + * @param listCapacity The size of the resulting list. */ - void removeById(final int songId) { - final Music music = getById(songId); - - synchronized (mList) { - if (music != null) { - mSongIDMap.remove(Integer.valueOf(songId)); - mList.remove(music); - } + void manipulate(final Iterable musicList, final int listCapacity) { + for (final Music music : musicList) { + /** + * Do not remove from either list. it will be removed by range. + */ + add(music); } - } - /** - * Removes a {@code Music} object at {@code position} from this {@code MusicList}, - * if it is present. - * - * @param index position of the {@code Music} to be removed from this - * {@code MusicList}. - */ - void removeByIndex(final int index) { + /** + * Consistency checks and cleanups. + */ synchronized (mList) { - final Music music = getByIndex(index); - - if (music != null) { - mList.remove(index); - mSongIDMap.remove(Integer.valueOf(music.getSongId())); + final int listSize = mList.size(); + final int songIDSize = mSongID.size(); + if (listSize < listCapacity) { + throw new IllegalStateException( + "List store: " + listSize + " and playlistLength: " + listCapacity + + " size differs."); } - } - } - - /** - * Removes all items sequentially within a specified range from the {@code MusicList}. - * - * @param start The position with which to start removing. - * @param end The final position to remove from the list. - */ - void removeByRange(final int start, final int end) { - if (start < -1 || start > mList.size()) { - throw new IndexOutOfBoundsException("Attempted invalid start range value: " + start + - ", list size: " + mList.size() + '.'); - } - if (end < -1 || end > mList.size()) { - throw new IndexOutOfBoundsException("Attempted invalid end range value: " + end + - ", list size: " + mList.size() + '.'); - } + mList.subList(listCapacity, listSize).clear(); + mSongID.subList(listCapacity, songIDSize).clear(); - int iterator = start; - synchronized (mList) { - while (iterator < end) { - removeByIndex(start); - iterator++; + if (songIDSize != listSize) { + throw new IllegalStateException("List store: " + listSize + + " and SongID: " + songIDSize + " size differs."); } } } /** - * Replace the current {@code MusicList} object. + * Replace all elements in this object. * * @param collection The {@code Music} collection to replace the {@code MusicList} with. */ void replace(final Collection collection) { + synchronized (mList) { - clear(); + mList.clear(); mList.addAll(collection); + mSongID.clear(); for (final Music track : collection) { - mSongIDMap.put(track.getSongId(), track); + mSongID.add(track.getSongId()); } } } From e1d8a8cae99e0bce901e2485a1ba8a0ed6512830 Mon Sep 17 00:00:00 2001 From: jpeitz Date: Tue, 11 Nov 2014 01:58:46 +0100 Subject: [PATCH 09/33] Artistfragment: Save and restore genre state --- .../mpdroid/fragments/ArtistsFragment.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/ArtistsFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/ArtistsFragment.java index 402ad2ad4f..97b575247c 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/ArtistsFragment.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/ArtistsFragment.java @@ -28,6 +28,7 @@ import org.a0z.mpd.item.Item; import android.content.SharedPreferences; +import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.StringRes; import android.util.Log; @@ -40,6 +41,8 @@ public class ArtistsFragment extends BrowseFragment { private static final String TAG = "ArtistsFragment"; + private static final String EXTRA_GENRE = "genre"; + private Genre mGenre = null; public ArtistsFragment() { @@ -125,6 +128,14 @@ public ArtistsFragment init(final Genre g) { return this; } + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState != null) { + init((Genre) savedInstanceState.getParcelable(EXTRA_GENRE)); + } + } + @Override public void onItemClick(final AdapterView parent, final View view, final int position, final long id) { @@ -138,4 +149,13 @@ public void onItemClick(final AdapterView parent, final View view, final int } ((ILibraryFragmentActivity) getActivity()).pushLibraryFragment(af, "album"); } + + @Override + public void onSaveInstanceState(final Bundle outState) { + if (mGenre != null) { + outState.putParcelable(EXTRA_GENRE, mGenre); + } + super.onSaveInstanceState(outState); + } + } From f7716ee36c062582ea890a5d0aa96c72fda06880 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Tue, 11 Nov 2014 07:22:03 -0800 Subject: [PATCH 10/33] MPD: Fix album artist response key case. --- JMPDComm/src/main/java/org/a0z/mpd/MPD.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java index 9ba73ade3c..a57d8c7b39 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java @@ -1083,8 +1083,7 @@ public List listAlbumArtists(final boolean sortInsensitive) throws IOException, MPDException { final List response = mConnection.sendCommand(MPDCommand.MPD_CMD_LIST_TAG, MPDCommand.MPD_TAG_ALBUM_ARTIST); - - return Tools.parseResponse(response, "albumartist", sortInsensitive); + return Tools.parseResponse(response, "AlbumArtist", sortInsensitive); } public List listAlbumArtists(final Genre genre) throws IOException, MPDException { @@ -1104,7 +1103,7 @@ public List listAlbumArtists(final Genre genre, final boolean sortInsens MPDCommand.MPD_CMD_LIST_TAG, MPDCommand.MPD_TAG_ALBUM_ARTIST, MPDCommand.MPD_TAG_GENRE, genre.getName()); - return Tools.parseResponse(response, MPDCommand.MPD_TAG_ALBUM_ARTIST, sortInsensitive); + return Tools.parseResponse(response, "AlbumArtist", sortInsensitive); } public List listAlbumArtists(final List albums) From 03b1f6dc70b427cb86223e70019c1e6967c9e7bb Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Tue, 11 Nov 2014 09:23:31 -0800 Subject: [PATCH 11/33] MPD: Refix album artist stuff. This commit (finally) removes the setAlbumArtist hack, if a album artist is to be set in the track there has to be new construction due to the equality/hashcode general contract. This fixes the broken album listing. --- .../src/main/java/org/a0z/mpd/item/Album.java | 4 +++ .../src/main/java/org/a0z/mpd/item/Album.java | 4 +++ JMPDComm/src/main/java/org/a0z/mpd/MPD.java | 28 +++++++++++-------- .../java/org/a0z/mpd/item/AbstractAlbum.java | 16 ++++------- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/JMPDComm/backends/android/src/main/java/org/a0z/mpd/item/Album.java b/JMPDComm/backends/android/src/main/java/org/a0z/mpd/item/Album.java index 24badf06f0..3672b04ef8 100644 --- a/JMPDComm/backends/android/src/main/java/org/a0z/mpd/item/Album.java +++ b/JMPDComm/backends/android/src/main/java/org/a0z/mpd/item/Album.java @@ -53,6 +53,10 @@ public Album(final Album otherAlbum) { super(otherAlbum); } + public Album(final Album otherAlbum, final Artist artist, final boolean hasAlbumArtist) { + super(otherAlbum, artist, hasAlbumArtist); + } + public Album(final String name, final Artist artist) { super(name, artist, false, 0L, 0L, 0L, null); } diff --git a/JMPDComm/backends/java/src/main/java/org/a0z/mpd/item/Album.java b/JMPDComm/backends/java/src/main/java/org/a0z/mpd/item/Album.java index f3b6c20a59..87741926af 100644 --- a/JMPDComm/backends/java/src/main/java/org/a0z/mpd/item/Album.java +++ b/JMPDComm/backends/java/src/main/java/org/a0z/mpd/item/Album.java @@ -38,6 +38,10 @@ public Album(final Album otherAlbum) { super(otherAlbum); } + public Album(final Album otherAlbum, final Artist artist, final boolean hasAlbumArtist) { + super(otherAlbum, artist, hasAlbumArtist); + } + public Album(final String name, final Artist artist) { super(name, artist, false, 0L, 0L, 0L, null); } diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java index a57d8c7b39..8b0dbaee74 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java @@ -585,13 +585,14 @@ protected void fixAlbumArtists(final List albums) { .isEmpty()) { // one albumartist, fix this // album final Artist artist = new Artist(aartists[0]); - albums.set(i, album.setAlbumArtist(artist)); + final Album newAlbum = new Album(album, artist, true); + albums.set(i, newAlbum); } // do nothing if albumartist is "" if (aartists.length > 1) { // it's more than one album, insert for (int n = 1; n < aartists.length; n++) { - final Album newalbum = - new Album(album.getName(), new Artist(aartists[n]), true); - splitAlbums.add(newalbum); + final Artist artist = new Artist(aartists[n]); + final Album newAlbum = new Album(album, artist, true); + splitAlbums.add(newAlbum); } } } @@ -1263,7 +1264,7 @@ public List listAllAlbumsGrouped(final boolean useAlbumArtist, final List response = mConnection.sendCommand(listAllAlbumsGroupedCommand(useAlbumArtist)); final List result = new ArrayList<>(response.size() / 2); - Album currentAlbum = null; + String currentAlbum = null; if (useAlbumArtist) { artistResponse = "AlbumArtist"; @@ -1272,17 +1273,22 @@ public List listAllAlbumsGrouped(final boolean useAlbumArtist, } for (final String[] pair : Tools.splitResponse(response)) { + if (artistResponse.equals(pair[KEY])) { - // Don't make the check with the other so we don't waste time doing string - // comparisons for nothing. if (currentAlbum != null) { - final Album newAlbum = currentAlbum.setAlbumArtist(new Artist(pair[VALUE])); - result.add(newAlbum); + final Artist artist = new Artist(pair[VALUE]); + result.add(new Album(currentAlbum, artist, useAlbumArtist)); + + currentAlbum = null; } } else if (albumResponse.equals(pair[KEY])) { + if (currentAlbum != null) { + /** There was no artist in this response, add the album alone */ + result.add(new Album(currentAlbum, null)); + } + if (!pair[VALUE].isEmpty() || includeUnknownAlbum) { - currentAlbum = new Album(pair[VALUE], null); - currentAlbum.setHasAlbumArtist(useAlbumArtist); + currentAlbum = pair[VALUE]; } else { currentAlbum = null; } diff --git a/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractAlbum.java b/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractAlbum.java index 4d8fd13c79..5998ffc8dd 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractAlbum.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractAlbum.java @@ -134,6 +134,11 @@ private int formattedYear(final long date) { otherAlbum.mPath); } + AbstractAlbum(final AbstractAlbum album, final Artist artist, final boolean hasAlbumArtist) { + this(album.mName, artist, hasAlbumArtist, album.mSongCount, album.mDuration, album.mYear, + album.mPath); + } + AbstractAlbum(final String name, final Artist artist) { this(name, artist, false, 0L, 0L, 0L, null); } @@ -244,17 +249,6 @@ public int hashCode() { return Arrays.hashCode(new Object[]{mName, mArtist}); } - /** - * This sets the album artist in a new album object, due to the required immutability of name - * and artist to satisfy the requirement that the hash code not change over time. - * - * @param albumArtist The album artist for this album. - * @return A new Album object based off this Album object. - */ - public Album setAlbumArtist(final Artist albumArtist) { - return new Album(mName, albumArtist, true, mSongCount, mDuration, mYear, mPath); - } - public void setDuration(final long duration) { mDuration = duration; } From 638283f24fdbb8ef3d05d57229de05769a34fe7e Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Wed, 12 Nov 2014 01:45:22 -0800 Subject: [PATCH 12/33] BrowseFragment: Fix regression from bfe8cc0. We received a crash report of someone trying to go to an artist on a PlaylistFile. This doesn't work as it's not an instance that has an artist, so, only accept instances that have artist entries. --- .../java/org/a0z/mpd/item/AbstractAlbum.java | 2 +- .../java/org/a0z/mpd/item/AbstractMusic.java | 2 +- .../mpdroid/fragments/BrowseFragment.java | 20 ++++++++++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractAlbum.java b/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractAlbum.java index 5998ffc8dd..f15fc887b4 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractAlbum.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractAlbum.java @@ -33,7 +33,7 @@ import java.util.Comparator; /** This class is the generic base for the Album items, abstracted for backend. */ -abstract class AbstractAlbum extends Item { +public abstract class AbstractAlbum extends Item { private final Artist mArtist; diff --git a/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractMusic.java b/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractMusic.java index 9e34c51d46..08083740ea 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractMusic.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractMusic.java @@ -48,7 +48,7 @@ * * @author Felipe Gustavo de Almeida */ -abstract class AbstractMusic extends Item implements FilesystemTreeEntry { +public abstract class AbstractMusic extends Item implements FilesystemTreeEntry { /** * This is like the default {@code Comparable} for the Music class, but it compares without diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/BrowseFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/BrowseFragment.java index 9ee81b945e..f56772197c 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/BrowseFragment.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/BrowseFragment.java @@ -26,6 +26,10 @@ import org.a0z.mpd.MPDCommand; import org.a0z.mpd.MPDStatus; import org.a0z.mpd.exception.MPDException; +import org.a0z.mpd.item.AbstractAlbum; +import org.a0z.mpd.item.AbstractMusic; +import org.a0z.mpd.item.Album; +import org.a0z.mpd.item.Artist; import org.a0z.mpd.item.Item; import org.a0z.mpd.item.Music; @@ -369,10 +373,20 @@ public boolean onMenuItemClick(final MenuItem item) { final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); final Object selectedItem = mItems.get((int) info.id); final Intent intent = new Intent(getActivity(), SimpleLibraryActivity.class); - final Music music = (Music) selectedItem; + Artist artist = null; + + if (selectedItem instanceof Album) { + artist = ((AbstractAlbum) selectedItem).getArtist(); + } else if (selectedItem instanceof Artist) { + artist = (Artist) selectedItem; + } else if (selectedItem instanceof Music) { + artist = new Artist(((AbstractMusic) selectedItem).getAlbumArtistOrArtist()); + } - intent.putExtra("artist", music.getArtistAsArtist()); - startActivityForResult(intent, -1); + if (artist != null) { + intent.putExtra("artist", artist); + startActivityForResult(intent, -1); + } break; default: final String name = item.getTitle().toString(); From 2359f1553b5428f7719cf6dfa2541df775fb3e46 Mon Sep 17 00:00:00 2001 From: Arnaud Barisain-Monrose Date: Wed, 12 Nov 2014 21:41:02 +0100 Subject: [PATCH 13/33] New build tools --- MPDroid/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MPDroid/build.gradle b/MPDroid/build.gradle index ddca05e604..4720fcbaa1 100644 --- a/MPDroid/build.gradle +++ b/MPDroid/build.gradle @@ -22,7 +22,7 @@ def gitShortHash() { android { compileSdkVersion 21 - buildToolsVersion "21.0.2" + buildToolsVersion "21.1.1" defaultConfig { minSdkVersion 14 From dc872eff47c10cad678127cc24af303050eaf128 Mon Sep 17 00:00:00 2001 From: Arnaud Barisain-Monrose Date: Wed, 12 Nov 2014 21:50:02 +0100 Subject: [PATCH 14/33] Bump buildtools --- JMPDComm/backends/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JMPDComm/backends/android/build.gradle b/JMPDComm/backends/android/build.gradle index 1feda5dd73..8811202959 100644 --- a/JMPDComm/backends/android/build.gradle +++ b/JMPDComm/backends/android/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.library' android { compileSdkVersion 21 - buildToolsVersion "21.0.2" + buildToolsVersion "21.1.1" lintOptions { abortOnError false From eaca04704c0e7edc31a41f85ed2230c69b9c220e Mon Sep 17 00:00:00 2001 From: Arnaud Barisain-Monrose Date: Wed, 12 Nov 2014 21:50:14 +0100 Subject: [PATCH 15/33] Add play services voice search --- MPDroid/src/main/AndroidManifest.xml | 2 +- .../src/main/java/com/namelessdev/mpdroid/SearchActivity.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/MPDroid/src/main/AndroidManifest.xml b/MPDroid/src/main/AndroidManifest.xml index b0f95c9368..ded136df5c 100644 --- a/MPDroid/src/main/AndroidManifest.xml +++ b/MPDroid/src/main/AndroidManifest.xml @@ -54,7 +54,7 @@ android:label="@string/search"> - + diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/SearchActivity.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/SearchActivity.java index 099d09eacd..3b3d6618aa 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/SearchActivity.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/SearchActivity.java @@ -78,6 +78,8 @@ public class SearchActivity extends MPDroidActivity implements OnMenuItemClickLi private static final String TAG = "SearchActivity"; + private static final String PLAY_SERVICES_ACTION_SEARCH = "com.google.android.gms.actions.SEARCH_ACTION"; + private final ArrayList mAlbumResults; private final ArrayList mArtistResults; @@ -327,7 +329,7 @@ public void onPageSelected(final int position) { final Intent queryIntent = getIntent(); final String queryAction = queryIntent.getAction(); - if (Intent.ACTION_SEARCH.equals(queryAction)) { + if (Intent.ACTION_SEARCH.equals(queryAction) || PLAY_SERVICES_ACTION_SEARCH.equals(queryAction)) { mSearchKeywords = queryIntent.getStringExtra(SearchManager.QUERY).trim(); final SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, SearchRecentProvider.AUTHORITY, SearchRecentProvider.MODE); From b530de6c6c11fe29161c0b313aaaf198bb759f1a Mon Sep 17 00:00:00 2001 From: Arnaud Barisain-Monrose Date: Wed, 12 Nov 2014 22:00:48 +0100 Subject: [PATCH 16/33] Fix travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0739757d5e..d9a30eccc6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ android: # - tools # The BuildTools version used by your project. - - build-tools-21.0.2 + - build-tools-21.1.1 # The SDK version used to compile your project. - android-21 From 46f4a10bd590f96a326c3ba6602803736d82d567 Mon Sep 17 00:00:00 2001 From: Arnaud Barisain-Monrose Date: Wed, 12 Nov 2014 22:06:06 +0100 Subject: [PATCH 17/33] Update korean translations --- MPDroid/src/main/res/values-ko/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MPDroid/src/main/res/values-ko/strings.xml b/MPDroid/src/main/res/values-ko/strings.xml index 412ecf8609..9f510e75d0 100644 --- a/MPDroid/src/main/res/values-ko/strings.xml +++ b/MPDroid/src/main/res/values-ko/strings.xml @@ -224,7 +224,7 @@ 음반 연주자로 가기 폴더로 가기 스트림으로 가기 - 현재 곡으로 이동 + 지금 곡으로 이동 기타 사진 이미지 재설정 @@ -247,7 +247,7 @@ 서랍 보기 서랍 닫기 - 현재 연주 중 설정 + 지금 연주 중 설정 작은 찾기 사용 찾은 이력 지우기 스트림 저장됨 @@ -296,6 +296,6 @@ 네트워크 관련 운영 실패. 스트림이 관련 코딩 규격과 맞지 않음. 운영 시간 초과. - 미디어 프레임워크가 스트림 코넥을 지원하지 않음. + 미디어 프레임워크가 스트림 코덱을 지원하지 않음. \ No newline at end of file From 065e711241fb9c799b43a56765abaf4bd8f4b186 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Wed, 12 Nov 2014 14:08:48 -0800 Subject: [PATCH 18/33] Music: Use smaller, more exact, constructors, fix NPE in getFullPath(). We received a crash report detailing a crash that occured due to a null mFullPath field. This really shouldn't happen, but since it apparently does, cover it with an if block like the rest of this class. This /could/ be fixed with the constructor fix (detailed below); cover it up until possibly post- release testing. While looking into this bug, I also noticed the children classes for the Music class are inexact constructors. For instance, we would construct the children with getTitle() which is /not/ a getter. Use a better suited constructor and change permissions so it won't happen again. --- .../src/main/java/org/a0z/mpd/item/Music.java | 32 ++++++------- .../java/org/a0z/mpd/item/AbstractMusic.java | 46 +++++++++++-------- .../mpdroid/models/AbstractPlaylistMusic.java | 10 +--- .../mpdroid/models/PlaylistSong.java | 5 +- .../mpdroid/models/PlaylistStream.java | 5 +- 5 files changed, 46 insertions(+), 52 deletions(-) diff --git a/JMPDComm/backends/android/src/main/java/org/a0z/mpd/item/Music.java b/JMPDComm/backends/android/src/main/java/org/a0z/mpd/item/Music.java index bfbec404af..af5ba308d2 100644 --- a/JMPDComm/backends/android/src/main/java/org/a0z/mpd/item/Music.java +++ b/JMPDComm/backends/android/src/main/java/org/a0z/mpd/item/Music.java @@ -57,7 +57,7 @@ protected Music(final Music music) { super(music); } - protected Music(final String album, final String artist, final String albumArtist, + Music(final String album, final String artist, final String albumArtist, final String composer, final String fullPath, final int disc, final long date, final String genre, final long time, final String title, final int totalTracks, final int track, final int songId, final int songPos, final String name) { @@ -84,20 +84,20 @@ public int describeContents() { @Override public void writeToParcel(final Parcel dest, final int flags) { - dest.writeString(getAlbum()); - dest.writeString(getArtist()); - dest.writeString(getAlbumArtist()); - dest.writeString(getComposer()); - dest.writeString(getFullPath()); - dest.writeInt(getDisc()); - dest.writeLong(getDate()); - dest.writeString(getGenre()); - dest.writeLong(getTime()); - dest.writeString(getTitle()); - dest.writeInt(getTotalTracks()); - dest.writeInt(getTrack()); - dest.writeInt(getSongId()); - dest.writeInt(getPos()); - dest.writeString(getName()); + dest.writeString(mAlbum); + dest.writeString(mArtist); + dest.writeString(mAlbumArtist); + dest.writeString(mComposer); + dest.writeString(mFullPath); + dest.writeInt(mDisc); + dest.writeLong(mDate); + dest.writeString(mGenre); + dest.writeLong(mTime); + dest.writeString(mTitle); + dest.writeInt(mTotalTracks); + dest.writeInt(mTrack); + dest.writeInt(mSongId); + dest.writeInt(mSongPos); + dest.writeString(mName); } } diff --git a/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractMusic.java b/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractMusic.java index 08083740ea..4e36786b20 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractMusic.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/item/AbstractMusic.java @@ -100,35 +100,35 @@ public int compare(final AbstractMusic lhs, final AbstractMusic rhs) { private static final int UNDEFINED_INT = -1; - private final String mAlbum; + final String mAlbum; - private final String mAlbumArtist; + final String mAlbumArtist; - private final String mArtist; + final String mArtist; - private final String mComposer; + final String mComposer; - private final long mDate; + final long mDate; - private final int mDisc; + final int mDisc; - private final String mFullPath; + final String mFullPath; - private final String mGenre; + final String mGenre; - private final String mName; + final String mName; - private final int mSongId; + final int mSongId; - private final int mSongPos; + final int mSongPos; - private final long mTime; + final long mTime; - private final String mTitle; + final String mTitle; - private final int mTotalTracks; + final int mTotalTracks; - private final int mTrack; + final int mTrack; AbstractMusic() { this(null, /** Album */ @@ -614,12 +614,18 @@ public int getDisc() { * @return filename. */ public String getFilename() { - final int pos = mFullPath.lastIndexOf('/'); - if (pos == -1 || pos == mFullPath.length() - 1) { - return mFullPath; - } else { - return mFullPath.substring(pos + 1); + String result = null; + + if (mFullPath != null) { + final int pos = mFullPath.lastIndexOf('/'); + if (pos == -1 || pos == mFullPath.length() - 1) { + result = mFullPath; + } else { + result = mFullPath.substring(pos + 1); + } } + + return result; } /** diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/models/AbstractPlaylistMusic.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/models/AbstractPlaylistMusic.java index b8f16c582e..e3e7f100c5 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/models/AbstractPlaylistMusic.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/models/AbstractPlaylistMusic.java @@ -24,14 +24,8 @@ public abstract class AbstractPlaylistMusic extends Music { private boolean mForceCoverRefresh = false; - protected AbstractPlaylistMusic(final String album, final String artist, - final String albumartist, final String composer, - final String fullpath, final int disc, final long date, final String genre, - final long time, final String title, - final int totalTracks, final int track, final int songId, final int pos, - final String name) { - super(album, artist, albumartist, composer, fullpath, disc, date, genre, time, title, - totalTracks, track, songId, pos, name); + protected AbstractPlaylistMusic(final Music music) { + super(music); } public int getCurrentSongIconRefID() { diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/models/PlaylistSong.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/models/PlaylistSong.java index 29271b1d8f..29bc8d4350 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/models/PlaylistSong.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/models/PlaylistSong.java @@ -27,10 +27,7 @@ public class PlaylistSong extends AbstractPlaylistMusic { public PlaylistSong(final Music music) { - super(music.getAlbum(), music.getArtist(), music.getAlbumArtist(), music.getComposer(), - music.getFullPath(), music.getDisc(), music.getDate(), music.getGenre(), - music.getTime(), music.getTitle(), music.getTotalTracks(), music.getTrack(), - music.getSongId(), music.getPos(), music.getName()); + super(music); } @Override diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/models/PlaylistStream.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/models/PlaylistStream.java index ffb5ee6d72..813b652a4b 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/models/PlaylistStream.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/models/PlaylistStream.java @@ -22,10 +22,7 @@ public class PlaylistStream extends AbstractPlaylistMusic { public PlaylistStream(final Music music) { - super(music.getAlbum(), music.getArtist(), music.getAlbumArtist(), music.getComposer(), - music.getFullPath(), music.getDisc(), music.getDate(), music.getGenre(), - music.getTime(), music.getTitle(), music.getTotalTracks(), music.getTrack(), - music.getSongId(), music.getPos(), music.getName()); + super(music); } @Override From 23e42142f7cc9df7aba61b3c47b2beb2b843fa51 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Fri, 31 Oct 2014 15:34:53 -0700 Subject: [PATCH 19/33] StreamHandler: Setup AudioAttributes for MediaPlayer. --- .../namelessdev/mpdroid/service/StreamHandler.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 eb0b316c6f..a296216963 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/service/StreamHandler.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/service/StreamHandler.java @@ -23,6 +23,7 @@ import org.a0z.mpd.MPDStatus; import android.content.res.Resources; +import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioManager.OnAudioFocusChangeListener; import android.media.MediaPlayer; @@ -30,6 +31,7 @@ import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnInfoListener; import android.media.MediaPlayer.OnPreparedListener; +import android.os.Build; import android.os.Handler; import android.os.Message; import android.os.PowerManager; @@ -690,5 +692,15 @@ private void windUpResources() { mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnErrorListener(this); mMediaPlayer.setWakeMode(mServiceContext, PowerManager.PARTIAL_WAKE_LOCK); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + final AudioAttributes audioAttributes = + new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) + .setUsage(AudioAttributes.USAGE_MEDIA) + .build(); + + mMediaPlayer.setAudioAttributes(audioAttributes); + } } } From fdaf0e6fd3d3cdb77f14d3233d14ae15c3e5c964 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Thu, 13 Nov 2014 13:23:38 -0800 Subject: [PATCH 20/33] MPD: Don't send a command queue if nothing was added in add(). We received a automated crash response due to an attempt to send an empty command queue. This was due to a user doing an add() with very specific parameters which would negate every conditional on the way through and never added to the command queue. For this case, I've added a conditional which should be negated if there is an empty command queue at the end. --- JMPDComm/src/main/java/org/a0z/mpd/CommandQueue.java | 8 ++++++++ JMPDComm/src/main/java/org/a0z/mpd/MPD.java | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/CommandQueue.java b/JMPDComm/src/main/java/org/a0z/mpd/CommandQueue.java index b490ab0d7d..257bdc4151 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/CommandQueue.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/CommandQueue.java @@ -155,6 +155,10 @@ void clear() { mCommandQueue.clear(); } + public boolean isEmpty() { + return mCommandQueue.isEmpty(); + } + /** Reverse the command queue order, useful for removing playlist entries. */ void reverse() { Collections.reverse(mCommandQueue); @@ -215,6 +219,10 @@ public List sendSeparated(final MPDConnection mpdConnection) return separatedQueueResults(send(mpdConnection, true)); } + public int size() { + return mCommandQueue.size(); + } + /** * Returns the command queue in {@code String} format. * diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java index 8b0dbaee74..cd49da44fd 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java @@ -330,7 +330,13 @@ public void add(final CommandQueue commandQueue, final boolean replace, } - commandQueue.send(mConnection); + /** + * It's rare, but possible to make it through the add() + * methods without adding to the command queue. + */ + if (!commandQueue.isEmpty()) { + commandQueue.send(mConnection); + } } /** From 544f5c226bdbe8ec5ee76f2d0f7cd7b7edb2a3d3 Mon Sep 17 00:00:00 2001 From: MaDill Date: Wed, 12 Nov 2014 17:41:33 +0100 Subject: [PATCH 21/33] Updated some German strings and compared with English strings.xml --- MPDroid/src/main/res/values-de/strings.xml | 559 +++++++++++---------- 1 file changed, 291 insertions(+), 268 deletions(-) diff --git a/MPDroid/src/main/res/values-de/strings.xml b/MPDroid/src/main/res/values-de/strings.xml index 7474023b9e..f7ed63b663 100644 --- a/MPDroid/src/main/res/values-de/strings.xml +++ b/MPDroid/src/main/res/values-de/strings.xml @@ -1,284 +1,307 @@ - + + + - + - MPDroid - Künstler - Genres - Wiedergabelisten - Dateien - Alben - Einstellungen - Nächster - Vorheriger - OK - Beenden - Wiederholen - Lade … - Lade Genres … - Lade Alben … - Lade Künstler … - Lade Titel … - Lade Wiedergabelisten … - Wiedergabeliste - Hinzufügen und ersetzen - Hinzufügen, ersetzen und abspielen - Album hinzufügen - Wiedergabeliste hinzufügen - Hinzufügen und abspielen - Künstler hinzufügen - Genre hinzufügen - Hinzufügen - Titel hinzufügen - Titel entfernen - Titel beschneiden - %s Titel entfernt - Leeren - Hauptmenü - Wiedergabeliste geleert - Titel von Wiedergabeliste entfernt - Album \"%s\" hinzugefügt - Wiedergabeliste \"%s\" hinzugefügt - Verzeichnis zur Wiedergabeliste hinzugefügt - Künstler \"%s\" hinzugefügt - Host - MPD-Server-Hostname oder IP-Adresse - Streaming-Host - Streaming-Server (Hostname oder IP-Adresse) - Port - MPD-Server-Port (Standard: 6600) - Passwort - Passwort für den Server - Version - Titel - Server-Informationen - Diverse MPD-Server-Informationen wie Version, Anzahl Stücke … - Verbindungseinstellungen - Setze MPD-Host/Port und Passwort - Ausgänge - Ansichtseinstellungen - Bibliothekseinstellungen - Titel \"%s\" hinzugefügt - Über - Verbindung fehlgeschlagen - Die Verbindung zum MPD-Server ist fehlgeschlagen! Bitte überprüfen Sie, ob der Server läuft und erreichbar ist. (%s) - Verbinde - Verbinde … - Verbinde mit MPD-Server. - Verbunden - Nicht verbunden - Keine Informationen für diesen Titel - Nicht in Reichweite, gespeichert - Wiedergabeliste \"%s\" gelöscht - Wiedergabeliste löschen - Standard-Verbindung - Bevorzugte Verbindung - WLAN-Netzwerk wählen - WLAN-basierte Verbindung - Standard-Verbindung - WLAN-basiert den MPD-Host/Port und das Passwort definieren - Standard-MPD-Host/Port und das Passwort definieren - Streaming - Zwischenspeichern … - Streaming-Port - MPD-Streaming-Port (Standard: 8000) - Streaming-URL-Suffix - Dateiendung für Stream-URL (z.B. mpd.mp3) - MPDroid ist Open Source. Quelltext unter http://github.com/abarisain/dmix - MPDroid ist ein Fork von PMix\n (http://code.google.com/p/pmix/). Bedanke dich! - Suchen - MPDroid - Suchen … - Bibliothek - Bitte lesen - Willkommen bei MPDroid 1.0!\nDiese Meldung wird nur einmal angezeigt.\n\nZuerst: Falls Sie nicht wissen, was ein MPD-Server ist, sollten Sie diese App wieder deinstallieren. Sie ist nichts für Sie.\nWichtig! Bekannter Fehler: Das Widget stürzt manchmal ab oder erhöht den Batterieverbrauch.\n\nFür Benutzer der alten Version: Vielen Dank für Ihre Unterstützung und Mitarbeit. Ich hoffe wirklich, dass Ihnen diese neue MPDroid-Version gefällt. Sie können mir gerne per E-Mail mitteilen, was Ihnen gefällt oder auch nicht gefällt :)\nDie alte Version gibt es noch auf meiner Github-Seite. - Bearbeiten - Du hörst - Abbrechen - Als Nächstes einordnen - Gehe zu … - An den Anfang verschieben - Ans Ende verschieben - Von der Wiedergabeliste entfernen - Album entfernen - Speichern - Aktualisiere die MPD-Datenbank - Album-Cache verwenden - Teile der MPD-Datenbank lokal speichern - Erscheinungsjahr - Sortiere Alben nach Erscheinungsjahr - Titelanzahl anzeigen - Zeige Titelanzahl der Alben - Lokale Albencover laden - Albencover vom MPD-Server laden (Erfordert einen Webserver, siehe Wiki) - Musikverzeichnis - Musikverzeichnis auf dem MPD-Server z.B. files/mp3 (music/ für Vortexbox-Benutzer). Für aufwendige Einstellungen können auch absolute Pfade (z.B. "http://ip:port/music") verwendet werden. - Albencover-Datei - Dateiname der Albencover z.B. folder.jpg (cover.jpg für Vortexbox-Benutzer) - Belegter Cache-Speicher - Diesen Server löschen - Original App-Logo von Asher (http://kyo-tux.deviantart.com/) und brsev (http://brsev.deviantart.com/), bearbeitet für MPDroid. - Die Verbindung zum MPD-Server ist fehlgeschlagen! Prüfen Sie die Verbindungseinstellungen. (%s) - Keine Ergebnisse - Erneut drücken, um das Programm zu beenden - Wiedergabeliste - Wiedergabeliste \"%s\" wirklich löschen? - %s konnte nicht gelöscht werden - Verschiedene Interpreten - %1$s Titel, %2$s - %1$s Titel, %2$s - Kann Streaming nicht starten. Wird von einer anderen Anwendung benutzt. - Zu einer Wiedergabeliste hinzufügen - (Neue Wiedergabeliste) - Wiedergabeliste - Name der neuen Wiedergabeliste: - Streams - Stream hinzufügen - Bearbeiten - Stream \"%s\" hinzugefügt - Lade Streams … - Stream \"%s\" gelöscht - Stream löschen - Stream \"%s\" wirklich löschen? - Name: - URL: - Genre \"%s\" hinzugefügt - Stopptaste anzeigen - Einzelmodus - Verbrauchsmodus - Albencover - Teiler Schaltfläche - Starte MPDroid - Menü-Schaltfläche - Element-Handle auflisten - Abspielen - Stopp - Album-Jahr anzeigen - Albumkünstler anzeigen - Audio-Eigenschaften anzeigen + MPDroid + Künstler + Genres + Wiedergabelisten + Dateien + Alben + Einstellungen + Nächster + Vorheriger + OK + Beenden + Wiederholen + Lade … + Lade Genres … + Lade Alben … + Lade Künstler … + Lade Titel … + Lade Wiedergabelisten … + Wiedergabeliste + Hinzufügen und ersetzen + Hinzufügen, ersetzen und abspielen + Album hinzufügen + Wiedergabeliste hinzufügen + Hinzufügen und abspielen + Künstler hinzufügen + Genre hinzufügen + Hinzufügen + Titel hinzufügen + Titel entfernen + Titel beschneiden + %s Titel entfernt + Leeren + Hauptmenü + Wiedergabeliste geleert + Titel von Wiedergabeliste entfernt + Album \"%s\" hinzugefügt + Wiedergabeliste \"%s\" hinzugefügt + Verzeichnis zur Wiedergabeliste hinzugefügt + Künstler \"%s\" hinzugefügt + Host + MPD-Server-Hostname oder IP-Adresse + Streaming-Host + Streaming-Server (Hostname oder IP-Adresse) + Port + MPD-Server-Port (Standard: 6600) + Passwort + Passwort für den Server + Version + Titel + Server-Informationen + Diverse MPD-Server-Informationen wie Version, Anzahl Stücke … + Verbindungseinstellungen + Setze MPD-Host/Port und Passwort + Ausgänge + Ansichtseinstellungen + Bibliothekseinstellungen + Titel \"%s\" hinzugefügt + Über + Verbindung fehlgeschlagen + Die Verbindung zum MPD-Server ist fehlgeschlagen! Bitte überprüfen Sie, ob der Server läuft und erreichbar ist. (%s) + Verbinde + Verbinde … + Verbinde mit MPD-Server. + Verbunden + Nicht verbunden + Keine Informationen für diesen Titel + Nicht in Reichweite, gespeichert + Wiedergabeliste \"%s\" gelöscht + Wiedergabeliste löschen + Standard-Verbindung + Bevorzugte Verbindung + WLAN-Netzwerk wählen + WLAN-basierte Verbindung + Standard-Verbindung + WLAN-basiert den MPD-Host/Port und das Passwort definieren + Standard-MPD-Host/Port und das Passwort definieren + Streaming + Zwischenspeichern … + Streaming-Port + MPD-Streaming-Port (Standard: 8000) + Streaming-URL-Suffix + Dateiendung für Stream-URL (z.B. mpd.mp3) + MPDroid ist Open Source. Quelltext unter http://github.com/abarisain/dmix + MPDroid ist ein Fork von PMix\n (http://code.google.com/p/pmix/). Bedanke dich! + Suchen + MPDroid + Suchen … + Bibliothek + Bitte lesen + Willkommen bei MPDroid 1.0!\nDiese Meldung wird nur einmal angezeigt.\n\nZuerst: Falls Sie nicht wissen, was ein MPD-Server ist, sollten Sie diese App wieder deinstallieren. Sie ist nichts für Sie.\nWichtig! Bekannter Fehler: Das Widget stürzt manchmal ab oder erhöht den Batterieverbrauch.\n\nFür Benutzer der alten Version: Vielen Dank für Ihre Unterstützung und Mitarbeit. Ich hoffe wirklich, dass Ihnen diese neue MPDroid-Version gefällt. Sie können mir gerne per E-Mail mitteilen, was Ihnen gefällt oder auch nicht gefällt :)\nDie alte Version gibt es noch auf meiner Github-Seite. + Bearbeiten + Du hörst + Abbrechen + Als Nächstes einordnen + Gehe zu … + An den Anfang verschieben + Ans Ende verschieben + Von der Wiedergabeliste entfernen + Album entfernen + Speichern + Aktualisiere die MPD-Datenbank + Album-Cache verwenden + Teile der MPD-Datenbank lokal speichern + Erscheinungsjahr + Sortiere Alben nach Erscheinungsjahr + Titelanzahl anzeigen + Zeige Titelanzahl der Alben + Lokale Albencover laden + Albencover vom MPD-Server laden (Erfordert einen Webserver, siehe Wiki) + Musikverzeichnis + Musikverzeichnis auf dem MPD-Server z.B. files/mp3 (music/ für Vortexbox-Benutzer). Für aufwendige Einstellungen können auch absolute Pfade (z.B. "http://ip:port/music") verwendet werden. + Albencover-Datei + Dateiname der Albencover z.B. folder.jpg (cover.jpg für Vortexbox-Benutzer) + Belegter Cache-Speicher + Diesen Server löschen + Original App-Logo von Asher (http://kyo-tux.deviantart.com/) und brsev (http://brsev.deviantart.com/), bearbeitet für MPDroid. + Die Verbindung zum MPD-Server ist fehlgeschlagen! Prüfen Sie die Verbindungseinstellungen. (%s) + Keine Ergebnisse + Erneut drücken, um das Programm zu beenden + Wiedergabeliste + Wiedergabeliste \"%s\" wirklich löschen? + %s konnte nicht gelöscht werden + Verschiedene Interpreten + %1$s Titel, %2$s + %1$s Titel, %2$s + Zu einer Wiedergabeliste hinzufügen + (Neue Wiedergabeliste) + Wiedergabeliste + Name der neuen Wiedergabeliste: + Streams + Stream hinzufügen + Bearbeiten + Stream \"%s\" hinzugefügt + Lade Streams … + Stream \"%s\" gelöscht + Stream löschen + Stream \"%s\" wirklich löschen? + Name: + URL: + Genre \"%s\" hinzugefügt + Stopptaste anzeigen + Einzelmodus + Verbrauchsmodus + Albencover + Teiler Schaltfläche + Starte MPDroid + Menü-Schaltfläche + Element-Handle auflisten + Abspielen + Stopp + Album-Jahr anzeigen + Albumkünstler anzeigen + Audio-Eigenschaften anzeigen + Bewertungsleiste anzeigen + Stream starten + Stream stoppen + Verhalten bei Anruf + Wiedergabe pausieren + Wiedergabe bei Anruf pausieren + Wiedergabe fortsetzen + Wiedergabe fortsetzen, wenn Anruf beendet - Verhalten bei Anruf - Wiedergabe pausieren - Wiedergabe bei Anruf pausieren - Wiedergabe fortsetzen - Wiedergabe fortsetzen, wenn Anruf beendet + Bibliotheksansichten + Wähle die Bibliotheksansichten aus und bestimme deren Anordnung + Benutzte Ansichten + Unbenutzte Ansichten - Bibliotheksansichten - Wähle die Bibliotheksansichten aus und bestimme deren Anordnung - Benutzte Ansichten - Unbenutzte Ansichten + Albencovereinstellungen + Bestimmt, wie Albencover geladen und gespeichert werden + Albencover speichern + Speichert Albencover auf der SD-Karte zur schnelleren Anzeige + Leere Albencover-Cache + Lösche alle gespeicherten Albencover von der SD-Karte + Alle Albencover löschen? + Erneuere lokalen Alben-Cache - Albencovereinstellungen - Bestimmt, wie Albencover geladen und gespeichert werden - Albencover speichern - Speichert Albencover auf der SD-Karte zur schnelleren Anzeige - Leere Albencover-Cache - Lösche alle gespeicherten Albencover von der SD-Karte - Alle Albencover löschen? - Erneuere lokalen Alben-Cache + Große Albencoveransicht der Bibliothek + Experimentell, Programmabsturz möglich. Setzt Albencover-Cache voraus. - Große Albencoveransicht der Bibliothek - Experimentell, Programmabsturz möglich. Setzt Albencover-Cache voraus. + Gehe zum Album + Gehe zum Künstler + Gehe zum Albumkünstler + Gehe zum Verzeichnis + Gehe zu Streams + Gehe zum aktuellen Song + Anderes Cover + Bild zurücksetzen - Gehe zum Album - Gehe zum Künstler - Gehe zum Albumkünstler - Gehe zum Verzeichnis - Gehe zu Streams - Gehe zum aktuellen Song - Anderes Cover - Bild zurücksetzen + 1 Titel ausgewählt + %s Titel ausgewählt + Suche in Wiedergabeliste … + Nur über Wi-Fi laden + Albencover nicht über Telefonnetzwerk laden. Kann Netzwerkkosten reduzieren + Vor dem Beenden nachfragen + Zweimaliges Drücken der Zurück-Taste zum Beenden erforderlich + Benutze helles Theme + Weiterleiten + Wird abgespielt: + Tablet-Ansicht + Neustart erforderlich + Albencover + Cover über verschiedene Anbieter herunterladen (sendet Titel-Informationen) + GraceNote-Client-ID + GraceNote-Client-ID (XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) + Zeige drawer + Schließe drawer - 1 Titel ausgewählt - %s Titel ausgewählt - Suche in Wiedergabeliste … - Nur über Wi-Fi laden - Albencover nicht über Telefonnetzwerk laden. Kann Netzwerkkosten reduzieren - Vor dem Beenden nachfragen - Zweimaliges Drücken der Zurück-Taste zum Beenden erforderlich - Benutze helles Theme - Weiterleiten - Wird abgespielt: - Tablet-Ansicht - Neustart erforderlich - Albencover - Cover über verschiedene Anbieter herunterladen (sendet Titel-Informationen) - GraceNote-Client-ID - GraceNote-Client-ID (XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) - Zeige drawer - Schließe drawer + "Du hörst"-Einstellungen + Kleine Schieberegler + Suchhistorie löschen + Stream gespeichert - "Du hörst"-Einstellungen - Kleine Schieberegler - Suchhistorie löschen - Stream gespeichert + Autoren + Programmbibliotheken + Separator + Cover - Autoren - Programmbibliotheken - Separator - Cover + Aktion zum starten auswählen - Aktion zum starten auswählen + Benachrichtigung + Benachrichtigung schließen + Wiedergabe + Pause + Zum Anfang + Stumm + Lautstärke - Benachrichtigung - Benachrichtigung schließen - Wiedergabe - Pause - Zum Anfang - Stumm - Lautstärke + Zurücksetzen + Einfacher Modus + Wiedergabelisten-Management wie ein Standard-Player (sofortiges Ersetzen und Abspielen aus der Bibliothek heraus) + Zur Wiedergabeliste hinzufügen - Zurücksetzen - Einfacher Modus - Wiedergabelisten-Management wie ein Standard-Player (sofortiges Ersetzen und Abspielen aus der Bibliothek heraus) - Zur Wiedergabeliste hinzufügen + Beide + Album-Künstler + Künstler + Projekt-Logo + Tag für die Künstlerliste + Wähle den Tag aus, der für die Künstlerliste zuständig ist. Nützlich, um Künstler zu verstecken, die nur in Compilations vorhanden sind. + Dauerhafte Benachrichtigung + Setze die Benachrichtigung dauerhaft auf an für dieses Netzwerk + Hinzugefügte Titel nicht im Zufallsmodus abspielen. - Beide - Album-Künstler - Künstler - Projekt-Logo - Tag für die Künstlerliste - Wähle den Tag aus, der für die Künstlerliste zuständig ist. Nützlich, um Künstler zu verstecken, die nur in Compilations vorhanden sind. - Dauerhafte Benachrichtigung - Setze die Benachrichtigung dauerhaft auf an für dieses Netzwerk - Hinzugefügte Titel nicht im Zufallsmodus abspielen. + + Fehler beim Starten des Streams: Eine andere Anwendung spielt bereits Musik. + %1$s Stream Fehler: %2$s. + Fehler beim Vorbereiten des Streams: Der Server hat seinen Status geändert. + Fehler beim Setzen der Streamquelle: %1$s. + + + + Nicht spezifizierter Fehler vom Mediaplayer. + Medien-Server ist gestorben. + + Netzwerk bezogener Ablauffehler. + Der Stream folgt nicht kodierungs Standards. + Zeitüberschreitung. + Der Stream-Codec wird nicht unterstützt. + \ No newline at end of file From b9088d318fd412efa8de5fd42bbf9a434ad5854b Mon Sep 17 00:00:00 2001 From: MaDill Date: Wed, 12 Nov 2014 17:46:49 +0100 Subject: [PATCH 22/33] changed tab to 4 blanks --- MPDroid/src/main/res/values-de/strings.xml | 572 ++++++++++----------- 1 file changed, 286 insertions(+), 286 deletions(-) diff --git a/MPDroid/src/main/res/values-de/strings.xml b/MPDroid/src/main/res/values-de/strings.xml index f7ed63b663..4172503ff9 100644 --- a/MPDroid/src/main/res/values-de/strings.xml +++ b/MPDroid/src/main/res/values-de/strings.xml @@ -2,306 +2,306 @@ - + - MPDroid - Künstler - Genres - Wiedergabelisten - Dateien - Alben - Einstellungen - Nächster - Vorheriger - OK - Beenden - Wiederholen - Lade … - Lade Genres … - Lade Alben … - Lade Künstler … - Lade Titel … - Lade Wiedergabelisten … - Wiedergabeliste - Hinzufügen und ersetzen - Hinzufügen, ersetzen und abspielen - Album hinzufügen - Wiedergabeliste hinzufügen - Hinzufügen und abspielen - Künstler hinzufügen - Genre hinzufügen - Hinzufügen - Titel hinzufügen - Titel entfernen - Titel beschneiden - %s Titel entfernt - Leeren - Hauptmenü - Wiedergabeliste geleert - Titel von Wiedergabeliste entfernt - Album \"%s\" hinzugefügt - Wiedergabeliste \"%s\" hinzugefügt - Verzeichnis zur Wiedergabeliste hinzugefügt - Künstler \"%s\" hinzugefügt - Host - MPD-Server-Hostname oder IP-Adresse - Streaming-Host - Streaming-Server (Hostname oder IP-Adresse) - Port - MPD-Server-Port (Standard: 6600) - Passwort - Passwort für den Server - Version - Titel - Server-Informationen - Diverse MPD-Server-Informationen wie Version, Anzahl Stücke … - Verbindungseinstellungen - Setze MPD-Host/Port und Passwort - Ausgänge - Ansichtseinstellungen - Bibliothekseinstellungen - Titel \"%s\" hinzugefügt - Über - Verbindung fehlgeschlagen - Die Verbindung zum MPD-Server ist fehlgeschlagen! Bitte überprüfen Sie, ob der Server läuft und erreichbar ist. (%s) - Verbinde - Verbinde … - Verbinde mit MPD-Server. - Verbunden - Nicht verbunden - Keine Informationen für diesen Titel - Nicht in Reichweite, gespeichert - Wiedergabeliste \"%s\" gelöscht - Wiedergabeliste löschen - Standard-Verbindung - Bevorzugte Verbindung - WLAN-Netzwerk wählen - WLAN-basierte Verbindung - Standard-Verbindung - WLAN-basiert den MPD-Host/Port und das Passwort definieren - Standard-MPD-Host/Port und das Passwort definieren - Streaming - Zwischenspeichern … - Streaming-Port - MPD-Streaming-Port (Standard: 8000) - Streaming-URL-Suffix - Dateiendung für Stream-URL (z.B. mpd.mp3) - MPDroid ist Open Source. Quelltext unter http://github.com/abarisain/dmix - MPDroid ist ein Fork von PMix\n (http://code.google.com/p/pmix/). Bedanke dich! - Suchen - MPDroid - Suchen … - Bibliothek - Bitte lesen - Willkommen bei MPDroid 1.0!\nDiese Meldung wird nur einmal angezeigt.\n\nZuerst: Falls Sie nicht wissen, was ein MPD-Server ist, sollten Sie diese App wieder deinstallieren. Sie ist nichts für Sie.\nWichtig! Bekannter Fehler: Das Widget stürzt manchmal ab oder erhöht den Batterieverbrauch.\n\nFür Benutzer der alten Version: Vielen Dank für Ihre Unterstützung und Mitarbeit. Ich hoffe wirklich, dass Ihnen diese neue MPDroid-Version gefällt. Sie können mir gerne per E-Mail mitteilen, was Ihnen gefällt oder auch nicht gefällt :)\nDie alte Version gibt es noch auf meiner Github-Seite. - Bearbeiten - Du hörst - Abbrechen - Als Nächstes einordnen - Gehe zu … - An den Anfang verschieben - Ans Ende verschieben - Von der Wiedergabeliste entfernen - Album entfernen - Speichern - Aktualisiere die MPD-Datenbank - Album-Cache verwenden - Teile der MPD-Datenbank lokal speichern - Erscheinungsjahr - Sortiere Alben nach Erscheinungsjahr - Titelanzahl anzeigen - Zeige Titelanzahl der Alben - Lokale Albencover laden - Albencover vom MPD-Server laden (Erfordert einen Webserver, siehe Wiki) - Musikverzeichnis - Musikverzeichnis auf dem MPD-Server z.B. files/mp3 (music/ für Vortexbox-Benutzer). Für aufwendige Einstellungen können auch absolute Pfade (z.B. "http://ip:port/music") verwendet werden. - Albencover-Datei - Dateiname der Albencover z.B. folder.jpg (cover.jpg für Vortexbox-Benutzer) - Belegter Cache-Speicher - Diesen Server löschen - Original App-Logo von Asher (http://kyo-tux.deviantart.com/) und brsev (http://brsev.deviantart.com/), bearbeitet für MPDroid. - Die Verbindung zum MPD-Server ist fehlgeschlagen! Prüfen Sie die Verbindungseinstellungen. (%s) - Keine Ergebnisse - Erneut drücken, um das Programm zu beenden - Wiedergabeliste - Wiedergabeliste \"%s\" wirklich löschen? - %s konnte nicht gelöscht werden - Verschiedene Interpreten - %1$s Titel, %2$s - %1$s Titel, %2$s - Zu einer Wiedergabeliste hinzufügen - (Neue Wiedergabeliste) - Wiedergabeliste - Name der neuen Wiedergabeliste: - Streams - Stream hinzufügen - Bearbeiten - Stream \"%s\" hinzugefügt - Lade Streams … - Stream \"%s\" gelöscht - Stream löschen - Stream \"%s\" wirklich löschen? - Name: - URL: - Genre \"%s\" hinzugefügt - Stopptaste anzeigen - Einzelmodus - Verbrauchsmodus - Albencover - Teiler Schaltfläche - Starte MPDroid - Menü-Schaltfläche - Element-Handle auflisten - Abspielen - Stopp - Album-Jahr anzeigen - Albumkünstler anzeigen - Audio-Eigenschaften anzeigen - Bewertungsleiste anzeigen - Stream starten - Stream stoppen + MPDroid + Künstler + Genres + Wiedergabelisten + Dateien + Alben + Einstellungen + Nächster + Vorheriger + OK + Beenden + Wiederholen + Lade … + Lade Genres … + Lade Alben … + Lade Künstler … + Lade Titel … + Lade Wiedergabelisten … + Wiedergabeliste + Hinzufügen und ersetzen + Hinzufügen, ersetzen und abspielen + Album hinzufügen + Wiedergabeliste hinzufügen + Hinzufügen und abspielen + Künstler hinzufügen + Genre hinzufügen + Hinzufügen + Titel hinzufügen + Titel entfernen + Titel beschneiden + %s Titel entfernt + Leeren + Hauptmenü + Wiedergabeliste geleert + Titel von Wiedergabeliste entfernt + Album \"%s\" hinzugefügt + Wiedergabeliste \"%s\" hinzugefügt + Verzeichnis zur Wiedergabeliste hinzugefügt + Künstler \"%s\" hinzugefügt + Host + MPD-Server-Hostname oder IP-Adresse + Streaming-Host + Streaming-Server (Hostname oder IP-Adresse) + Port + MPD-Server-Port (Standard: 6600) + Passwort + Passwort für den Server + Version + Titel + Server-Informationen + Diverse MPD-Server-Informationen wie Version, Anzahl Stücke … + Verbindungseinstellungen + Setze MPD-Host/Port und Passwort + Ausgänge + Ansichtseinstellungen + Bibliothekseinstellungen + Titel \"%s\" hinzugefügt + Über + Verbindung fehlgeschlagen + Die Verbindung zum MPD-Server ist fehlgeschlagen! Bitte überprüfen Sie, ob der Server läuft und erreichbar ist. (%s) + Verbinde + Verbinde … + Verbinde mit MPD-Server. + Verbunden + Nicht verbunden + Keine Informationen für diesen Titel + Nicht in Reichweite, gespeichert + Wiedergabeliste \"%s\" gelöscht + Wiedergabeliste löschen + Standard-Verbindung + Bevorzugte Verbindung + WLAN-Netzwerk wählen + WLAN-basierte Verbindung + Standard-Verbindung + WLAN-basiert den MPD-Host/Port und das Passwort definieren + Standard-MPD-Host/Port und das Passwort definieren + Streaming + Zwischenspeichern … + Streaming-Port + MPD-Streaming-Port (Standard: 8000) + Streaming-URL-Suffix + Dateiendung für Stream-URL (z.B. mpd.mp3) + MPDroid ist Open Source. Quelltext unter http://github.com/abarisain/dmix + MPDroid ist ein Fork von PMix\n (http://code.google.com/p/pmix/). Bedanke dich! + Suchen + MPDroid + Suchen … + Bibliothek + Bitte lesen + Willkommen bei MPDroid 1.0!\nDiese Meldung wird nur einmal angezeigt.\n\nZuerst: Falls Sie nicht wissen, was ein MPD-Server ist, sollten Sie diese App wieder deinstallieren. Sie ist nichts für Sie.\nWichtig! Bekannter Fehler: Das Widget stürzt manchmal ab oder erhöht den Batterieverbrauch.\n\nFür Benutzer der alten Version: Vielen Dank für Ihre Unterstützung und Mitarbeit. Ich hoffe wirklich, dass Ihnen diese neue MPDroid-Version gefällt. Sie können mir gerne per E-Mail mitteilen, was Ihnen gefällt oder auch nicht gefällt :)\nDie alte Version gibt es noch auf meiner Github-Seite. + Bearbeiten + Du hörst + Abbrechen + Als Nächstes einordnen + Gehe zu … + An den Anfang verschieben + Ans Ende verschieben + Von der Wiedergabeliste entfernen + Album entfernen + Speichern + Aktualisiere die MPD-Datenbank + Album-Cache verwenden + Teile der MPD-Datenbank lokal speichern + Erscheinungsjahr + Sortiere Alben nach Erscheinungsjahr + Titelanzahl anzeigen + Zeige Titelanzahl der Alben + Lokale Albencover laden + Albencover vom MPD-Server laden (Erfordert einen Webserver, siehe Wiki) + Musikverzeichnis + Musikverzeichnis auf dem MPD-Server z.B. files/mp3 (music/ für Vortexbox-Benutzer). Für aufwendige Einstellungen können auch absolute Pfade (z.B. "http://ip:port/music") verwendet werden. + Albencover-Datei + Dateiname der Albencover z.B. folder.jpg (cover.jpg für Vortexbox-Benutzer) + Belegter Cache-Speicher + Diesen Server löschen + Original App-Logo von Asher (http://kyo-tux.deviantart.com/) und brsev (http://brsev.deviantart.com/), bearbeitet für MPDroid. + Die Verbindung zum MPD-Server ist fehlgeschlagen! Prüfen Sie die Verbindungseinstellungen. (%s) + Keine Ergebnisse + Erneut drücken, um das Programm zu beenden + Wiedergabeliste + Wiedergabeliste \"%s\" wirklich löschen? + %s konnte nicht gelöscht werden + Verschiedene Interpreten + %1$s Titel, %2$s + %1$s Titel, %2$s + Zu einer Wiedergabeliste hinzufügen + (Neue Wiedergabeliste) + Wiedergabeliste + Name der neuen Wiedergabeliste: + Streams + Stream hinzufügen + Bearbeiten + Stream \"%s\" hinzugefügt + Lade Streams … + Stream \"%s\" gelöscht + Stream löschen + Stream \"%s\" wirklich löschen? + Name: + URL: + Genre \"%s\" hinzugefügt + Stopptaste anzeigen + Einzelmodus + Verbrauchsmodus + Albencover + Teiler Schaltfläche + Starte MPDroid + Menü-Schaltfläche + Element-Handle auflisten + Abspielen + Stopp + Album-Jahr anzeigen + Albumkünstler anzeigen + Audio-Eigenschaften anzeigen + Bewertungsleiste anzeigen + Stream starten + Stream stoppen - Verhalten bei Anruf - Wiedergabe pausieren - Wiedergabe bei Anruf pausieren - Wiedergabe fortsetzen - Wiedergabe fortsetzen, wenn Anruf beendet + Verhalten bei Anruf + Wiedergabe pausieren + Wiedergabe bei Anruf pausieren + Wiedergabe fortsetzen + Wiedergabe fortsetzen, wenn Anruf beendet - Bibliotheksansichten - Wähle die Bibliotheksansichten aus und bestimme deren Anordnung - Benutzte Ansichten - Unbenutzte Ansichten + Bibliotheksansichten + Wähle die Bibliotheksansichten aus und bestimme deren Anordnung + Benutzte Ansichten + Unbenutzte Ansichten - Albencovereinstellungen - Bestimmt, wie Albencover geladen und gespeichert werden - Albencover speichern - Speichert Albencover auf der SD-Karte zur schnelleren Anzeige - Leere Albencover-Cache - Lösche alle gespeicherten Albencover von der SD-Karte - Alle Albencover löschen? - Erneuere lokalen Alben-Cache + Albencovereinstellungen + Bestimmt, wie Albencover geladen und gespeichert werden + Albencover speichern + Speichert Albencover auf der SD-Karte zur schnelleren Anzeige + Leere Albencover-Cache + Lösche alle gespeicherten Albencover von der SD-Karte + Alle Albencover löschen? + Erneuere lokalen Alben-Cache - Große Albencoveransicht der Bibliothek - Experimentell, Programmabsturz möglich. Setzt Albencover-Cache voraus. + Große Albencoveransicht der Bibliothek + Experimentell, Programmabsturz möglich. Setzt Albencover-Cache voraus. - Gehe zum Album - Gehe zum Künstler - Gehe zum Albumkünstler - Gehe zum Verzeichnis - Gehe zu Streams - Gehe zum aktuellen Song - Anderes Cover - Bild zurücksetzen + Gehe zum Album + Gehe zum Künstler + Gehe zum Albumkünstler + Gehe zum Verzeichnis + Gehe zu Streams + Gehe zum aktuellen Song + Anderes Cover + Bild zurücksetzen - 1 Titel ausgewählt - %s Titel ausgewählt - Suche in Wiedergabeliste … - Nur über Wi-Fi laden - Albencover nicht über Telefonnetzwerk laden. Kann Netzwerkkosten reduzieren - Vor dem Beenden nachfragen - Zweimaliges Drücken der Zurück-Taste zum Beenden erforderlich - Benutze helles Theme - Weiterleiten - Wird abgespielt: - Tablet-Ansicht - Neustart erforderlich - Albencover - Cover über verschiedene Anbieter herunterladen (sendet Titel-Informationen) - GraceNote-Client-ID - GraceNote-Client-ID (XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) - Zeige drawer - Schließe drawer + 1 Titel ausgewählt + %s Titel ausgewählt + Suche in Wiedergabeliste … + Nur über Wi-Fi laden + Albencover nicht über Telefonnetzwerk laden. Kann Netzwerkkosten reduzieren + Vor dem Beenden nachfragen + Zweimaliges Drücken der Zurück-Taste zum Beenden erforderlich + Benutze helles Theme + Weiterleiten + Wird abgespielt: + Tablet-Ansicht + Neustart erforderlich + Albencover + Cover über verschiedene Anbieter herunterladen (sendet Titel-Informationen) + GraceNote-Client-ID + GraceNote-Client-ID (XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) + Zeige drawer + Schließe drawer - "Du hörst"-Einstellungen - Kleine Schieberegler - Suchhistorie löschen - Stream gespeichert + "Du hörst"-Einstellungen + Kleine Schieberegler + Suchhistorie löschen + Stream gespeichert - Autoren - Programmbibliotheken - Separator - Cover + Autoren + Programmbibliotheken + Separator + Cover - Aktion zum starten auswählen + Aktion zum starten auswählen - Benachrichtigung - Benachrichtigung schließen - Wiedergabe - Pause - Zum Anfang - Stumm - Lautstärke + Benachrichtigung + Benachrichtigung schließen + Wiedergabe + Pause + Zum Anfang + Stumm + Lautstärke - Zurücksetzen - Einfacher Modus - Wiedergabelisten-Management wie ein Standard-Player (sofortiges Ersetzen und Abspielen aus der Bibliothek heraus) - Zur Wiedergabeliste hinzufügen + Zurücksetzen + Einfacher Modus + Wiedergabelisten-Management wie ein Standard-Player (sofortiges Ersetzen und Abspielen aus der Bibliothek heraus) + Zur Wiedergabeliste hinzufügen - Beide - Album-Künstler - Künstler - Projekt-Logo - Tag für die Künstlerliste - Wähle den Tag aus, der für die Künstlerliste zuständig ist. Nützlich, um Künstler zu verstecken, die nur in Compilations vorhanden sind. - Dauerhafte Benachrichtigung - Setze die Benachrichtigung dauerhaft auf an für dieses Netzwerk - Hinzugefügte Titel nicht im Zufallsmodus abspielen. + Beide + Album-Künstler + Künstler + Projekt-Logo + Tag für die Künstlerliste + Wähle den Tag aus, der für die Künstlerliste zuständig ist. Nützlich, um Künstler zu verstecken, die nur in Compilations vorhanden sind. + Dauerhafte Benachrichtigung + Setze die Benachrichtigung dauerhaft auf an für dieses Netzwerk + Hinzugefügte Titel nicht im Zufallsmodus abspielen. - - Fehler beim Starten des Streams: Eine andere Anwendung spielt bereits Musik. - %1$s Stream Fehler: %2$s. - Fehler beim Vorbereiten des Streams: Der Server hat seinen Status geändert. - Fehler beim Setzen der Streamquelle: %1$s. - + + Fehler beim Starten des Streams: Eine andere Anwendung spielt bereits Musik. + %1$s Stream Fehler: %2$s. + Fehler beim Vorbereiten des Streams: Der Server hat seinen Status geändert. + Fehler beim Setzen der Streamquelle: %1$s. + - - Nicht spezifizierter Fehler vom Mediaplayer. - Medien-Server ist gestorben. + + Nicht spezifizierter Fehler vom Mediaplayer. + Medien-Server ist gestorben. - Netzwerk bezogener Ablauffehler. - Der Stream folgt nicht kodierungs Standards. - Zeitüberschreitung. - Der Stream-Codec wird nicht unterstützt. - + Netzwerk bezogener Ablauffehler. + Der Stream folgt nicht kodierungs Standards. + Zeitüberschreitung. + Der Stream-Codec wird nicht unterstützt. + \ No newline at end of file From c677564c68c1539729691eea8581511280bc5b35 Mon Sep 17 00:00:00 2001 From: MaDill Date: Wed, 12 Nov 2014 17:49:09 +0100 Subject: [PATCH 23/33] corrected some hyphen --- MPDroid/src/main/res/values-de/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MPDroid/src/main/res/values-de/strings.xml b/MPDroid/src/main/res/values-de/strings.xml index 4172503ff9..61d8f6c18a 100644 --- a/MPDroid/src/main/res/values-de/strings.xml +++ b/MPDroid/src/main/res/values-de/strings.xml @@ -6,8 +6,8 @@ Über MPDroid Wi-Fi nicht verfügbar, es werden keine neuen Bilder empfangen Konfigurationsname - Albencover Einstellungen - Client Einstellungen + Albencover-Einstellungen + Client-Einstellungen Ändern Benutze helles Theme für "Du hörst" Starte die App neu, um Änderung anzuwenden @@ -22,8 +22,8 @@ Endlosschleife Aktiviere/Deaktiviere Endlosschleife L - Server Adresse: - Server Einstellungen + Server-Adresse: + Server-Einstellungen Hierhin springen Beendet Streamdetails: @@ -304,4 +304,4 @@ Zeitüberschreitung. Der Stream-Codec wird nicht unterstützt. - \ No newline at end of file + From d4aa760f61bfe9205633ed095181d51d0aa36291 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Thu, 13 Nov 2014 15:02:37 -0800 Subject: [PATCH 24/33] NowPlayingFragment: Only set rating visibility on init, connection and config. Setting the rating visibility was happening per track change, now we only change it on initialization, connection and if the config option changes. --- .../mpdroid/fragments/NowPlayingFragment.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/NowPlayingFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/NowPlayingFragment.java index 451cd7a7d9..8cc1f57b84 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/NowPlayingFragment.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/NowPlayingFragment.java @@ -313,6 +313,7 @@ private void forceStatusUpdate() { updateTrackInfo(status, true); setButtonAttribute(getRepeatAttribute(status.isRepeat()), mRepeatButton); setButtonAttribute(getShuffleAttribute(status.isRandom()), mShuffleButton); + setStickerVisibility(); } } @@ -804,6 +805,10 @@ public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, mIsAudioNameTextEnabled = sharedPreferences.getBoolean(key, false); updateAudioNameText(mApp.oMPDAsyncHelper.oMPD.getStatus()); break; + case "enableRating": + setStickerVisibility(); + updateTrackInfo(mApp.oMPDAsyncHelper.oMPD.getStatus(), false); + break; default: break; } @@ -902,6 +907,14 @@ private void setButtonAttribute(@AttrRes final int attribute, final ImageButton ta.recycle(); } + private void setStickerVisibility() { + if (mApp.oMPDAsyncHelper.oMPD.getStickerManager().isAvailable()) { + applyViewVisibility(mSongRating, "enableRating"); + } else { + mSongRating.setVisibility(View.GONE); + } + } + private void startPosTimer(final long start, final long total) { stopPosTimer(); mPosTimer = new Timer(); @@ -958,12 +971,6 @@ private void toggleTrackProgress(final MPDStatus status) { updateTrackProgress(elapsedTime, totalTime); } - if (mApp.oMPDAsyncHelper.oMPD.getStickerManager().isAvailable()) { - applyViewVisibility(mSongRating, "enableRating"); - } else { - mSongRating.setVisibility(View.GONE); - } - mTrackSeekBar.setMax((int) totalTime); mTrackTime.setVisibility(View.VISIBLE); From 8346b5a4d0bfc15da5e72b9d86946295176fe98c Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Thu, 13 Nov 2014 15:06:05 -0800 Subject: [PATCH 25/33] UpdateTrackInfo: Only attempt rating retrival if the config option is set. --- .../java/com/namelessdev/mpdroid/helpers/UpdateTrackInfo.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/helpers/UpdateTrackInfo.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/helpers/UpdateTrackInfo.java index 5d654f2ba4..ccdc848be2 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/helpers/UpdateTrackInfo.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/helpers/UpdateTrackInfo.java @@ -212,7 +212,8 @@ protected final Void doInBackground(final MPDStatus... params) { private float getTrackRating() { float rating = 0.0f; - if (mCurrentTrack != null && mSticker.isAvailable()) { + if (mCurrentTrack != null && mSticker.isAvailable() && + mSettings.getBoolean("enableRating", false)) { try { rating = (float) mSticker.getRating(mCurrentTrack) / 2.0f; } catch (final IOException | MPDException e) { From 9258d7aa536dde88871d4a089958d7b85d5aa3c2 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Fri, 14 Nov 2014 10:16:17 -0800 Subject: [PATCH 26/33] dmix: Final cleanup to try to fix null responses. --- .../org/a0z/mpd/connection/CommandResult.java | 52 +++++----- .../org/a0z/mpd/connection/MPDConnection.java | 98 +++++++++---------- 2 files changed, 67 insertions(+), 83 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/connection/CommandResult.java b/JMPDComm/src/main/java/org/a0z/mpd/connection/CommandResult.java index ac97aff9fb..55dba40f6b 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/connection/CommandResult.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/connection/CommandResult.java @@ -37,18 +37,16 @@ /** This class stores the result for MPDCallable. */ class CommandResult { + private Boolean isIOExceptionLast = null; + private String mConnectionResult; private IOException mIOException; - private MPDException mLastException; + private MPDException mMPDException; private List mResult; - final IOException getIOException() { - return mIOException; - } - /** * Returns the first string response from the media server after connection. This method is * mainly for debugging. @@ -60,20 +58,12 @@ public String getConnectionResult() { return mConnectionResult; } - final MPDException getLastException() { - return mLastException; + final IOException getIOException() { + return mIOException; } - public boolean isHeaderValid() { - final boolean isHeaderValid; - - if (mConnectionResult == null) { - isHeaderValid = false; - } else { - isHeaderValid = true; - } - - return isHeaderValid; + final MPDException getMPDException() { + return mMPDException; } /** @@ -104,30 +94,34 @@ final List getResult() { return mResult; } - final boolean isMPDException() { - final boolean isMPDException; + public boolean isHeaderValid() { + final boolean isHeaderValid; - if (mLastException == null) { - isMPDException = false; + if (mConnectionResult == null) { + isHeaderValid = false; } else { - isMPDException = true; + isHeaderValid = true; } - return isMPDException; + return isHeaderValid; + } + + public Boolean isIOExceptionLast() { + return isIOExceptionLast; } final void setConnectionResult(final String result) { mConnectionResult = result; } - final void setException(final IOException ioException) { - mLastException = null; - mIOException = ioException; + final void setException(final IOException exception) { + isIOExceptionLast = Boolean.TRUE; + mIOException = exception; } - final void setException(final MPDException lastException) { - mIOException = null; - mLastException = lastException; + final void setException(final MPDException exception) { + isIOExceptionLast = Boolean.FALSE; + mMPDException = exception; } final void setResult(final List result) { diff --git a/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java b/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java index 0d47929e21..a3b27b2fcf 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/connection/MPDConnection.java @@ -41,7 +41,6 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; -import java.net.SocketException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -60,6 +59,8 @@ */ public abstract class MPDConnection { + static final String MPD_RESPONSE_OK = "OK"; + private static final int CONNECTION_TIMEOUT = 10000; /** The debug flag to enable or disable debug logging output. */ @@ -73,12 +74,8 @@ public abstract class MPDConnection { private static final String MPD_RESPONSE_ERR = "ACK"; - static final String MPD_RESPONSE_OK = "OK"; - private static final String POOL_THREAD_NAME_PREFIX = "pool"; - private final String mTag; - /** A set containing all available commands, populated on connection. */ private final Collection mAvailableCommands = new HashSet<>(); @@ -91,6 +88,8 @@ public abstract class MPDConnection { /** The command communication timeout. */ private final int mReadWriteTimeout; + private final String mTag; + /** If set to true, this will cancel any processing commands at next opportunity. */ private boolean mCancelled = false; @@ -98,7 +97,7 @@ public abstract class MPDConnection { private boolean mIsConnected = false; /** Current media server's major/minor/micro version. */ - private int[] mMPDVersion = { 0, 0, 0 }; + private int[] mMPDVersion = {0, 0, 0}; /** Current media server password. */ private String mPassword = null; @@ -307,26 +306,21 @@ private CommandResult processCommand(final MPDCommand command) } if (result.getResult() == null) { - if (result.isMPDException()) { - throw result.getLastException(); - } else { - final IOException e = result.getIOException(); - - if (e == null) { - /** - * This should not occur, and this exception should extend RuntimeException, - * BUT a RuntimeException would most likely not help the situation. - */ - throw new IOException( - "No result, no exception. This is a bug. Please report." + '\n' + - "Cancelled: " + mCancelled + '\n' + - "Command: " + command + '\n' + - "Connected: " + mIsConnected + '\n' + - "Connection result: " + result.getConnectionResult() + '\n'); - } else { - /** Don't throw if it's just about a cancelled command. That's expected. */ - throw e; - } + if (result.isIOExceptionLast() == null) { + /** + * This should not occur, and this exception should extend RuntimeException, + * BUT a RuntimeException would most likely not help the situation. + */ + throw new IOException( + "No result, no exception. This is a bug. Please report." + '\n' + + "Cancelled: " + mCancelled + '\n' + + "Command: " + command + '\n' + + "Connected: " + mIsConnected + '\n' + + "Connection result: " + result.getConnectionResult() + '\n'); + } else if (result.isIOExceptionLast().equals(Boolean.TRUE)) { + throw result.getIOException(); + } else if (result.isIOExceptionLast().equals(Boolean.FALSE)) { + throw result.getMPDException(); } } @@ -456,34 +450,6 @@ public final CommandResult call() { return result; } - private void logError(final CommandResult result, final String baseCommand, - final int retryCount) { - final StringBuilder stringBuilder = new StringBuilder(50); - - stringBuilder.append("Command "); - stringBuilder.append(baseCommand); - stringBuilder.append(" failed after "); - stringBuilder.append(retryCount + 1); - - if (retryCount == 0) { - stringBuilder.append(" attempt."); - } else { - stringBuilder.append(" attempts."); - } - - if (result.isMPDException()) { - Log.error(mTag, stringBuilder.toString(), result.getLastException()); - } else { - final IOException e = result.getIOException(); - - /** Don't log if it's just about a cancelled command. That's expected. */ - if (!(mCancelled && e instanceof SocketException && - baseCommand.contains(MPDCommand.MPD_CMD_IDLE))) { - Log.error(mTag, stringBuilder.toString(), e); - } - } - } - /** * Used after a server error, sleeps for a small time then tries to reconnect. * @@ -599,6 +565,30 @@ private boolean isNonfatalACK(final String message) { return isNonfatalACK; } + private void logError(final CommandResult result, final String baseCommand, + final int retryCount) { + final StringBuilder stringBuilder = new StringBuilder(50); + + stringBuilder.append("Command "); + stringBuilder.append(baseCommand); + stringBuilder.append(" failed after "); + stringBuilder.append(retryCount + 1); + + if (retryCount == 0) { + stringBuilder.append(" attempt."); + } else { + stringBuilder.append(" attempts."); + } + + if (result.isIOExceptionLast() == null) { + Log.error(mTag, stringBuilder.toString()); + } else if (result.isIOExceptionLast().equals(Boolean.TRUE)) { + Log.error(mTag, stringBuilder.toString(), result.getIOException()); + } else if (result.isIOExceptionLast().equals(Boolean.FALSE)) { + Log.error(mTag, stringBuilder.toString(), result.getMPDException()); + } + } + /** * Read the server response after a {@code write()} to the server. * From b8bae196c1e91a05ff40bd247ae2c966e39a50a9 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Sun, 16 Nov 2014 16:03:47 -0800 Subject: [PATCH 27/33] MPDStatusMonitor: Don't wait() when connected. In certain cases, an idle subsystem update event can be skipped due to a wait() used to keep from looping (and subsequently eating too much CPU) too often during disconnection. Now, we only only wait() when disconnected. This is a stop gap fix until this class is rewritten. --- JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java b/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java index 5719e1966f..54cfa8806c 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java @@ -316,14 +316,16 @@ public void run() { Log.error(TAG, "Exception caught while looping.", e); } } + try { synchronized (this) { - wait(mDelay); + if (!mMPD.isConnected()) { + wait(mDelay); + } } } catch (final InterruptedException e) { - e.printStackTrace(); + Log.error(TAG, "Interruption caught during disconnection and wait.", e); } - } } From 1609b7141e8440e16cbc47860116864bd12fa65e Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Sun, 16 Nov 2014 16:24:01 -0800 Subject: [PATCH 28/33] MPDApplication: Suppress exception if a disconnection timer is cancelled. We received an automated crash report that an exception caused a crash due to a disconnection timer cancellation. This is not a problem as this is part of the normal course of operations. Log and suppress this exception. --- .../namelessdev/mpdroid/MPDApplication.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/MPDApplication.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/MPDApplication.java index 35c652d8a0..a70cf4c626 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/MPDApplication.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/MPDApplication.java @@ -485,14 +485,18 @@ public final void setupServiceBinder() { } private void startDisconnectScheduler() { - mDisconnectScheduler.schedule(new TimerTask() { - @Override - public void run() { - Log.w(TAG, "Disconnecting (" + DISCONNECT_TIMER + " ms timeout)"); - oMPDAsyncHelper.stopStatusMonitor(); - oMPDAsyncHelper.disconnect(); - } - }, DISCONNECT_TIMER); + try { + mDisconnectScheduler.schedule(new TimerTask() { + @Override + public void run() { + Log.w(TAG, "Disconnecting (" + DISCONNECT_TIMER + " ms timeout)"); + oMPDAsyncHelper.stopStatusMonitor(); + oMPDAsyncHelper.disconnect(); + } + }, DISCONNECT_TIMER); + } catch (final IllegalStateException e) { + Log.d(TAG, "Disconnection timer interrupted.", e); + } } public final void startNotification() { From 3cf352fc7342d67b70bd4f59aaea73d4dd581f6d Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Mon, 17 Nov 2014 18:09:44 -0800 Subject: [PATCH 29/33] dmix: Code style. --- JMPDComm/src/main/java/org/a0z/mpd/MPD.java | 2 +- .../src/main/java/org/a0z/mpd/MusicList.java | 2 +- JMPDComm/src/main/java/org/a0z/mpd/Tools.java | 2 +- MPDroid/src/main/AndroidManifest.xml | 1 + .../namelessdev/mpdroid/SearchActivity.java | 8 +- .../mpdroid/fragments/ArtistsFragment.java | 4 +- .../src/main/res/layout-v21/notification.xml | 3 +- .../main/res/layout-v21/notification_big.xml | 5 +- MPDroid/src/main/res/values-de/strings.xml | 4 +- MPDroid/src/main/res/values-ko/strings.xml | 596 +++++++++--------- 10 files changed, 313 insertions(+), 314 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java index cd49da44fd..7fab1c89b4 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPD.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPD.java @@ -591,7 +591,7 @@ protected void fixAlbumArtists(final List albums) { .isEmpty()) { // one albumartist, fix this // album final Artist artist = new Artist(aartists[0]); - final Album newAlbum = new Album(album, artist, true); + final Album newAlbum = new Album(album, artist, true); albums.set(i, newAlbum); } // do nothing if albumartist is "" if (aartists.length > 1) { // it's more than one album, insert diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MusicList.java b/JMPDComm/src/main/java/org/a0z/mpd/MusicList.java index da6ad2269a..12e2d89f0e 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MusicList.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MusicList.java @@ -110,7 +110,7 @@ private void add(final Music music) { * @return a Music with given songId or {@code null} if it is not * present on this {@code MusicList}. */ - Music getById(final int songId) { + Music getById(final int songId) { final int songPos = Integer.valueOf(mSongID.indexOf(songId)); return mList.get(songPos); diff --git a/JMPDComm/src/main/java/org/a0z/mpd/Tools.java b/JMPDComm/src/main/java/org/a0z/mpd/Tools.java index c2a48136d9..4457a25215 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/Tools.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/Tools.java @@ -169,7 +169,7 @@ public static boolean isNotEqual(final int[][] arrays) { * Parse a media server response for one entry type. * * @param response The media server response. - * @param type The entry type in the response to add to the collection. + * @param type The entry type in the response to add to the collection. * @return A collection of entries of one type in a media server response. */ public static List parseResponse(final Collection response, final String type) { diff --git a/MPDroid/src/main/AndroidManifest.xml b/MPDroid/src/main/AndroidManifest.xml index ded136df5c..547d908351 100644 --- a/MPDroid/src/main/AndroidManifest.xml +++ b/MPDroid/src/main/AndroidManifest.xml @@ -55,6 +55,7 @@ + diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/SearchActivity.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/SearchActivity.java index 3b3d6618aa..8d572ea2c4 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/SearchActivity.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/SearchActivity.java @@ -76,9 +76,10 @@ public class SearchActivity extends MPDroidActivity implements OnMenuItemClickLi public static final int PLAYLIST = 3; - private static final String TAG = "SearchActivity"; + private static final String PLAY_SERVICES_ACTION_SEARCH + = "com.google.android.gms.actions.SEARCH_ACTION"; - private static final String PLAY_SERVICES_ACTION_SEARCH = "com.google.android.gms.actions.SEARCH_ACTION"; + private static final String TAG = "SearchActivity"; private final ArrayList mAlbumResults; @@ -329,7 +330,8 @@ public void onPageSelected(final int position) { final Intent queryIntent = getIntent(); final String queryAction = queryIntent.getAction(); - if (Intent.ACTION_SEARCH.equals(queryAction) || PLAY_SERVICES_ACTION_SEARCH.equals(queryAction)) { + if (Intent.ACTION_SEARCH.equals(queryAction) || PLAY_SERVICES_ACTION_SEARCH + .equals(queryAction)) { mSearchKeywords = queryIntent.getStringExtra(SearchManager.QUERY).trim(); final SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, SearchRecentProvider.AUTHORITY, SearchRecentProvider.MODE); diff --git a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/ArtistsFragment.java b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/ArtistsFragment.java index 97b575247c..18d4c20a37 100644 --- a/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/ArtistsFragment.java +++ b/MPDroid/src/main/java/com/namelessdev/mpdroid/fragments/ArtistsFragment.java @@ -39,10 +39,10 @@ public class ArtistsFragment extends BrowseFragment { - private static final String TAG = "ArtistsFragment"; - private static final String EXTRA_GENRE = "genre"; + private static final String TAG = "ArtistsFragment"; + private Genre mGenre = null; public ArtistsFragment() { diff --git a/MPDroid/src/main/res/layout-v21/notification.xml b/MPDroid/src/main/res/layout-v21/notification.xml index 0e85cb91e2..221ecba636 100644 --- a/MPDroid/src/main/res/layout-v21/notification.xml +++ b/MPDroid/src/main/res/layout-v21/notification.xml @@ -1,5 +1,4 @@ - - - - + - - MPDroid - 연주자 - 장르 - 연주목록 - 파일 - 음반 - 설정 - 다음 곡 - 이전 곡 - 확인 - 나가기 - 다시 시도 - 불러오는 중… - 장르 불러오는 중… - 음반 불러오는 중… - 연주자 불러오는 중… - 곡 불러오는 중… - 연주목록 불러오는 중… - 연주목록 - 추가와 교체 - 추가와 교체와 연주 - 음반 추가 - 연주목록 추가 - 추가와 연주 - 연주자 추가 - 장르 추가 - 추가 - 곡 추가 - 여러 곡 지우기 - 잘라내기 - %s 곡이 지워짐 - 지우기 - 주 메뉴 - 연주목록 지워짐 - 연주목록에서 곡 지움 - 음반 %s 추가됨 - 연주목록 %s 추가됨 - 연주목록에 %s 추가됨 - 연주자 %s 추가됨 - 호스트 - MPD 서버 호스트 이름이나 IP 주소 - 스트리밍 호스트 - 스트리밍 서버 호스트 이름 또는 IP 주소 - 포트 - MPD 서버 포트 (기본값: 6600) - 비밀번호 - 서버 비밀번호 - 버전 - - 서버 정보 - 버전과 곡 수 등 각종 MPD 서버 정보를 보여줍니다 - 연결 설정 - MPD 호스트/포트와 비밀번호를 설정합니다 - 출력 - 인터페이스 설정 - 라이브러리 설정 - 곡 %s 추가됨 - 정보 - 연결 안됨 - MPD 서버 연결이 안 됩니다! 서버가 가동 중이고 연결할 수 있는지 확인해야 합니다 (%s) - 연결 - 연결 중… - MPD 서버로 연결 중입니다 - 연결됨 - 연결 안됨 - 곡 정보 없음 - 저장된 범위에 없음 - 연주목록 %s 지워짐 - 연주목록 지우기 - 기본 연결 - 우선 연결 - 무선랜을 선택합니다 - 무선랜 기반 연결 - 기본 연결 설정 - 무선랜 기반의 MPD 호스트/서버와 비밀번호를 설정합니다 - 기본 MPD 호스트/서버와 비밀번호를 설정합니다 - 스트리밍 - 버퍼링… - 스트리밍 포트 - MPD 스트리밍 포트 (기본값: 8000) - 스트리밍 주소 덧붙임 - 스트림 주소 뒤에 덧붙입니다 (예. mpd.mp3) - MPDroid는 오픈 소스 소프트웨어로 소스코드는 http://github.com/abarisain/dmix를 방문하면 됩니다. - MPDroid는 PMix (http://code.google.com/p/pmix/) 에서 나왔습니다. 감사합니다! - 찾기 - MPDroid - 찾기 … - 라이브러리 - 읽을거리 - MPDroid 1.0에 오신 걸 환영합니다!\n이 화면은 한 번만 보입니다.\n\n먼저 MPD 서버에 대하여 모르신다면, 이 앱은 도움이 되지 않으므로 지금 지우시기 바랍니다.\n\n알려진 주요 문제점 : 위젯이 가끔 다운되거나 배터리를 소모할 수 있습니다.\n\n기존 사용자분들의 지원과 기여에 감사합니다. 저는 여러분이 MPDroid를 좋아해 주시기를 진심으로 바랍니다. 싫어하거나 되돌리기를 바라는 부분은 언제라도 메일로 알려주시기 바랍니다 (^_^)\n이전 버전은 여전히 저의 github 페이지에 있습니다. - 수정 - 지금 연주 중 - 취소 - 다음 곡 연주 - 가기… - 처음으로 이동 - 마지막으로 이동 - 연주목록에서 지우기 - 연주목록에서 음반 지우기 - 저장 - MPD 데이터베이스 새로 고침 - 음반 캐시 사용 - MPD 데이터베이스 정보를 로컬에 저장합니다 - 음반 연도 - 음반을 연도로 정리합니다 - 음반 곡 수 - 음반의 곡 수를 보여줍니다 - 로컬 음반표지 내려받기 - MPD 서버에서 음반표지를 내려받습니다 (웹서버가 필요하며, 위키를 보시기 바랍니다!) - 음악 경로 - MPD 서버의 음악 디렉터리, 예) files/mp3 (vortexbox 사용자들은 music/). 복잡한 설정에서는 절대 경로를 써도 됩니다, 예) "http://ip:port/music". - 음반표지 이름 - 음반표지의 기본 파일 이름, 예) folder.jpg (vortexbox 사용자들은 cover.jpg) - 캐시 사용 - 이 서버를 지우기 - Asher (http://kyo-tux.deviantart.com/) 와 brsev (http://brsev.deviantart.com/) 의 원래 앱 아이콘을 MPDroid에 맞게 수정하였습니다. - 연결이 안되므로, 설정을 확인하시기 바랍니다 (%s) - 결과 없음 - 나가려면 뒤로 가기를 다시 누릅니다 - 연주순서 - %s 을 지우는 것이 맞습니까? - %s 가 지워지지 않습니다 - 여러 연주자 - %1$s 곡, %2$s - %1$s 곡, %2$s - 연주목록에 추가 - (새로운 연주목록) - 연주목록 이름 - 새로운 연주목록 이름을 입력합니다: - 스트림 - 스트림 추가 - 스트림 수정 - 스트림 %s 추가됨 - 스트림 읽는 중… - 스트림 %s 지워짐 - 스트림 지우기 - %s 을 지우는 것이 맞습니까? - 이름: - 주소: - 장르 %s 추가됨 - 정지 단추 보기 - 단일 모드 - 소비 모드 - 음반표지 - 나눔 단추 - MPDroid 시작 - 메뉴 단추 - 처리 항목 목록 - 연주 - 정지 - 음반 연도 보기 - 음반연주자 보기 - 오디오속성 보기 - 등급 보기 - 스트리밍 시작 - 스트리밍 중지 - - 전화 받기 - 연주 잠시 멈춤 - 전화 중일 때 연주를 잠시 멈춥니다 - 연주 다시 시작 - 전화가 끝나면 연주를 다시 시작합니다 - - 라이브러리 탭 설정 - 보일 탭과 순서를 바꿉니다 - 보일 탭 - 숨길 탭 - - 음반표지 설정 - 음반표지를 내려받고 저장하는 방법을 바꿉니다 - 음반표지 캐시 - 음반표지를 빨리 찾기 위하여 내려받은 표지를 장치에 저장합니다 - 음반표지 캐시 지우기 - 음반표지 캐시의 저장 공간을 비웁니다 - 음반표지 캐시를 모두 지웁니까? - 로컬 음반 캐시 업데이트 - - 음반표지를 라이브러리에 보기 - 큰 음반표지를 라이브러리에 타일형태로 보여줍니다. 이 기능은 실험적입니다! 느려지거나 실패할 수 있습니다 (음반표지 캐시 필요) - - 음반으로 가기 - 연주자로 가기 - 음반 연주자로 가기 - 폴더로 가기 - 스트림으로 가기 - 지금 곡으로 이동 - 기타 사진 - 이미지 재설정 - - 한 곡이 선택됨 - %s 곡이 선택됨 - 연주순서 찾기… - 와이파이로만 내려받기 - 이동 통신으로 음반표지를 내려받지 않습니다 (요금 절약) - 나가기 전에 확인 - 나가려면 두 번 누릅니다 - 밝은 테마 사용 - 공유 - 지금 연주 중 : - 태블릿 UI 사용 - 바꾸려면 앱을 다시 시작해야 합니다 - 음반표지 내려받기 - 인터넷으로 음반표지를 내려받습니다 (음악정보 보냄) - GraceNote 클라이언트 ID - GraceNote 클라이언트 ID (XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) - 서랍 보기 - 서랍 닫기 - - 지금 연주 중 설정 - 작은 찾기 사용 - 찾은 이력 지우기 - 스트림 저장됨 - - 저자 - 라이브러리 - 나눔 - 음반표지 - - 실행 선택하기 - - 알림 - 알림 닫기 - 연주 켰다 끄기 - 잠시 멈춤 - 되감기 - 조용히 - 음량 설정 - - 다시 맞추기 - 단순 모드 - 일반 안드로이드 미디어 연주기처럼 연주순서를 관리합니다 - 연주순서에 추가 - - 모두 - 음반연주자 - 연주자 - 프로젝트 아이콘 - 연주자 항목에 쓸 태그 - 연주자 항목을 덧붙이는 데에 사용할 태그를 선택합니다. 편집음반에만 나오는 연주자를 숨기는 데에 유용합니다. - 계속 알림 - 이 네트워크에 머물도록 알림 설정 - 무작위 모드에서 추가된 항목 연주 안 됨. - - - 스트리밍을 할 수 없습니다 : 다른 앱이 사용 중입니다. - %1$s 스트림 오류: %2$s. - 이 오류는 스트림을 준비하는 과정에서 서버 상태가 변경되어서입니다. - 스트림 소스 설정 실패: %1$s. - - - - 미디어 플레이어 미지정 오류. - 미디어 서버 없음. - - 네트워크 관련 운영 실패. - 스트림이 관련 코딩 규격과 맞지 않음. - 운영 시간 초과. - 미디어 프레임워크가 스트림 코덱을 지원하지 않음. - + + + MPDroid + 연주자 + 장르 + 연주목록 + 파일 + 음반 + 설정 + 다음 곡 + 이전 곡 + 확인 + 나가기 + 다시 시도 + 불러오는 중… + 장르 불러오는 중… + 음반 불러오는 중… + 연주자 불러오는 중… + 곡 불러오는 중… + 연주목록 불러오는 중… + 연주목록 + 추가와 교체 + 추가와 교체와 연주 + 음반 추가 + 연주목록 추가 + 추가와 연주 + 연주자 추가 + 장르 추가 + 추가 + 곡 추가 + 여러 곡 지우기 + 잘라내기 + %s 곡이 지워짐 + 지우기 + 주 메뉴 + 연주목록 지워짐 + 연주목록에서 곡 지움 + 음반 %s 추가됨 + 연주목록 %s 추가됨 + 연주목록에 %s 추가됨 + 연주자 %s 추가됨 + 호스트 + MPD 서버 호스트 이름이나 IP 주소 + 스트리밍 호스트 + 스트리밍 서버 호스트 이름 또는 IP 주소 + 포트 + MPD 서버 포트 (기본값: 6600) + 비밀번호 + 서버 비밀번호 + 버전 + + 서버 정보 + 버전과 곡 수 등 각종 MPD 서버 정보를 보여줍니다 + 연결 설정 + MPD 호스트/포트와 비밀번호를 설정합니다 + 출력 + 인터페이스 설정 + 라이브러리 설정 + 곡 %s 추가됨 + 정보 + 연결 안됨 + MPD 서버 연결이 안 됩니다! 서버가 가동 중이고 연결할 수 있는지 확인해야 합니다 (%s) + 연결 + 연결 중… + MPD 서버로 연결 중입니다 + 연결됨 + 연결 안됨 + 곡 정보 없음 + 저장된 범위에 없음 + 연주목록 %s 지워짐 + 연주목록 지우기 + 기본 연결 + 우선 연결 + 무선랜을 선택합니다 + 무선랜 기반 연결 + 기본 연결 설정 + 무선랜 기반의 MPD 호스트/서버와 비밀번호를 설정합니다 + 기본 MPD 호스트/서버와 비밀번호를 설정합니다 + 스트리밍 + 버퍼링… + 스트리밍 포트 + MPD 스트리밍 포트 (기본값: 8000) + 스트리밍 주소 덧붙임 + 스트림 주소 뒤에 덧붙입니다 (예. mpd.mp3) + MPDroid는 오픈 소스 소프트웨어로 소스코드는 http://github.com/abarisain/dmix를 방문하면 됩니다. + MPDroid는 PMix (http://code.google.com/p/pmix/) 에서 나왔습니다. 감사합니다! + 찾기 + MPDroid + 찾기 … + 라이브러리 + 읽을거리 + MPDroid 1.0에 오신 걸 환영합니다!\n이 화면은 한 번만 보입니다.\n\n먼저 MPD 서버에 대하여 모르신다면, 이 앱은 도움이 되지 않으므로 지금 지우시기 바랍니다.\n\n알려진 주요 문제점 : 위젯이 가끔 다운되거나 배터리를 소모할 수 있습니다.\n\n기존 사용자분들의 지원과 기여에 감사합니다. 저는 여러분이 MPDroid를 좋아해 주시기를 진심으로 바랍니다. 싫어하거나 되돌리기를 바라는 부분은 언제라도 메일로 알려주시기 바랍니다 (^_^)\n이전 버전은 여전히 저의 github 페이지에 있습니다. + 수정 + 지금 연주 중 + 취소 + 다음 곡 연주 + 가기… + 처음으로 이동 + 마지막으로 이동 + 연주목록에서 지우기 + 연주목록에서 음반 지우기 + 저장 + MPD 데이터베이스 새로 고침 + 음반 캐시 사용 + MPD 데이터베이스 정보를 로컬에 저장합니다 + 음반 연도 + 음반을 연도로 정리합니다 + 음반 곡 수 + 음반의 곡 수를 보여줍니다 + 로컬 음반표지 내려받기 + MPD 서버에서 음반표지를 내려받습니다 (웹서버가 필요하며, 위키를 보시기 바랍니다!) + 음악 경로 + MPD 서버의 음악 디렉터리, 예) files/mp3 (vortexbox 사용자들은 music/). 복잡한 설정에서는 절대 경로를 써도 됩니다, 예) "http://ip:port/music". + 음반표지 이름 + 음반표지의 기본 파일 이름, 예) folder.jpg (vortexbox 사용자들은 cover.jpg) + 캐시 사용 + 이 서버를 지우기 + Asher (http://kyo-tux.deviantart.com/) 와 brsev (http://brsev.deviantart.com/) 의 원래 앱 아이콘을 MPDroid에 맞게 수정하였습니다. + 연결이 안되므로, 설정을 확인하시기 바랍니다 (%s) + 결과 없음 + 나가려면 뒤로 가기를 다시 누릅니다 + 연주순서 + %s 을 지우는 것이 맞습니까? + %s 가 지워지지 않습니다 + 여러 연주자 + %1$s 곡, %2$s + %1$s 곡, %2$s + 연주목록에 추가 + (새로운 연주목록) + 연주목록 이름 + 새로운 연주목록 이름을 입력합니다: + 스트림 + 스트림 추가 + 스트림 수정 + 스트림 %s 추가됨 + 스트림 읽는 중… + 스트림 %s 지워짐 + 스트림 지우기 + %s 을 지우는 것이 맞습니까? + 이름: + 주소: + 장르 %s 추가됨 + 정지 단추 보기 + 단일 모드 + 소비 모드 + 음반표지 + 나눔 단추 + MPDroid 시작 + 메뉴 단추 + 처리 항목 목록 + 연주 + 정지 + 음반 연도 보기 + 음반연주자 보기 + 오디오속성 보기 + 등급 보기 + 스트리밍 시작 + 스트리밍 중지 + + 전화 받기 + 연주 잠시 멈춤 + 전화 중일 때 연주를 잠시 멈춥니다 + 연주 다시 시작 + 전화가 끝나면 연주를 다시 시작합니다 + + 라이브러리 탭 설정 + 보일 탭과 순서를 바꿉니다 + 보일 탭 + 숨길 탭 + + 음반표지 설정 + 음반표지를 내려받고 저장하는 방법을 바꿉니다 + 음반표지 캐시 + 음반표지를 빨리 찾기 위하여 내려받은 표지를 장치에 저장합니다 + 음반표지 캐시 지우기 + 음반표지 캐시의 저장 공간을 비웁니다 + 음반표지 캐시를 모두 지웁니까? + 로컬 음반 캐시 업데이트 + + 음반표지를 라이브러리에 보기 + 큰 음반표지를 라이브러리에 타일형태로 보여줍니다. 이 기능은 실험적입니다! 느려지거나 실패할 수 있습니다 (음반표지 캐시 필요) + + 음반으로 가기 + 연주자로 가기 + 음반 연주자로 가기 + 폴더로 가기 + 스트림으로 가기 + 지금 곡으로 이동 + 기타 사진 + 이미지 재설정 + + 한 곡이 선택됨 + %s 곡이 선택됨 + 연주순서 찾기… + 와이파이로만 내려받기 + 이동 통신으로 음반표지를 내려받지 않습니다 (요금 절약) + 나가기 전에 확인 + 나가려면 두 번 누릅니다 + 밝은 테마 사용 + 공유 + 지금 연주 중 : + 태블릿 UI 사용 + 바꾸려면 앱을 다시 시작해야 합니다 + 음반표지 내려받기 + 인터넷으로 음반표지를 내려받습니다 (음악정보 보냄) + GraceNote 클라이언트 ID + GraceNote 클라이언트 ID (XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) + 서랍 보기 + 서랍 닫기 + + 지금 연주 중 설정 + 작은 찾기 사용 + 찾은 이력 지우기 + 스트림 저장됨 + + 저자 + 라이브러리 + 나눔 + 음반표지 + + 실행 선택하기 + + 알림 + 알림 닫기 + 연주 켰다 끄기 + 잠시 멈춤 + 되감기 + 조용히 + 음량 설정 + + 다시 맞추기 + 단순 모드 + 일반 안드로이드 미디어 연주기처럼 연주순서를 관리합니다 + 연주순서에 추가 + + 모두 + 음반연주자 + 연주자 + 프로젝트 아이콘 + 연주자 항목에 쓸 태그 + 연주자 항목을 덧붙이는 데에 사용할 태그를 선택합니다. 편집음반에만 나오는 연주자를 숨기는 데에 유용합니다. + 계속 알림 + 이 네트워크에 머물도록 알림 설정 + 무작위 모드에서 추가된 항목 연주 안 됨. + + + 스트리밍을 할 수 없습니다 : 다른 앱이 사용 중입니다. + %1$s 스트림 오류: %2$s. + 이 오류는 스트림을 준비하는 과정에서 서버 상태가 변경되어서입니다. + 스트림 소스 설정 실패: %1$s. + + + + 미디어 플레이어 미지정 오류. + 미디어 서버 없음. + + 네트워크 관련 운영 실패. + 스트림이 관련 코딩 규격과 맞지 않음. + 운영 시간 초과. + 미디어 프레임워크가 스트림 코덱을 지원하지 않음. + \ No newline at end of file From 3a4cec77d23a3702395a3f2bdafe355a873faa14 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Tue, 18 Nov 2014 15:29:18 -0800 Subject: [PATCH 30/33] gradle/android: Update for new support library/repository. --- MPDroid/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MPDroid/build.gradle b/MPDroid/build.gradle index 4720fcbaa1..f9a5bf491a 100644 --- a/MPDroid/build.gradle +++ b/MPDroid/build.gradle @@ -79,8 +79,8 @@ android { dependencies { // Support Libraries - compile 'com.android.support:support-v4:21.0.0' - compile 'com.android.support:appcompat-v7:21.0.0' + compile 'com.android.support:support-v4:21.0.2' + compile 'com.android.support:appcompat-v7:21.0.2' // Projects compile project(':JMPDCommAndroid') From dd8a344f6d54d8185215ed67980e4fcebb88bc55 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Tue, 18 Nov 2014 15:37:16 -0800 Subject: [PATCH 31/33] MPDStatusMonitor: Workaround an Android 5 bug. First, let me start by saying this code change makes no logical sense, that I can tell. This issue is, intermittently, if state is changed quickly enough, the state change wouldn't show. After a few hours of bisection I traced this down to: e0d9799:JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java:107 When this line is removed, and the code is replace with code that result in the same code result (hard coded or otherwise) the state changes just as it should. This is not a cloning issue, the state is not modified in MPDCommand (and I could reproduce it post-cloning). Since I've only been able to reproduce this in Android 5, so my wild assumption is that this is a bug in ART; but it's easy enough to workaround that this patch is a trivial non-issue. --- .../java/org/a0z/mpd/MPDStatusMonitor.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java b/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java index 54cfa8806c..ad5f36ff07 100644 --- a/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java +++ b/JMPDComm/src/main/java/org/a0z/mpd/MPDStatusMonitor.java @@ -81,12 +81,12 @@ public class MPDStatusMonitor extends Thread { private final long mDelay; - private final MPDCommand mIdleCommand; - private final MPD mMPD; private final Queue mStatusChangeListeners; + private final String[] mSupportedSubsystems; + private final Queue mTrackPositionListeners; private volatile boolean mGiveup; @@ -94,11 +94,11 @@ public class MPDStatusMonitor extends Thread { /** * Constructs a MPDStatusMonitor. * - * @param mpd MPD server to monitor. - * @param delay status query interval. - * @param supportedIdle Idle subsystems to support, see IDLE fields in this class. + * @param mpd MPD server to monitor. + * @param delay status query interval. + * @param supportedSubsystems Idle subsystems to support, see IDLE fields in this class. */ - public MPDStatusMonitor(final MPD mpd, final long delay, final String[] supportedIdle) { + public MPDStatusMonitor(final MPD mpd, final long delay, final String[] supportedSubsystems) { super("MPDStatusMonitor"); mMPD = mpd; @@ -106,7 +106,7 @@ public MPDStatusMonitor(final MPD mpd, final long delay, final String[] supporte mGiveup = false; mStatusChangeListeners = new LinkedList<>(); mTrackPositionListeners = new LinkedList<>(); - mIdleCommand = new MPDCommand(MPDCommand.MPD_CMD_IDLE, supportedIdle); + mSupportedSubsystems = supportedSubsystems.clone(); } /** @@ -339,9 +339,11 @@ public void run() { */ private List waitForChanges() throws IOException, MPDException { final MPDConnection mpdIdleConnection = mMPD.getIdleConnection(); + final MPDCommand idleCommand = new MPDCommand(MPDCommand.MPD_CMD_IDLE, + mSupportedSubsystems); while (mpdIdleConnection != null && mpdIdleConnection.isConnected()) { - final List data = mpdIdleConnection.sendCommand(mIdleCommand); + final List data = mpdIdleConnection.sendCommand(idleCommand); if (data == null || data.isEmpty()) { continue; From c1aec73956ba5d2c0d4fb1e676f2b7969c31fc83 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Wed, 19 Nov 2014 07:55:15 -0800 Subject: [PATCH 32/33] dmix: Commit iml changes from 3a4cec7. This should have gone with that commit (whoops!). --- MPDroid/MPDroid.iml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MPDroid/MPDroid.iml b/MPDroid/MPDroid.iml index 69c0cf8327..784584d7de 100644 --- a/MPDroid/MPDroid.iml +++ b/MPDroid/MPDroid.iml @@ -107,12 +107,12 @@ - - + + - + From 72669e6cde2ed166410c716565326c29a4b47f6d Mon Sep 17 00:00:00 2001 From: Arnaud Barisain-Monrose Date: Thu, 20 Nov 2014 22:01:17 +0100 Subject: [PATCH 33/33] 1.07 RC3 --- MPDroid/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MPDroid/build.gradle b/MPDroid/build.gradle index f9a5bf491a..9412ba48d7 100644 --- a/MPDroid/build.gradle +++ b/MPDroid/build.gradle @@ -27,8 +27,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 50 - versionName "1.07 RC2 " + gitShortHash() + versionCode 51 + versionName "1.07 RC3 " + gitShortHash() } lintOptions {