diff options
author | Scott Jackson <daneren2005@gmail.com> | 2013-02-24 08:36:22 -0800 |
---|---|---|
committer | Scott Jackson <daneren2005@gmail.com> | 2013-02-24 08:36:22 -0800 |
commit | a8f5f2803019cd4bcfed015ec8dbd10b034283f8 (patch) | |
tree | e1a280c83efdfc126d78ffcf1e1e03e09f7d963a /subsonic-android/src | |
parent | 70084659b4e021c089bdf6809c48604c24897820 (diff) | |
parent | 7f490872cdbf8301892fe9d06a9b164c18764409 (diff) | |
download | dsub-a8f5f2803019cd4bcfed015ec8dbd10b034283f8.tar.gz dsub-a8f5f2803019cd4bcfed015ec8dbd10b034283f8.tar.bz2 dsub-a8f5f2803019cd4bcfed015ec8dbd10b034283f8.zip |
Merge branch 'master' into Experimental
Diffstat (limited to 'subsonic-android/src')
13 files changed, 161 insertions, 50 deletions
diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java index a4222ce5..954a3f02 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java @@ -36,6 +36,7 @@ import android.graphics.Color; import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; +import android.os.Parcelable; import android.util.Log; import android.view.ContextMenu; import android.view.Display; @@ -81,6 +82,7 @@ import github.daneren2005.dsub.util.*; import github.daneren2005.dsub.view.AutoRepeatButton; import java.util.ArrayList; import java.util.concurrent.ScheduledFuture; +import com.mobeta.android.dslv.*; public class DownloadActivity extends SubsonicTabActivity implements OnGestureListener { private static final String TAG = DownloadActivity.class.getSimpleName(); @@ -95,7 +97,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi private TextView emptyTextView; private TextView songTitleTextView; private ImageView albumArtImageView; - private ListView playlistView; + private DragSortListView playlistView; private TextView positionTextView; private TextView durationTextView; private TextView statusTextView; @@ -121,6 +123,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi private VisualizerView visualizerView; private boolean nowPlaying = true; private ScheduledFuture<?> hideControlsFuture; + private SongListAdapter songListAdapter; /** * Called when the activity is first created. @@ -145,7 +148,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi durationTextView = (TextView) findViewById(R.id.download_duration); statusTextView = (TextView) findViewById(R.id.download_status); progressBar = (HorizontalSlider) findViewById(R.id.download_progress_bar); - playlistView = (ListView) findViewById(R.id.download_list); + playlistView = (DragSortListView) findViewById(R.id.download_list); previousButton = (AutoRepeatButton)findViewById(R.id.download_previous); nextButton = (AutoRepeatButton)findViewById(R.id.download_next); pauseButton = findViewById(R.id.download_pause); @@ -344,6 +347,20 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi } } }); + playlistView.setDropListener(new DragSortListView.DropListener() { + @Override + public void drop(int from, int to) { + getDownloadService().swap(from, to); + onDownloadListChanged(); + } + }); + playlistView.setRemoveListener(new DragSortListView.RemoveListener() { + @Override + public void remove(int which) { + getDownloadService().remove(which); + onDownloadListChanged(); + } + }); registerForContextMenu(playlistView); @@ -783,25 +800,35 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi } } } - - private void onDownloadListChanged() { + private void onDownloadListChanged() { + onDownloadListChanged(false); + } + private void onDownloadListChanged(boolean refresh) { DownloadService downloadService = getDownloadService(); if (downloadService == null) { return; } List<DownloadFile> list; - if(nowPlaying) + if(nowPlaying) { list = downloadService.getSongs(); - else + } + else { list = downloadService.getBackgroundDownloads(); + } - if(downloadService.isShufflePlayEnabled()) + if(downloadService.isShufflePlayEnabled()) { emptyTextView.setText(R.string.download_shuffle_loading); - else + } + else { emptyTextView.setText(R.string.download_empty); + } - playlistView.setAdapter(new SongListAdapter(list)); + if(songListAdapter == null || refresh) { + playlistView.setAdapter(songListAdapter = new SongListAdapter(list)); + } else { + songListAdapter.notifyDataSetChanged(); + } emptyTextView.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE); currentRevision = downloadService.getDownloadListUpdateRevision(); @@ -1004,7 +1031,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi private void toggleNowPlaying() { nowPlaying = !nowPlaying; setTitle(nowPlaying ? "Now Playing" : "Downloading"); - onDownloadListChanged(); + onDownloadListChanged(true); } @Override diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java index 392401bf..46a32ed4 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java @@ -38,6 +38,7 @@ import github.daneren2005.dsub.R; import github.daneren2005.dsub.domain.MusicDirectory; import github.daneren2005.dsub.service.*; import github.daneren2005.dsub.util.*; +import com.mobeta.android.dslv.*; import java.io.File; import java.util.*; @@ -46,13 +47,15 @@ public class SelectAlbumActivity extends SubsonicTabActivity { private static final String TAG = SelectAlbumActivity.class.getSimpleName(); - private ListView entryList; + private DragSortListView entryList; private View footer; private View emptyView; private boolean hideButtons = false; private Button moreButton; private Boolean licenseValid; private boolean showHeader = true; + private EntryAdapter entryAdapter; + private List<MusicDirectory.Entry> entries; /** * Called when the activity is first created. @@ -62,7 +65,7 @@ public class SelectAlbumActivity extends SubsonicTabActivity { super.onCreate(savedInstanceState); setContentView(R.layout.select_album); - entryList = (ListView) findViewById(R.id.select_album_entries); + entryList = (DragSortListView) findViewById(R.id.select_album_entries); footer = LayoutInflater.from(this).inflate(R.layout.select_album_footer, entryList, false); entryList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); @@ -86,6 +89,20 @@ public class SelectAlbumActivity extends SubsonicTabActivity { } } }); + entryList.setDropListener(new DragSortListView.DropListener() { + @Override + public void drop(int from, int to) { + int max = entries.size(); + if(to >= max) { + to = max - 1; + } + else if(to < 0) { + to = 0; + } + entries.add(to, entries.remove(from)); + entryAdapter.notifyDataSetChanged(); + } + }); moreButton = (Button) footer.findViewById(R.id.select_album_more); emptyView = findViewById(R.id.select_album_empty); @@ -677,7 +694,7 @@ public class SelectAlbumActivity extends SubsonicTabActivity { @Override protected void done(Pair<MusicDirectory, Boolean> result) { - List<MusicDirectory.Entry> entries = result.getFirst().getChildren(); + entries = result.getFirst().getChildren(); int songCount = 0; for (MusicDirectory.Entry entry : entries) { @@ -695,7 +712,7 @@ public class SelectAlbumActivity extends SubsonicTabActivity { } emptyView.setVisibility(entries.isEmpty() ? View.VISIBLE : View.GONE); - entryList.setAdapter(new EntryAdapter(SelectAlbumActivity.this, getImageLoader(), entries, true)); + entryList.setAdapter(entryAdapter = new EntryAdapter(SelectAlbumActivity.this, getImageLoader(), entries, true)); licenseValid = result.getSecond(); invalidateOptionsMenu(); @@ -753,12 +770,16 @@ public class SelectAlbumActivity extends SubsonicTabActivity { @Override protected void done(Void result) { - refresh(); + for(int i = indexes.size() - 1; i >= 0; i--) { + entryList.setItemChecked(indexes.get(i) + 1, false); + entryAdapter.removeAt(indexes.get(i)); + } + entryAdapter.notifyDataSetChanged(); Util.toast(SelectAlbumActivity.this, getResources().getString(R.string.removed_playlist, indexes.size(), name)); } @Override - protected void error(Throwable error) { + protected void error(Throwable error) { String msg; if (error instanceof OfflineException || error instanceof ServerTooOldException) { msg = getErrorMessage(error); diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/SelectPlaylistActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/SelectPlaylistActivity.java index d7deb610..5870f286 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/SelectPlaylistActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/SelectPlaylistActivity.java @@ -43,6 +43,7 @@ import java.util.List; public class SelectPlaylistActivity extends SubsonicTabActivity implements AdapterView.OnItemClickListener { private ListView list; private View emptyTextView; + private PlaylistAdapter playlistAdapter; @Override public void onCreate(Bundle savedInstanceState) { @@ -116,7 +117,7 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt @Override protected void done(List<Playlist> result) { - list.setAdapter(new PlaylistAdapter(SelectPlaylistActivity.this, result)); + list.setAdapter(playlistAdapter = new PlaylistAdapter(SelectPlaylistActivity.this, result)); emptyTextView.setVisibility(result.isEmpty() ? View.VISIBLE : View.GONE); } }; @@ -206,7 +207,8 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt @Override protected void done(Void result) { - refresh(); + playlistAdapter.remove(playlist); + playlistAdapter.notifyDataSetChanged(); Util.toast(SelectPlaylistActivity.this, getResources().getString(R.string.menu_deleted_playlist, playlist.getName())); } diff --git a/subsonic-android/src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java b/subsonic-android/src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java index cdbe8c4d..9796971f 100644 --- a/subsonic-android/src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java +++ b/subsonic-android/src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java @@ -40,5 +40,11 @@ public class MediaButtonIntentReceiver extends BroadcastReceiver { Intent serviceIntent = new Intent(context, DownloadServiceImpl.class); serviceIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); context.startService(serviceIntent); + + try { + abortBroadcast(); + } catch (Exception x) { + // Ignored. + } } } diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadService.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadService.java index 0536c198..889d7d2b 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadService.java @@ -60,6 +60,8 @@ public interface DownloadService { void clearIncomplete(); int size(); + + void remove(int which); void remove(DownloadFile downloadFile); @@ -130,4 +132,6 @@ public interface DownloadService { boolean getSleepTimer(); void setVolume(float volume); + + void swap(int from, int to); } diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java index 8b87d46a..93af3bf4 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java @@ -446,6 +446,11 @@ public class DownloadServiceImpl extends Service implements DownloadService { updateJukeboxPlaylist(); setNextPlaying(); } + + @Override + public synchronized void remove(int which) { + downloadList.remove(which); + } @Override public synchronized void remove(DownloadFile downloadFile) { @@ -558,9 +563,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { @Override public synchronized List<DownloadFile> getSongs() { - List<DownloadFile> temp = new ArrayList<DownloadFile>(); - temp.addAll(downloadList); - return temp; + return downloadList; } @Override @@ -573,9 +576,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { @Override public synchronized List<DownloadFile> getBackgroundDownloads() { - List<DownloadFile> temp = new ArrayList<DownloadFile>(); - temp.addAll(backgroundDownloadList); - return temp; + return backgroundDownloadList; } /** Plays either the current song (resume) or the first/next one in queue. */ @@ -1119,6 +1120,22 @@ public class DownloadServiceImpl extends Service implements DownloadService { mediaPlayer.setVolume(volume, volume); } } + + @Override + public synchronized void swap(int from, int to) { + int max = size(); + if(to >= max) { + to = max - 1; + } + else if(to < 0) { + to = 0; + } + + downloadList.add(to, downloadList.remove(from)); + if(jukeboxEnabled) { + updateJukeboxPlaylist(); + } + } private void handleError(Exception x) { Log.w(TAG, "Media player error: " + x, x); diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java index 6ff45dee..e04fc00c 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java @@ -30,6 +30,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.RemoteControlClient; +import android.os.AsyncTask; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; @@ -181,15 +182,7 @@ public class DownloadServiceLifecycleSupport { } public void serializeDownloadQueue() { - State state = new State(); - for (DownloadFile downloadFile : downloadService.getSongs()) { - state.songs.add(downloadFile.getSong()); - } - state.currentPlayingIndex = downloadService.getCurrentPlayingIndex(); - state.currentPlayingPosition = downloadService.getPlayerPosition(); - - Log.i(TAG, "Serialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); - FileUtil.serialize(downloadService, state, FILENAME_DOWNLOADS_SER); + new SerializeTask().execute(); } private void deserializeDownloadQueue() { @@ -277,4 +270,22 @@ public class DownloadServiceLifecycleSupport { private int currentPlayingIndex; private int currentPlayingPosition; } + + private class SerializeTask extends AsyncTask<Void, Void, Void> { + @Override + protected Void doInBackground(Void... params) { + List<DownloadFile> songs = new ArrayList<DownloadFile>(downloadService.getSongs()); + State state = new State(); + for (DownloadFile downloadFile : songs) { + state.songs.add(downloadFile.getSong()); + } + state.currentPlayingIndex = downloadService.getCurrentPlayingIndex(); + state.currentPlayingPosition = downloadService.getPlayerPosition(); + + Log.i(TAG, "Serialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); + FileUtil.serialize(downloadService, state, FILENAME_DOWNLOADS_SER); + + return null; + } + } }
\ No newline at end of file diff --git a/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java b/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java index a62920b9..69cdb642 100644 --- a/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java +++ b/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java @@ -60,10 +60,18 @@ public class Updater { }
}
+ public String getName() {
+ return this.TAG;
+ }
+
private class BackgroundUpdate extends AsyncTask<Updater, Void, Void> {
@Override
protected Void doInBackground(Updater... params) {
- params[0].update(context);
+ try {
+ params[0].update(context);
+ } catch(Exception e) {
+ Log.w(TAG, "Failed to run update for " + params[0].getName());
+ }
return null;
}
}
diff --git a/subsonic-android/src/github/daneren2005/dsub/updates/Updater373.java b/subsonic-android/src/github/daneren2005/dsub/updates/Updater373.java index 4df31580..b56c2731 100644 --- a/subsonic-android/src/github/daneren2005/dsub/updates/Updater373.java +++ b/subsonic-android/src/github/daneren2005/dsub/updates/Updater373.java @@ -29,9 +29,10 @@ import java.io.File; *
* @author Scott
*/
-public class Updater373 extends Updater {
+public class Updater373 extends Updater {
public Updater373() {
super(373);
+ TAG = Updater373.class.getSimpleName();
}
@Override
@@ -39,7 +40,9 @@ public class Updater373 extends Updater { // Rename cover.jpeg to cover.jpg
Log.i(TAG, "Running Updater373: updating cover.jpeg to cover.jpg");
File dir = FileUtil.getMusicDirectory(context);
- moveArt(dir);
+ if(dir != null) {
+ moveArt(dir);
+ }
}
private void moveArt(File dir) {
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/ImageLoader.java b/subsonic-android/src/github/daneren2005/dsub/util/ImageLoader.java index 4c3b256b..8e014afe 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/ImageLoader.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/ImageLoader.java @@ -64,7 +64,7 @@ public class ImageLoader implements Runnable { public ImageLoader(Context context) { this.context = context; final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); - final int cacheSize = maxMemory / 2; + final int cacheSize = maxMemory / 4; cache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { @@ -253,7 +253,10 @@ public class ImageLoader implements Runnable { try { MusicService musicService = MusicServiceFactory.getMusicService(mContext); Bitmap bitmap = musicService.getCoverArt(mContext, mEntry, mSize, mSaveSize, null); - cache.put(getKey(mEntry.getCoverArt(), mSize), bitmap); + String key = getKey(mEntry.getCoverArt(), mSize); + cache.put(key, bitmap); + // Make sure key is the most recently "used" + cache.get(key); final Drawable drawable = Util.createDrawableFromBitmap(mContext, bitmap); mTaskHandler.setDrawable(drawable); diff --git a/subsonic-android/src/github/daneren2005/dsub/util/ModalBackgroundTask.java b/subsonic-android/src/github/daneren2005/dsub/util/ModalBackgroundTask.java index 973f4ead..1954c474 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/ModalBackgroundTask.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/ModalBackgroundTask.java @@ -129,11 +129,13 @@ public abstract class ModalBackgroundTask<T> extends BackgroundTask<T> { @Override public void updateProgress(final String message) { - getHandler().post(new Runnable() { - @Override - public void run() { - progressDialog.setMessage(message); - } - }); + if(!cancelled) { + getHandler().post(new Runnable() { + @Override + public void run() { + progressDialog.setMessage(message); + } + }); + } } } diff --git a/subsonic-android/src/github/daneren2005/dsub/view/EntryAdapter.java b/subsonic-android/src/github/daneren2005/dsub/view/EntryAdapter.java index 6d2c7a63..476d3478 100644 --- a/subsonic-android/src/github/daneren2005/dsub/view/EntryAdapter.java +++ b/subsonic-android/src/github/daneren2005/dsub/view/EntryAdapter.java @@ -37,13 +37,19 @@ public class EntryAdapter extends ArrayAdapter<MusicDirectory.Entry> { private final SubsonicTabActivity activity; private final ImageLoader imageLoader; private final boolean checkable; + private List<MusicDirectory.Entry> entries; public EntryAdapter(SubsonicTabActivity activity, ImageLoader imageLoader, List<MusicDirectory.Entry> entries, boolean checkable) { super(activity, android.R.layout.simple_list_item_1, entries); + this.entries = entries; this.activity = activity; this.imageLoader = imageLoader; this.checkable = checkable; } + + public void removeAt(int position) { + entries.remove(position); + } @Override public View getView(int position, View convertView, ViewGroup parent) { @@ -51,12 +57,7 @@ public class EntryAdapter extends ArrayAdapter<MusicDirectory.Entry> { if (entry.isDirectory()) { AlbumView view; - // TODO: Reuse AlbumView objects once cover art loading is working. -// if (convertView != null && convertView instanceof AlbumView) { -// view = (AlbumView) convertView; -// } else { - view = new AlbumView(activity); -// } + view = new AlbumView(activity); view.setAlbum(entry, imageLoader); return view; diff --git a/subsonic-android/src/github/daneren2005/dsub/view/UpdateView.java b/subsonic-android/src/github/daneren2005/dsub/view/UpdateView.java index fee37ff0..9fbaccf6 100644 --- a/subsonic-android/src/github/daneren2005/dsub/view/UpdateView.java +++ b/subsonic-android/src/github/daneren2005/dsub/view/UpdateView.java @@ -21,6 +21,8 @@ package github.daneren2005.dsub.view; import android.content.Context;
import android.os.Handler;
import android.util.Log;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
import android.widget.LinearLayout;
import java.util.WeakHashMap;
@@ -32,6 +34,10 @@ public class UpdateView extends LinearLayout { public UpdateView(Context context) {
super(context);
+ setLayoutParams(new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+
INSTANCES.put(this, null);
int instanceCount = INSTANCES.size();
if (instanceCount > 50) {
|