From ba0eab073ef9422a05285c2f48c86241cadd6604 Mon Sep 17 00:00:00 2001 From: Joshua Bahnsen Date: Mon, 30 Dec 2013 01:33:39 -0700 Subject: [PATCH] Code stability, fix playlist playback on Ice Cream Sandwich devices --- .../androidapp/activity/BookmarkActivity.java | 2 +- .../androidapp/activity/DownloadActivity.java | 19 ++-- .../androidapp/activity/SearchActivity.java | 28 ++++-- .../activity/SelectPlaylistActivity.java | 39 ++++++-- .../androidapp/activity/SettingsActivity.java | 98 ++++++++++++------- .../androidapp/activity/ShareActivity.java | 42 +++++--- .../activity/SubsonicTabActivity.java | 17 ++-- .../audiofx/EqualizerController.java | 5 + .../audiofx/VisualizerController.java | 9 +- .../androidapp/domain/Bookmark.java | 5 +- .../ultrasonic/androidapp/domain/Indexes.java | 11 ++- .../androidapp/domain/Playlist.java | 2 +- .../androidapp/domain/SearchCritera.java | 61 ------------ .../ultrasonic/androidapp/domain/Share.java | 4 +- .../ultrasonic/androidapp/domain/Version.java | 32 +++--- .../provider/UltraSonicAppWidgetProvider.java | 12 +-- .../receiver/MediaButtonIntentReceiver.java | 4 +- .../androidapp/service/DownloadFile.java | 3 +- .../service/DownloadServiceImpl.java | 11 ++- .../DownloadServiceLifecycleSupport.java | 17 +++- .../service/OfflineMusicService.java | 6 +- .../androidapp/service/RESTMusicService.java | 8 +- .../service/ServerTooOldException.java | 2 +- .../service/parser/IndexesParser.java | 16 ++- .../androidapp/util/CacheCleaner.java | 2 +- .../util/EntryByDiscAndTrackComparator.java | 21 ++-- .../ultrasonic/androidapp/util/FileUtil.java | 26 +++-- .../androidapp/util/ShufflePlayBuffer.java | 2 +- .../androidapp/util/TimeSpanPicker.java | 49 +++++++--- .../androidapp/util/TimeSpanPreference.java | 7 +- .../ultrasonic/androidapp/util/Util.java | 38 ++----- .../androidapp/view/PlaylistAdapter.java | 5 +- .../androidapp/view/ShareAdapter.java | 5 +- .../ultrasonic/androidapp/view/SongView.java | 3 +- 34 files changed, 331 insertions(+), 280 deletions(-) delete mode 100644 src/com/thejoshwa/ultrasonic/androidapp/domain/SearchCritera.java diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/BookmarkActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/BookmarkActivity.java index c13a3fc4..3baa0b3a 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/BookmarkActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/BookmarkActivity.java @@ -204,7 +204,7 @@ public class BookmarkActivity extends SubsonicTabActivity private void playNow(List songs) { - if (getSelectedSongs(albumListView).size() > 0) + if (!getSelectedSongs(albumListView).isEmpty()) { int position = songs.get(0).getBookmarkPosition(); getDownloadService().restore(songs, 0, position, true, true); diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/DownloadActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/DownloadActivity.java index 62f9a643..7da385f8 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/DownloadActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/DownloadActivity.java @@ -119,8 +119,6 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi private SilentBackgroundTask onProgressChangedTask; LinearLayout visualizerViewLayout; private MenuItem starMenuItem; - private MenuItem bookmarkMenuItem; - private MenuItem bookmarkRemoveMenuItem; /** * Called when the activity is first created. @@ -677,10 +675,9 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi final MenuItem equalizerMenuItem = menu.findItem(R.id.menu_item_equalizer); final MenuItem visualizerMenuItem = menu.findItem(R.id.menu_item_visualizer); final MenuItem shareMenuItem = menu.findItem(R.id.menu_item_share); - final MenuItem savePlaylistMenuItem = menu.findItem(R.id.menu_item_save_playlist); starMenuItem = menu.findItem(R.id.menu_item_star); - bookmarkMenuItem = menu.findItem(R.id.menu_item_bookmark_set); - bookmarkRemoveMenuItem = menu.findItem(R.id.menu_item_bookmark_delete); + MenuItem bookmarkMenuItem = menu.findItem(R.id.menu_item_bookmark_set); + MenuItem bookmarkRemoveMenuItem = menu.findItem(R.id.menu_item_bookmark_delete); if (Util.isOffline(this)) @@ -856,12 +853,22 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi switch (menuItemId) { case R.id.menu_show_album: + if (entry == null) + { + return false; + } + Intent intent = new Intent(this, SelectAlbumActivity.class); intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, entry.getParent()); intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, entry.getAlbum()); Util.startActivityWithoutTransition(this, intent); return true; case R.id.menu_lyrics: + if (entry == null) + { + return false; + } + intent = new Intent(this, LyricsActivity.class); intent.putExtra(Constants.INTENT_EXTRA_NAME_ARTIST, entry.getArtist()); intent.putExtra(Constants.INTENT_EXTRA_NAME_TITLE, entry.getTitle()); @@ -920,7 +927,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi onDownloadListChanged(); return true; case R.id.menu_item_save_playlist: - if (getDownloadService().getSongs().size() > 0) + if (!getDownloadService().getSongs().isEmpty()) { showDialog(DIALOG_SAVE_PLAYLIST); } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/SearchActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/SearchActivity.java index 3a8c8897..512335d1 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/SearchActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/SearchActivity.java @@ -100,14 +100,16 @@ public class SearchActivity extends SubsonicTabActivity View buttons = LayoutInflater.from(this).inflate(R.layout.search_buttons, null); - artistsHeading = buttons.findViewById(R.id.search_artists); - albumsHeading = buttons.findViewById(R.id.search_albums); - songsHeading = buttons.findViewById(R.id.search_songs); - - searchButton = (TextView) buttons.findViewById(R.id.search_search); - moreArtistsButton = buttons.findViewById(R.id.search_more_artists); - moreAlbumsButton = buttons.findViewById(R.id.search_more_albums); - moreSongsButton = buttons.findViewById(R.id.search_more_songs); + if (buttons != null) + { + artistsHeading = buttons.findViewById(R.id.search_artists); + albumsHeading = buttons.findViewById(R.id.search_albums); + songsHeading = buttons.findViewById(R.id.search_songs); + searchButton = (TextView) buttons.findViewById(R.id.search_search); + moreArtistsButton = buttons.findViewById(R.id.search_more_artists); + moreAlbumsButton = buttons.findViewById(R.id.search_more_albums); + moreSongsButton = buttons.findViewById(R.id.search_more_songs); + } list = (ListView) findViewById(R.id.search_list); @@ -210,11 +212,17 @@ public class SearchActivity extends SubsonicTabActivity MenuItem shareButton = menu.findItem(R.id.menu_item_share); MenuItem downloadMenuItem = menu.findItem(R.id.album_menu_download); - downloadMenuItem.setVisible(!Util.isOffline(this)); + if (downloadMenuItem != null) + { + downloadMenuItem.setVisible(!Util.isOffline(this)); + } if (Util.isOffline(this) || isArtist) { - shareButton.setVisible(false); + if (shareButton != null) + { + shareButton.setVisible(false); + } } } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/SelectPlaylistActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/SelectPlaylistActivity.java index 074de15f..555c88e4 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/SelectPlaylistActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/SelectPlaylistActivity.java @@ -24,6 +24,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; +import android.text.Editable; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuInflater; @@ -154,7 +155,16 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt public boolean onContextItemSelected(MenuItem menuItem) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo(); + if (info == null) + { + return false; + } + Playlist playlist = (Playlist) playlistsListView.getItemAtPosition(info.position); + if (playlist == null) + { + return false; + } Intent intent; switch (menuItem.getItemId()) @@ -214,9 +224,13 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - Playlist playlist = (Playlist) parent.getItemAtPosition(position); + if (playlist == null) + { + return; + } + Intent intent = new Intent(SelectPlaylistActivity.this, SelectAlbumActivity.class); intent.putExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId()); intent.putExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName()); @@ -252,14 +266,7 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt protected void error(Throwable error) { String msg; - if (error instanceof OfflineException || error instanceof ServerTooOldException) - { - msg = getErrorMessage(error); - } - else - { - msg = String.format("%s %s", getResources().getString(R.string.menu_deleted_playlist_error, playlist.getName()), getErrorMessage(error)); - } + msg = error instanceof OfflineException || error instanceof ServerTooOldException ? getErrorMessage(error) : String.format("%s %s", getResources().getString(R.string.menu_deleted_playlist_error, playlist.getName()), getErrorMessage(error)); Util.toast(SelectPlaylistActivity.this, msg, false); } @@ -281,6 +288,12 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt private void updatePlaylistInfo(final Playlist playlist) { View dialogView = getLayoutInflater().inflate(R.layout.update_playlist, null); + + if (dialogView == null) + { + return; + } + final EditText nameBox = (EditText) dialogView.findViewById(R.id.get_playlist_name); final EditText commentBox = (EditText) dialogView.findViewById(R.id.get_playlist_comment); final CheckBox publicBox = (CheckBox) dialogView.findViewById(R.id.get_playlist_public); @@ -288,6 +301,7 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt nameBox.setText(playlist.getName()); commentBox.setText(playlist.getComment()); Boolean pub = playlist.getPublic(); + if (pub == null) { publicBox.setEnabled(false); @@ -312,8 +326,13 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt @Override protected Void doInBackground() throws Throwable { + Editable nameBoxText = nameBox.getText(); + Editable commentBoxText = commentBox.getText(); + String name = nameBoxText != null ? nameBoxText.toString() : null; + String comment = commentBoxText != null ? commentBoxText.toString() : null; + MusicService musicService = MusicServiceFactory.getMusicService(SelectPlaylistActivity.this); - musicService.updatePlaylist(playlist.getId(), nameBox.getText().toString(), commentBox.getText().toString(), publicBox.isChecked(), SelectPlaylistActivity.this, null); + musicService.updatePlaylist(playlist.getId(), name, comment, publicBox.isChecked(), SelectPlaylistActivity.this, null); return null; } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/SettingsActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/SettingsActivity.java index 73318612..4fde7cc9 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/SettingsActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/SettingsActivity.java @@ -19,6 +19,7 @@ package com.thejoshwa.ultrasonic.androidapp.activity; import android.app.ActionBar; +import android.app.Dialog; import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; @@ -89,12 +90,11 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer private CheckBoxPreference sendBluetoothNotifications; private CheckBoxPreference sendBluetoothAlbumArt; private ListPreference viewRefresh; - private CheckBoxPreference sharingAlwaysAskForDetails; private EditTextPreference sharingDefaultDescription; private EditTextPreference sharingDefaultGreeting; private TimeSpanPreference sharingDefaultExpiration; private int maxServerCount = 10; - private int minServerCount = 0; + private int minServerCount; private static final String STATE_MENUDRAWER = "com.thejoshwa.ultrasonic.androidapp.menuDrawer"; private static final String STATE_ACTIVE_VIEW_ID = "com.thejoshwa.ultrasonic.androidapp.activeViewId"; @@ -184,24 +184,28 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer sendBluetoothAlbumArt = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SEND_BLUETOOTH_ALBUM_ART); sendBluetoothNotifications = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SEND_BLUETOOTH_NOTIFICATIONS); viewRefresh = (ListPreference) findPreference(Constants.PREFERENCES_KEY_VIEW_REFRESH); - sharingAlwaysAskForDetails = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_ASK_FOR_SHARE_DETAILS); sharingDefaultDescription = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_DESCRIPTION); sharingDefaultGreeting = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_GREETING); sharingDefaultExpiration = (TimeSpanPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_EXPIRATION); sharingDefaultGreeting.setText(Util.getShareGreeting(this)); - findPreference(Constants.PREFERENCES_KEY_CLEAR_SEARCH_HISTORY).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() + Preference clearSearchPreference = findPreference(Constants.PREFERENCES_KEY_CLEAR_SEARCH_HISTORY); + + if (clearSearchPreference != null) { - @Override - public boolean onPreferenceClick(Preference preference) + clearSearchPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - SearchRecentSuggestions suggestions = new SearchRecentSuggestions(SettingsActivity.this, SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE); - suggestions.clearHistory(); - Util.toast(SettingsActivity.this, R.string.settings_search_history_cleared); - return false; - } - }); + @Override + public boolean onPreferenceClick(Preference preference) + { + SearchRecentSuggestions suggestions = new SearchRecentSuggestions(SettingsActivity.this, SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE); + suggestions.clearHistory(); + Util.toast(SettingsActivity.this, R.string.settings_search_history_cleared); + return false; + } + }); + } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { @@ -231,15 +235,20 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer serversCategory.addPreference(addServer(i)); - findPreference(Constants.PREFERENCES_KEY_TEST_CONNECTION + i).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() + Preference testConnectionPreference = findPreference(Constants.PREFERENCES_KEY_TEST_CONNECTION + i); + + if (testConnectionPreference != null) { - @Override - public boolean onPreferenceClick(Preference preference) + testConnectionPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - testConnection(instanceValue); - return false; - } - }); + @Override + public boolean onPreferenceClick(Preference preference) + { + testConnection(instanceValue); + return false; + } + }); + } String instance = String.valueOf(i); serverSettings.put(instance, new ServerSettings(instance)); @@ -262,14 +271,23 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer prefEditor.commit(); Preference addServerPreference = findPreference(Constants.PREFERENCES_KEY_ADD_SERVER); - serversCategory.removePreference(addServerPreference); + + if (addServerPreference != null) + { + serversCategory.removePreference(addServerPreference); + } + serversCategory.addPreference(addServer(activeServers)); - serversCategory.addPreference(addServerPreference); + + if (addServerPreference != null) + { + serversCategory.addPreference(addServerPreference); + addServerPreference.setEnabled(activeServers < maxServerCount); + } String instance = String.valueOf(activeServers); serverSettings.put(instance, new ServerSettings(instance)); - addServerPreference.setEnabled(activeServers < maxServerCount); applyTheme(); return true; @@ -333,7 +351,10 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer serverUrlPreference.setSummary(serverUrlPreference.getText()); - screen.setSummary(serverUrlPreference.getText()); + if (screen != null) + { + screen.setSummary(serverUrlPreference.getText()); + } final EditTextPreference serverUsernamePreference = new EditTextPreference(this); serverUsernamePreference.setKey(Constants.PREFERENCES_KEY_USERNAME + instance); @@ -391,14 +412,22 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer activeServers--; - serversCategory.removePreference(screen); + if (screen != null) + { + serversCategory.removePreference(screen); + Dialog dialog = screen.getDialog(); + + if (dialog != null) + { + dialog.dismiss(); + } + } SharedPreferences.Editor prefEditor = settings.edit(); prefEditor.putInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, activeServers); prefEditor.commit(); addServerPreference.setEnabled(activeServers < maxServerCount); - screen.getDialog().dismiss(); return true; } @@ -419,14 +448,17 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer } }); - screen.addPreference(serverNamePreference); - screen.addPreference(serverUrlPreference); - screen.addPreference(serverUsernamePreference); - screen.addPreference(serverPasswordPreference); - screen.addPreference(serverEnabledPreference); - screen.addPreference(jukeboxEnabledPreference); - screen.addPreference(serverRemoveServerPreference); - screen.addPreference(serverTestConnectionPreference); + if (screen != null) + { + screen.addPreference(serverNamePreference); + screen.addPreference(serverUrlPreference); + screen.addPreference(serverUsernamePreference); + screen.addPreference(serverPasswordPreference); + screen.addPreference(serverEnabledPreference); + screen.addPreference(jukeboxEnabledPreference); + screen.addPreference(serverRemoveServerPreference); + screen.addPreference(serverTestConnectionPreference); + } return screen; } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/ShareActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/ShareActivity.java index 6e1adad2..7d5fef39 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/ShareActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/ShareActivity.java @@ -24,6 +24,8 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; +import android.text.Editable; +import android.text.Spannable; import android.text.SpannableString; import android.text.method.LinkMovementMethod; import android.text.util.Linkify; @@ -148,9 +150,17 @@ public class ShareActivity extends SubsonicTabActivity implements AdapterView.On public boolean onContextItemSelected(MenuItem menuItem) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo(); - Share share = (Share) sharesListView.getItemAtPosition(info.position); + if (info == null) + { + return false; + } + + Share share = (Share) sharesListView.getItemAtPosition(info.position); + if (share == null) + { + return false; + } - Intent intent; switch (menuItem.getItemId()) { case R.id.share_menu_pin: @@ -201,6 +211,11 @@ public class ShareActivity extends SubsonicTabActivity implements AdapterView.On { Share share = (Share) parent.getItemAtPosition(position); + if (share == null) + { + return; + } + Intent intent = new Intent(ShareActivity.this, SelectAlbumActivity.class); intent.putExtra(Constants.INTENT_EXTRA_NAME_SHARE_ID, share.getId()); intent.putExtra(Constants.INTENT_EXTRA_NAME_SHARE_NAME, share.getName()); @@ -251,32 +266,30 @@ public class ShareActivity extends SubsonicTabActivity implements AdapterView.On final TextView textView = new TextView(this); textView.setPadding(3, 3, 3, 3); - final SpannableString message = new SpannableString( - "Owner: " + share.getUsername() + + final Spannable message = new SpannableString("Owner: " + share.getUsername() + "\nComments: " + ((share.getDescription() == null) ? "" : share.getDescription()) + "\nURL: " + share.getUrl() + "\nEntry Count: " + share.getEntries().size() + "\nVisit Count: " + share.getVisitCount() + ((share.getCreated() == null) ? "" : ("\nCreation Date: " + share.getCreated().replace('T', ' '))) + ((share.getLastVisited() == null) ? "" : ("\nLast Visited Date: " + share.getLastVisited().replace('T', ' '))) + - ((share.getExpires() == null) ? "" : ("\nExpiration Date: " + share.getExpires().replace('T', ' '))) - ); + ((share.getExpires() == null) ? "" : ("\nExpiration Date: " + share.getExpires().replace('T', ' ')))); Linkify.addLinks(message, Linkify.WEB_URLS); textView.setText(message); textView.setMovementMethod(LinkMovementMethod.getInstance()); - new AlertDialog.Builder(this) - .setTitle("Share Details") - .setCancelable(true) - .setIcon(android.R.drawable.ic_dialog_info) - .setView(textView) - .show(); + new AlertDialog.Builder(this).setTitle("Share Details").setCancelable(true).setIcon(android.R.drawable.ic_dialog_info).setView(textView).show(); } private void updateShareInfo(final Share share) { View dialogView = getLayoutInflater().inflate(R.layout.share_details, null); + if (dialogView == null) + { + return; + } + final EditText shareDescription = (EditText) dialogView.findViewById(R.id.share_description); final TimeSpanPicker timeSpanPicker = (TimeSpanPicker) dialogView.findViewById(R.id.date_picker); @@ -322,8 +335,11 @@ public class ShareActivity extends SubsonicTabActivity implements AdapterView.On millis = TimeSpan.getCurrentTime().add(millis).getTotalMilliseconds(); } + Editable shareDescriptionText = shareDescription.getText(); + String description = shareDescriptionText != null ? shareDescriptionText.toString() : null; + MusicService musicService = MusicServiceFactory.getMusicService(ShareActivity.this); - musicService.updateShare(share.getId(), shareDescription.getText().toString(), millis, ShareActivity.this, null); + musicService.updateShare(share.getId(), description, millis, ShareActivity.this, null); return null; } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/SubsonicTabActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/SubsonicTabActivity.java index 47684e6c..bf63b3b2 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/SubsonicTabActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/SubsonicTabActivity.java @@ -454,14 +454,17 @@ public class SubsonicTabActivity extends Activity implements OnClickListener }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - public void hidePlayingNotification(final Handler handler, final DownloadServiceImpl downloadService) { + public void hidePlayingNotification(final Handler handler, final DownloadServiceImpl downloadService) + { currentSong = null; // Remove notification and remove the service from the foreground - handler.post(new Runnable(){ + handler.post(new Runnable() + { @Override - public void run() { + public void run() + { downloadService.stopForeground(true); } }); @@ -637,7 +640,7 @@ public class SubsonicTabActivity extends Activity implements OnClickListener if (saveAsDefaultsCheckBox.isChecked()) { - String timeSpanType = timeSpanPicker.getTimeSpanType(); + String timeSpanType = timeSpanPicker.getTimeSpanType(); int timeSpanAmount = timeSpanPicker.getTimeSpanAmount(); Util.setDefaultShareExpiration(SubsonicTabActivity.this, !noExpirationCheckBox.isChecked() && timeSpanAmount > 0 ? String.format("%d:%s", timeSpanAmount, timeSpanType) : ""); Util.setDefaultShareDescription(SubsonicTabActivity.this, shareDetails.Description); @@ -775,7 +778,7 @@ public class SubsonicTabActivity extends Activity implements OnClickListener task.execute(); } - public void setTextViewTextOnUiThread(final RemoteViews view, final int id, final String text) + public void setTextViewTextOnUiThread(final RemoteViews view, final int id, final CharSequence text) { this.runOnUiThread(new Runnable() { @@ -805,7 +808,7 @@ public class SubsonicTabActivity extends Activity implements OnClickListener }); } - public void setImageViewResourceOnUiThread(final RemoteViews view, final int id, final int resouce) + public void setImageViewResourceOnUiThread(final RemoteViews view, final int id, final int resource) { this.runOnUiThread(new Runnable() { @@ -814,7 +817,7 @@ public class SubsonicTabActivity extends Activity implements OnClickListener { if (view != null) { - view.setImageViewResource(id, resouce); + view.setImageViewResource(id, resource); } } }); diff --git a/src/com/thejoshwa/ultrasonic/androidapp/audiofx/EqualizerController.java b/src/com/thejoshwa/ultrasonic/androidapp/audiofx/EqualizerController.java index 8247dc0f..174fc677 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/audiofx/EqualizerController.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/audiofx/EqualizerController.java @@ -70,6 +70,11 @@ public class EqualizerController try { + if (mediaPlayer == null) + { + return; + } + audioSessionId = mediaPlayer.getAudioSessionId(); equalizer = new Equalizer(0, audioSessionId); } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/audiofx/VisualizerController.java b/src/com/thejoshwa/ultrasonic/androidapp/audiofx/VisualizerController.java index cd838f74..c1507bb5 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/audiofx/VisualizerController.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/audiofx/VisualizerController.java @@ -35,8 +35,8 @@ public class VisualizerController private static final int PREFERRED_CAPTURE_SIZE = 128; // Must be a power of two. private Visualizer visualizer; - private boolean released = false; - private int audioSessionId = 0; + private boolean released; + private int audioSessionId; // Class initialization fails when this throws an exception. static @@ -63,6 +63,11 @@ public class VisualizerController { try { + if (mediaPlayer == null) + { + return; + } + audioSessionId = mediaPlayer.getAudioSessionId(); visualizer = new Visualizer(audioSessionId); } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/domain/Bookmark.java b/src/com/thejoshwa/ultrasonic/androidapp/domain/Bookmark.java index c9bf228b..cc52301b 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/domain/Bookmark.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/domain/Bookmark.java @@ -1,14 +1,13 @@ package com.thejoshwa.ultrasonic.androidapp.domain; +import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry; + import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; import java.util.Locale; -import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry; - public class Bookmark implements Serializable { /** diff --git a/src/com/thejoshwa/ultrasonic/androidapp/domain/Indexes.java b/src/com/thejoshwa/ultrasonic/androidapp/domain/Indexes.java index a4f58334..67e31025 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/domain/Indexes.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/domain/Indexes.java @@ -18,8 +18,8 @@ */ package com.thejoshwa.ultrasonic.androidapp.domain; -import java.util.List; import java.io.Serializable; +import java.util.List; /** * @author Sindre Mehus @@ -32,12 +32,14 @@ public class Indexes implements Serializable */ private static final long serialVersionUID = 8156117238598414701L; private final long lastModified; + private final String ignoredArticles; private final List shortcuts; private final List artists; - public Indexes(long lastModified, List shortcuts, List artists) + public Indexes(long lastModified, String ignoredArticles, List shortcuts, List artists) { this.lastModified = lastModified; + this.ignoredArticles = ignoredArticles; this.shortcuts = shortcuts; this.artists = artists; } @@ -56,4 +58,9 @@ public class Indexes implements Serializable { return artists; } + + public String getIgnoredArticles() + { + return ignoredArticles; + } } \ No newline at end of file diff --git a/src/com/thejoshwa/ultrasonic/androidapp/domain/Playlist.java b/src/com/thejoshwa/ultrasonic/androidapp/domain/Playlist.java index 8e7a6883..afa97877 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/domain/Playlist.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/domain/Playlist.java @@ -52,7 +52,7 @@ public class Playlist implements Serializable this.comment = (comment == null) ? "" : comment; this.songCount = (songCount == null) ? "" : songCount; this.created = (created == null) ? "" : created; - this.pub = (pub == null) ? null : (pub.equals("true")); + this.pub = (pub == null) ? null : ("true".equals(pub)); } public String getId() diff --git a/src/com/thejoshwa/ultrasonic/androidapp/domain/SearchCritera.java b/src/com/thejoshwa/ultrasonic/androidapp/domain/SearchCritera.java deleted file mode 100644 index aff69176..00000000 --- a/src/com/thejoshwa/ultrasonic/androidapp/domain/SearchCritera.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - This file is part of Subsonic. - - Subsonic is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Subsonic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Subsonic. If not, see . - - Copyright 2009 (C) Sindre Mehus - */ -package com.thejoshwa.ultrasonic.androidapp.domain; - -/** - * The criteria for a music search. - * - * @author Sindre Mehus - */ -public class SearchCritera -{ - - private final String query; - private final int artistCount; - private final int albumCount; - private final int songCount; - - public SearchCritera(String query, int artistCount, int albumCount, int songCount) - { - this.query = query; - this.artistCount = artistCount; - this.albumCount = albumCount; - this.songCount = songCount; - } - - public String getQuery() - { - return query; - } - - public int getArtistCount() - { - return artistCount; - } - - public int getAlbumCount() - { - return albumCount; - } - - public int getSongCount() - { - return songCount; - } -} \ No newline at end of file diff --git a/src/com/thejoshwa/ultrasonic/androidapp/domain/Share.java b/src/com/thejoshwa/ultrasonic/androidapp/domain/Share.java index ae16bf28..18bef43a 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/domain/Share.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/domain/Share.java @@ -5,10 +5,12 @@ import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry; import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; public class Share implements Serializable { private static final long serialVersionUID = 1487561657691009668L; + private static final Pattern urlPattern = Pattern.compile(".*/([^/?]+).*"); private String id; private String url; private String description; @@ -26,7 +28,7 @@ public class Share implements Serializable public String getName() { - return url.replaceFirst(".*/([^/?]+).*", "$1"); + return urlPattern.matcher(url).replaceFirst("$1"); } public String getId() diff --git a/src/com/thejoshwa/ultrasonic/androidapp/domain/Version.java b/src/com/thejoshwa/ultrasonic/androidapp/domain/Version.java index cf71c6a9..fd6a7a77 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/domain/Version.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/domain/Version.java @@ -32,14 +32,14 @@ public class Version implements Comparable private int major; private int minor; private int beta; - private int bugfix; + private int bugFix; /** * Creates a new version instance by parsing the given string. * * @param version A string of the format "1.27", "1.27.2" or "1.27.beta3". */ - public Version(String version) + public Version(CharSequence version) { String[] s = COMPILE.split(version); major = Integer.valueOf(s[0]); @@ -53,7 +53,7 @@ public class Version implements Comparable } else { - bugfix = Integer.valueOf(s[2]); + bugFix = Integer.valueOf(s[2]); } } } @@ -81,9 +81,7 @@ public class Version implements Comparable final Version version = (Version) o; - if (beta != version.beta) return false; - if (bugfix != version.bugfix) return false; - return major == version.major && minor == version.minor; + return beta == version.beta && bugFix == version.bugFix && major == version.major && minor == version.minor; } /** @@ -97,7 +95,7 @@ public class Version implements Comparable result = major; result = 29 * result + minor; result = 29 * result + beta; - result = 29 * result + bugfix; + result = 29 * result + bugFix; return result; } @@ -108,15 +106,15 @@ public class Version implements Comparable */ public String toString() { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(3); buf.append(major).append('.').append(minor); if (beta != 0) { buf.append(".beta").append(beta); } - else if (bugfix != 0) + else if (bugFix != 0) { - buf.append('.').append(bugfix); + buf.append('.').append(bugFix); } return buf.toString(); @@ -136,7 +134,8 @@ public class Version implements Comparable { return -1; } - else if (major > version.major) + + if (major > version.major) { return 1; } @@ -145,16 +144,18 @@ public class Version implements Comparable { return -1; } - else if (minor > version.minor) + + if (minor > version.minor) { return 1; } - if (bugfix < version.bugfix) + if (bugFix < version.bugFix) { return -1; } - else if (bugfix > version.bugfix) + + if (bugFix > version.bugFix) { return 1; } @@ -166,7 +167,8 @@ public class Version implements Comparable { return -1; } - else if (thisBeta > otherBeta) + + if (thisBeta > otherBeta) { return 1; } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/provider/UltraSonicAppWidgetProvider.java b/src/com/thejoshwa/ultrasonic/androidapp/provider/UltraSonicAppWidgetProvider.java index d46f4add..853effae 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/provider/UltraSonicAppWidgetProvider.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/provider/UltraSonicAppWidgetProvider.java @@ -8,7 +8,6 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; import android.os.Environment; import android.util.Log; import android.view.KeyEvent; @@ -84,14 +83,14 @@ public class UltraSonicAppWidgetProvider extends AppWidgetProvider private boolean hasInstances(Context context) { AppWidgetManager manager = AppWidgetManager.getInstance(context); - int[] appWidgetIds = new int[0]; if (manager != null) { - appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, getClass())); + int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, getClass())); + return (appWidgetIds.length > 0); } - return (appWidgetIds.length > 0); + return false; } /** @@ -158,11 +157,6 @@ public class UltraSonicAppWidgetProvider extends AppWidgetProvider // Set the cover art try { - int size; - Resources resources = context.getResources(); - Drawable drawable = resources.getDrawable(R.drawable.appwidget_art_default); - size = drawable != null ? drawable.getIntrinsicHeight() : 0; - Bitmap bitmap = currentPlaying == null ? null : FileUtil.getAlbumArtBitmap(context, currentPlaying, 240, true); if (bitmap == null) diff --git a/src/com/thejoshwa/ultrasonic/androidapp/receiver/MediaButtonIntentReceiver.java b/src/com/thejoshwa/ultrasonic/androidapp/receiver/MediaButtonIntentReceiver.java index e39306e1..91d3600b 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/receiver/MediaButtonIntentReceiver.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/receiver/MediaButtonIntentReceiver.java @@ -22,8 +22,8 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.os.Parcelable; import android.util.Log; -import android.view.KeyEvent; import com.thejoshwa.ultrasonic.androidapp.service.DownloadServiceImpl; import com.thejoshwa.ultrasonic.androidapp.util.Util; @@ -52,7 +52,7 @@ public class MediaButtonIntentReceiver extends BroadcastReceiver return; } - KeyEvent event = (KeyEvent) extras.get(Intent.EXTRA_KEY_EVENT); + Parcelable event = (Parcelable) extras.get(Intent.EXTRA_KEY_EVENT); Log.i(TAG, "Got MEDIA_BUTTON key event: " + event); Intent serviceIntent = new Intent(context, DownloadServiceImpl.class); diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadFile.java b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadFile.java index 4770c96d..4d822a14 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadFile.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadFile.java @@ -60,7 +60,7 @@ public class DownloadFile private final MediaStoreService mediaStoreService; private CancellableTask downloadTask; - private boolean save; + private final boolean save; private boolean failed; private int bitRate; private volatile boolean isPlaying; @@ -252,7 +252,6 @@ public class DownloadFile catch (Exception e) { Log.w(TAG, String.format("Failed to set last-modified date on %s", file)); - e.printStackTrace(); } } } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java index 8b894710..7c2c9822 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java @@ -71,7 +71,14 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.*; +import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.COMPLETED; +import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.DOWNLOADING; +import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.IDLE; +import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.PAUSED; +import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.PREPARED; +import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.PREPARING; +import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.STARTED; +import static com.thejoshwa.ultrasonic.androidapp.domain.PlayerState.STOPPED; /** * @author Sindre Mehus, Joshua Bahnsen @@ -1655,7 +1662,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { setNextPlayerState(PREPARED); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED)) + if (Util.getGaplessPlaybackPreference(DownloadServiceImpl.this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED)) { mediaPlayer.setNextMediaPlayer(nextMediaPlayer); nextSetup = true; diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceLifecycleSupport.java b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceLifecycleSupport.java index f7aece79..a62427fe 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceLifecycleSupport.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceLifecycleSupport.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.AsyncTask; +import android.os.Bundle; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; @@ -41,6 +42,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** @@ -58,7 +60,7 @@ public class DownloadServiceLifecycleSupport private BroadcastReceiver ejectEventReceiver; private PhoneStateListener phoneStateListener; private boolean externalStorageAvailable = true; - private ReentrantLock lock = new ReentrantLock(); + private Lock lock = new ReentrantLock(); private final AtomicBoolean setup = new AtomicBoolean(false); /** @@ -132,8 +134,15 @@ public class DownloadServiceLifecycleSupport @Override public void onReceive(Context context, Intent intent) { - Log.i(TAG, String.format("Headset event for: %s", intent.getExtras().get("name"))); - if (intent.getExtras().getInt("state") == 0) + Bundle extras = intent.getExtras(); + + if (extras == null) + { + return; + } + + Log.i(TAG, String.format("Headset event for: %s", extras.get("name"))); + if (extras.getInt("state") == 0) { if (!downloadService.isJukeboxEnabled()) { @@ -235,7 +244,7 @@ public class DownloadServiceLifecycleSupport public void serializeDownloadQueueNow() { - List songs = new ArrayList(downloadService.getSongs()); + Iterable songs = new ArrayList(downloadService.getSongs()); State state = new State(); for (DownloadFile downloadFile : songs) { diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/OfflineMusicService.java b/src/com/thejoshwa/ultrasonic/androidapp/service/OfflineMusicService.java index f409b1cc..24de3c4d 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/OfflineMusicService.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/OfflineMusicService.java @@ -134,7 +134,7 @@ public class OfflineMusicService extends RESTMusicService } }); - return new Indexes(0L, Collections.emptyList(), artists); + return new Indexes(0L, ignoredArticlesString, Collections.emptyList(), artists); } @Override @@ -528,7 +528,7 @@ public class OfflineMusicService extends RESTMusicService } } - if (!server.equals(lastServer) && fileList.size() > 0) + if (!server.equals(lastServer) && !fileList.isEmpty()) { if (lastServer != null) { @@ -750,7 +750,7 @@ public class OfflineMusicService extends RESTMusicService return result; } - Random random = new Random(); + Random random = new java.security.SecureRandom(); for (int i = 0; i < size; i++) { File file = children.get(random.nextInt(children.size())); diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/RESTMusicService.java b/src/com/thejoshwa/ultrasonic/androidapp/service/RESTMusicService.java index 126df11d..cb08e549 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/RESTMusicService.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/RESTMusicService.java @@ -266,7 +266,7 @@ public class RESTMusicService implements MusicService return indexes; } - return cachedIndexes != null ? cachedIndexes : new Indexes(0, new ArrayList(), new ArrayList()); + return cachedIndexes != null ? cachedIndexes : new Indexes(0, null, new ArrayList(), new ArrayList()); } finally { @@ -313,7 +313,7 @@ public class RESTMusicService implements MusicService return indexes; } - return cachedArtists != null ? cachedArtists : new Indexes(0, new ArrayList(), new ArrayList()); + return cachedArtists != null ? cachedArtists : new Indexes(0, null, new ArrayList(), new ArrayList()); } finally { @@ -852,7 +852,7 @@ public class RESTMusicService implements MusicService Reader reader = getReaderForURL(context, VERSION_URL, null, null, null, progressListener); try { - return new VersionParser().parse(reader); + return VersionParser.parse(reader); } finally { @@ -997,7 +997,7 @@ public class RESTMusicService implements MusicService @Override public String getVideoUrl(Context context, String id, boolean useFlash) throws Exception { - StringBuilder builder = new StringBuilder(); + StringBuilder builder = new StringBuilder(5); if (useFlash) { builder.append(Util.getRestUrl(context, "videoPlayer")); diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/ServerTooOldException.java b/src/com/thejoshwa/ultrasonic/androidapp/service/ServerTooOldException.java index 8a3ffe04..6ab304c7 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/ServerTooOldException.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/ServerTooOldException.java @@ -35,7 +35,7 @@ public class ServerTooOldException extends Exception private static String createMessage(String text) { - StringBuilder builder = new StringBuilder(); + StringBuilder builder = new StringBuilder(25); if (text != null) { diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/parser/IndexesParser.java b/src/com/thejoshwa/ultrasonic/androidapp/service/parser/IndexesParser.java index c48bbeef..31205bf1 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/parser/IndexesParser.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/parser/IndexesParser.java @@ -18,20 +18,19 @@ */ package com.thejoshwa.ultrasonic.androidapp.service.parser; -import java.io.Reader; -import java.util.List; -import java.util.ArrayList; - -import org.xmlpull.v1.XmlPullParser; - import android.content.Context; +import android.util.Log; import com.thejoshwa.ultrasonic.androidapp.R; import com.thejoshwa.ultrasonic.androidapp.domain.Artist; import com.thejoshwa.ultrasonic.androidapp.domain.Indexes; import com.thejoshwa.ultrasonic.androidapp.util.ProgressListener; -import android.util.Log; +import org.xmlpull.v1.XmlPullParser; + +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; /** * @author Sindre Mehus @@ -75,7 +74,6 @@ public class IndexesParser extends AbstractParser else if ("index".equals(name)) { index = get("name"); - } else if ("artist".equals(name)) { @@ -121,6 +119,6 @@ public class IndexesParser extends AbstractParser String msg = getContext().getResources().getString(R.string.parser_artist_count, artists.size()); updateProgress(progressListener, msg); - return new Indexes(lastModified == null ? 0L : lastModified, shortcuts, artists); + return new Indexes(lastModified == null ? 0L : lastModified, ignoredArticles, shortcuts, artists); } } \ No newline at end of file diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java b/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java index 8df546d1..e6628c65 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java @@ -108,7 +108,7 @@ public class CacheCleaner private long getMinimumDelete(List files) { - if (files.size() == 0) + if (files.isEmpty()) { return 0L; } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/EntryByDiscAndTrackComparator.java b/src/com/thejoshwa/ultrasonic/androidapp/util/EntryByDiscAndTrackComparator.java index a0d88b05..42ff7e5b 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/EntryByDiscAndTrackComparator.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/EntryByDiscAndTrackComparator.java @@ -2,10 +2,13 @@ package com.thejoshwa.ultrasonic.androidapp.util; import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory; +import java.io.Serializable; import java.util.Comparator; -public class EntryByDiscAndTrackComparator implements Comparator +public class EntryByDiscAndTrackComparator implements Comparator, Serializable { + private static final long serialVersionUID = 5540441864560835223L; + @Override public int compare(MusicDirectory.Entry x, MusicDirectory.Entry y) { @@ -13,17 +16,9 @@ public class EntryByDiscAndTrackComparator implements Comparator b ? 1 : 0; } - private int compare(String a, String b) + private static int compare(String a, String b) { if (a == null && b == null) { return 0; } - if (a == null && b != null) + if (a == null) { return -1; } - if (a != null && b == null) + if (b == null) { return 1; } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/FileUtil.java b/src/com/thejoshwa/ultrasonic/androidapp/util/FileUtil.java index 08efeff3..d03373f7 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/FileUtil.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/FileUtil.java @@ -116,24 +116,28 @@ public class FileUtil if (albumArtDir == null || albumDir == null) { - return null; + return null; } String md5Hex = Util.md5Hex(albumDir.getPath()); return new File(albumArtDir, String.format("%s.jpeg", md5Hex)); } - public static Bitmap getAlbumArtBitmap(Context context, MusicDirectory.Entry entry, int size, boolean highQuality) { + public static Bitmap getAlbumArtBitmap(Context context, MusicDirectory.Entry entry, int size, boolean highQuality) + { File albumArtFile = getAlbumArtFile(context, entry); - if (albumArtFile != null && albumArtFile.exists()) { + if (albumArtFile != null && albumArtFile.exists()) + { final BitmapFactory.Options opt = new BitmapFactory.Options(); - if (size > 0) { + if (size > 0) + { opt.inJustDecodeBounds = true; BitmapFactory.decodeFile(albumArtFile.getPath(), opt); - if (highQuality) { + if (highQuality) + { opt.inDither = true; opt.inPreferQualityOverSpeed = true; } @@ -156,11 +160,13 @@ public class FileUtil { final BitmapFactory.Options opt = new BitmapFactory.Options(); - if (size > 0) { + if (size > 0) + { opt.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); - if (highQuality) { + if (highQuality) + { opt.inDither = true; opt.inPreferQualityOverSpeed = true; } @@ -171,7 +177,7 @@ public class FileUtil } Log.i("getSampledBitmap", String.valueOf(size)); - return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); + return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); } public static File getArtistDirectory(Context context, Artist artist) @@ -310,7 +316,7 @@ public class FileUtil */ private static String fileSystemSafe(String filename) { - if (filename == null || filename.trim().length() == 0) + if (filename == null || filename.trim().isEmpty()) { return "unnamed"; } @@ -332,7 +338,7 @@ public class FileUtil */ private static String fileSystemSafeDir(String path) { - if (path == null || path.trim().length() == 0) + if (path == null || path.trim().isEmpty()) { return ""; } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/ShufflePlayBuffer.java b/src/com/thejoshwa/ultrasonic/androidapp/util/ShufflePlayBuffer.java index f70e57c9..5b7d292a 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/ShufflePlayBuffer.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/ShufflePlayBuffer.java @@ -44,7 +44,7 @@ public class ShufflePlayBuffer private final ScheduledExecutorService executorService; private final List buffer = new ArrayList(); - private Context context; + private final Context context; private int currentServer; public ShufflePlayBuffer(Context context) diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/TimeSpanPicker.java b/src/com/thejoshwa/ultrasonic/androidapp/util/TimeSpanPicker.java index 2f4c7ad4..b582c196 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/TimeSpanPicker.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/TimeSpanPicker.java @@ -2,6 +2,7 @@ package com.thejoshwa.ultrasonic.androidapp.util; import android.content.Context; import android.content.res.Resources; +import android.text.Editable; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; @@ -28,19 +29,22 @@ public class TimeSpanPicker extends LinearLayout implements AdapterView.OnItemSe private Context context; private View dialog; - public TimeSpanPicker(Context context) { + public TimeSpanPicker(Context context) + { this(context, null); this.context = context; } - public TimeSpanPicker(Context context, AttributeSet attrs) { + public TimeSpanPicker(Context context, AttributeSet attrs) + { this(context, attrs, 0); this.context = context; } - public TimeSpanPicker(Context context, AttributeSet attrs, int defStyle) { + public TimeSpanPicker(Context context, AttributeSet attrs, int defStyle) + { super(context, attrs, defStyle); this.context = context; @@ -48,7 +52,7 @@ public class TimeSpanPicker extends LinearLayout implements AdapterView.OnItemSe final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); dialog = inflater.inflate(R.layout.time_span_dialog, this, true); - timeSpan = new TimeSpan(-1); + timeSpan = new TimeSpan(-1); timeSpanEditText = (EditText) dialog.findViewById(R.id.timeSpanEditText); timeSpanEditText.setText("0"); @@ -82,14 +86,7 @@ public class TimeSpanPicker extends LinearLayout implements AdapterView.OnItemSe public TimeSpan getTimeSpan() { - if (!timeSpanDisableCheckbox.isChecked()) - { - this.timeSpan = getTimeSpanFromDialog(this.context, dialog); - } - else - { - this.timeSpan = new TimeSpan(0); - } + this.timeSpan = !timeSpanDisableCheckbox.isChecked() ? getTimeSpanFromDialog(this.context, dialog) : new TimeSpan(0); return timeSpan; } @@ -120,7 +117,14 @@ public class TimeSpanPicker extends LinearLayout implements AdapterView.OnItemSe return -1; } - String timeSpanAmountString = timeSpanEditText.getText().toString(); + Editable text = timeSpanEditText.getText(); + + String timeSpanAmountString = null; + + if (text != null) + { + timeSpanAmountString = text.toString(); + } int timeSpanAmount = 0; @@ -163,7 +167,14 @@ public class TimeSpanPicker extends LinearLayout implements AdapterView.OnItemSe } String timeSpanType = (String) timeSpanSpinner.getSelectedItem(); - String timeSpanAmountString = timeSpanEditText.getText().toString(); + + Editable text = timeSpanEditText.getText(); + String timeSpanAmountString = null; + + if (text != null) + { + timeSpanAmountString = text.toString(); + } int timeSpanAmount = 0; @@ -208,8 +219,14 @@ public class TimeSpanPicker extends LinearLayout implements AdapterView.OnItemSe @Override public void onItemSelected(AdapterView parent, View view, int pos, long id) { - String timeSpanType = (String)parent.getItemAtPosition(pos); - String timeSpanAmountString = timeSpanEditText.getText().toString(); + String timeSpanType = (String) parent.getItemAtPosition(pos); + Editable text = timeSpanEditText.getText(); + if (text == null) + { + return; + } + + String timeSpanAmountString = text.toString(); int timeSpanAmount = 0; diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/TimeSpanPreference.java b/src/com/thejoshwa/ultrasonic/androidapp/util/TimeSpanPreference.java index 0de2f7b2..60736cb6 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/TimeSpanPreference.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/TimeSpanPreference.java @@ -38,7 +38,7 @@ public class TimeSpanPreference extends DialogPreference return persisted.replace(':', ' '); } - return this.context.getResources().getString(R.string.time_span_disabled) ; + return this.context.getResources().getString(R.string.time_span_disabled); } @Override @@ -49,7 +49,7 @@ public class TimeSpanPreference extends DialogPreference String persisted = getPersistedString(""); - if (!persisted.equals("")) + if (!"".equals(persisted)) { String[] split = COMPILE.split(persisted); @@ -75,7 +75,8 @@ public class TimeSpanPreference extends DialogPreference } @Override - protected void onDialogClosed(boolean positiveResult) { + protected void onDialogClosed(boolean positiveResult) + { super.onDialogClosed(positiveResult); String persisted = ""; diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/Util.java b/src/com/thejoshwa/ultrasonic/androidapp/util/Util.java index bf320a4b..af22b79d 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/Util.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/Util.java @@ -28,7 +28,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -75,8 +74,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; import java.security.MessageDigest; import java.text.DecimalFormat; import java.text.NumberFormat; @@ -439,7 +436,7 @@ public class Util extends DownloadActivity * @param input the InputStream to read from * @return the requested byte array * @throws NullPointerException if the input is null - * @throws java.io.IOException if an I/O error occurs + * @throws java.io.IOException if an I/O error occurs */ public static byte[] toByteArray(InputStream input) throws IOException { @@ -833,9 +830,9 @@ public class Util extends DownloadActivity } } - public static void startActivityWithoutTransition(Activity currentActivity, Class newActivitiy) + public static void startActivityWithoutTransition(Activity currentActivity, Class newActivity) { - startActivityWithoutTransition(currentActivity, new Intent(currentActivity, newActivitiy)); + startActivityWithoutTransition(currentActivity, new Intent(currentActivity, newActivity)); } public static void startActivityWithoutTransition(Activity currentActivity, Intent intent) @@ -846,18 +843,7 @@ public class Util extends DownloadActivity public static void disablePendingTransition(Activity activity) { - - // Activity.overridePendingTransition() was introduced in Android 2.0. Use reflection to maintain - // compatibility with 1.5. - try - { - Method method = Activity.class.getMethod("overridePendingTransition", int.class, int.class); - method.invoke(activity, 0, 0); - } - catch (Throwable x) - { - // Ignored - } + activity.overridePendingTransition(0, 0); } public static Drawable getDrawableFromAttribute(Context context, int attr) @@ -877,17 +863,7 @@ public class Util extends DownloadActivity public static Drawable createDrawableFromBitmap(Context context, Bitmap bitmap) { - // BitmapDrawable(Resources, Bitmap) was introduced in Android 1.6. Use reflection to maintain - // compatibility with 1.5. - try - { - Constructor constructor = BitmapDrawable.class.getConstructor(Resources.class, Bitmap.class); - return constructor.newInstance(context.getResources(), bitmap); - } - catch (Throwable x) - { - return new BitmapDrawable(context.getResources(), bitmap); - } + return new BitmapDrawable(context.getResources(), bitmap); } public static WifiManager.WifiLock createWifiLock(Context context, String tag) @@ -1393,7 +1369,7 @@ public class Util extends DownloadActivity public static boolean getGaplessPlaybackPreference(Context context) { SharedPreferences preferences = getPreferences(context); - return preferences.getBoolean(Constants.PREFERENCES_KEY_GAPLESS_PLAYBACK, true); + return preferences.getBoolean(Constants.PREFERENCES_KEY_GAPLESS_PLAYBACK, false); } public static boolean getShouldTransitionOnPlaybackPreference(Context context) @@ -1593,7 +1569,7 @@ public class Util extends DownloadActivity { SharedPreferences preferences = getPreferences(context); return preferences.getString(Constants.PREFERENCES_KEY_DEFAULT_SHARE_EXPIRATION, "0"); - } + } public static long getDefaultShareExpirationInMillis(Context context) { diff --git a/src/com/thejoshwa/ultrasonic/androidapp/view/PlaylistAdapter.java b/src/com/thejoshwa/ultrasonic/androidapp/view/PlaylistAdapter.java index 203c30f7..fd1fbbf0 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/view/PlaylistAdapter.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/view/PlaylistAdapter.java @@ -8,6 +8,7 @@ import com.thejoshwa.ultrasonic.androidapp.R; import com.thejoshwa.ultrasonic.androidapp.activity.SubsonicTabActivity; import com.thejoshwa.ultrasonic.androidapp.domain.Playlist; +import java.io.Serializable; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -36,8 +37,10 @@ public class PlaylistAdapter extends ArrayAdapter return view; } - public static class PlaylistComparator implements Comparator + public static class PlaylistComparator implements Comparator, Serializable { + private static final long serialVersionUID = -6201663557439120008L; + @Override public int compare(Playlist playlist1, Playlist playlist2) { diff --git a/src/com/thejoshwa/ultrasonic/androidapp/view/ShareAdapter.java b/src/com/thejoshwa/ultrasonic/androidapp/view/ShareAdapter.java index 308a8add..9443ac52 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/view/ShareAdapter.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/view/ShareAdapter.java @@ -8,6 +8,7 @@ import com.thejoshwa.ultrasonic.androidapp.R; import com.thejoshwa.ultrasonic.androidapp.activity.SubsonicTabActivity; import com.thejoshwa.ultrasonic.androidapp.domain.Share; +import java.io.Serializable; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -36,8 +37,10 @@ public class ShareAdapter extends ArrayAdapter return view; } - public static class ShareComparator implements Comparator + public static class ShareComparator implements Comparator, Serializable { + private static final long serialVersionUID = -7169409928471418921L; + @Override public int compare(Share share1, Share share2) { diff --git a/src/com/thejoshwa/ultrasonic/androidapp/view/SongView.java b/src/com/thejoshwa/ultrasonic/androidapp/view/SongView.java index a2267294..b0bc563d 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/view/SongView.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/view/SongView.java @@ -61,7 +61,6 @@ public class SongView extends UpdateView implements Checkable private CheckedTextView checkedTextView; private ImageView starImageView; - private ImageView songDragImageView; private TextView titleTextView; private TextView statusTextView; private Entry song; @@ -141,7 +140,7 @@ public class SongView extends UpdateView implements Checkable checkedTextView = (CheckedTextView) findViewById(R.id.song_check); starImageView = (ImageView) findViewById(R.id.song_star); - songDragImageView = (ImageView) findViewById(R.id.song_drag); + ImageView songDragImageView = (ImageView) findViewById(R.id.song_drag); TextView trackTextView = (TextView) findViewById(R.id.song_track); titleTextView = (TextView) findViewById(R.id.song_title); TextView artistTextView = (TextView) findViewById(R.id.song_artist);