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;
}