diff --git a/src/org/kreed/vanilla/PlaybackService.java b/src/org/kreed/vanilla/PlaybackService.java index f7076bfb..ce5e4b05 100644 --- a/src/org/kreed/vanilla/PlaybackService.java +++ b/src/org/kreed/vanilla/PlaybackService.java @@ -565,7 +565,10 @@ public final class PlaybackService extends Service implements Handler.Callback, Song song = mTimeline.shiftCurrentSong(delta); if (song == null) { - setFlag(FLAG_NO_MEDIA); + if (Song.isSongAvailable()) + setCurrentSong(+1); // we only encountered a bad song; skip it + else + setFlag(FLAG_NO_MEDIA); // we don't have any songs : / return; } else if ((mState & FLAG_NO_MEDIA) != 0) { unsetFlag(FLAG_NO_MEDIA); diff --git a/src/org/kreed/vanilla/Song.java b/src/org/kreed/vanilla/Song.java index 82efcea3..0c68f236 100644 --- a/src/org/kreed/vanilla/Song.java +++ b/src/org/kreed/vanilla/Song.java @@ -59,6 +59,10 @@ public class Song implements Parcelable { */ private static final Song[] mRandomSongs = new Song[5]; + private static final String[] EMPTY_PROJECTION = { + MediaStore.Audio.Media._ID, + }; + private static final String[] FILLED_PROJECTION = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA, @@ -109,11 +113,11 @@ public class Song implements Parcelable { ContentResolver resolver = ContextApplication.getContext().getContentResolver(); Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0"; - Cursor cursor = resolver.query(media, FILLED_PROJECTION, selection, null, null); + Cursor cursor = resolver.query(media, EMPTY_PROJECTION, selection, null, null); return cursor != null && cursor.getCount() > 0; } - + /** * Returns a song randomly selected from all the songs in the Android * MediaStore. @@ -420,4 +424,4 @@ public class Song implements Parcelable { return null; } -} \ No newline at end of file +} diff --git a/src/org/kreed/vanilla/SongTimeline.java b/src/org/kreed/vanilla/SongTimeline.java index ce0c915e..f0560303 100644 --- a/src/org/kreed/vanilla/SongTimeline.java +++ b/src/org/kreed/vanilla/SongTimeline.java @@ -273,11 +273,11 @@ public final class SongTimeline { /** * Returns the song delta places away from the current * position. If there is no song at the given position, a random - * song will be placed in that position. Returns null if no songs are - * available. + * song will be placed in that position. Returns null if there is a problem + * retrieving the song (caused by either an empty library or stale song id). * * Note: This returns songs based on their position in the playback - * sequence, not necessarily the stored timeline. When repeat is enabled, + * sequence, not their position in the stored timeline. When repeat is enabled, * the two will differ. * * @param delta The offset from the current position. Should be -1, 0, or @@ -285,28 +285,24 @@ public final class SongTimeline { */ public Song getSong(int delta) { - if (!Song.isSongAvailable()) - return null; - ArrayList timeline = mSongs; - Song song; + Song song = null; synchronized (this) { int pos = mCurrentPos + delta; if (pos < 0) return null; - int size = timeline.size(); - if (pos > size) - return null; - - if (pos == size) { + while (pos >= timeline.size()) { song = Song.randomSong(); + if (song == null) + return null; timeline.add(song); - } else { - song = timeline.get(pos); } + if (song == null) + song = timeline.get(pos); + if (song != null && mRepeatStart != -1 && (song.flags & Song.FLAG_RANDOM) != 0) { if (delta == 1 && mRepeatStart < mCurrentPos + 1) { // We have reached a non-user-selected song; this song will @@ -336,15 +332,9 @@ public final class SongTimeline { } } - if (song == null) + if (!song.query(false)) + // we have a stale song id return null; - - if (!song.query(false)) { - song.copy(Song.randomSong()); - - if (song == null || !song.query(false)) - return null; - } return song; }