Add a new smart playlist "Not played lately" playlist (#613)
* Add "Not played lately" playlist (#1) * Fix bad recent playlist construction (#6) * Revert History rename * Code review
This commit is contained in:
parent
71f5072624
commit
764751381a
9 changed files with 126 additions and 8 deletions
|
|
@ -18,7 +18,7 @@ public class LastAddedLoader {
|
|||
}
|
||||
|
||||
public static Cursor makeLastAddedCursor(@NonNull final Context context) {
|
||||
long cutoff = PreferenceUtil.getInstance(context).getLastAddedCutoff();
|
||||
long cutoff = PreferenceUtil.getInstance(context).getLastAddedCutoffTimeSecs();
|
||||
|
||||
return SongLoader.makeSongCursor(
|
||||
context,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package com.kabouzeid.gramophone.loader;
|
|||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.provider.BaseColumns;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
|
|
@ -26,6 +27,8 @@ import com.kabouzeid.gramophone.model.Song;
|
|||
import com.kabouzeid.gramophone.provider.HistoryStore;
|
||||
import com.kabouzeid.gramophone.provider.SongPlayCountStore;
|
||||
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TopAndRecentlyPlayedTracksLoader {
|
||||
|
|
@ -36,6 +39,23 @@ public class TopAndRecentlyPlayedTracksLoader {
|
|||
return SongLoader.getSongs(makeRecentTracksCursorAndClearUpDatabase(context));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ArrayList<Song> getNotRecentlyPlayedTracks
|
||||
(@NonNull Context context) {
|
||||
ArrayList<Song> allSongs = SongLoader.getSongs(
|
||||
SongLoader.makeSongCursor(
|
||||
context,
|
||||
null, null,
|
||||
MediaStore.Audio.Media.DATE_ADDED + " ASC"));
|
||||
|
||||
ArrayList<Song> recentlyPlayedSongs = SongLoader.getSongs(
|
||||
makeRecentTracksCursorAndClearUpDatabase(context));
|
||||
|
||||
allSongs.removeAll(recentlyPlayedSongs);
|
||||
|
||||
return allSongs;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ArrayList<Song> getTopTracks(@NonNull Context context) {
|
||||
return SongLoader.getSongs(makeTopTracksCursorAndClearUpDatabase(context));
|
||||
|
|
@ -76,7 +96,8 @@ public class TopAndRecentlyPlayedTracksLoader {
|
|||
@Nullable
|
||||
private static SortedLongCursor makeRecentTracksCursorImpl(@NonNull final Context context) {
|
||||
// first get the top results ids from the internal database
|
||||
Cursor songs = HistoryStore.getInstance(context).queryRecentIds();
|
||||
final long cutoff = PreferenceUtil.getInstance(context).getRecentlyPlayedCutoffTimeMillis();
|
||||
Cursor songs = HistoryStore.getInstance(context).queryRecentIds(cutoff);
|
||||
|
||||
try {
|
||||
return makeSortedCursor(context, songs,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
package com.kabouzeid.gramophone.model.smartplaylist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcel;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.loader.TopAndRecentlyPlayedTracksLoader;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.provider.HistoryStore;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author SC (soncaokim)
|
||||
*/
|
||||
public class NotRecentlyPlayedPlaylist extends AbsSmartPlaylist {
|
||||
|
||||
public NotRecentlyPlayedPlaylist(@NonNull Context context) {
|
||||
super(context.getString(R.string.not_recently_played), R.drawable.ic_library_music_white_24dp);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<Song> getSongs(@NonNull Context context) {
|
||||
return TopAndRecentlyPlayedTracksLoader.getNotRecentlyPlayedTracks(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(@NonNull Context context) {
|
||||
HistoryStore.getInstance(context).clear();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected NotRecentlyPlayedPlaylist(Parcel in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public static final Creator<NotRecentlyPlayedPlaylist> CREATOR = new Creator<NotRecentlyPlayedPlaylist>() {
|
||||
public NotRecentlyPlayedPlaylist createFromParcel(Parcel source) {
|
||||
return new NotRecentlyPlayedPlaylist(source);
|
||||
}
|
||||
|
||||
public NotRecentlyPlayedPlaylist[] newArray(int size) {
|
||||
return new NotRecentlyPlayedPlaylist[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ import android.support.annotation.NonNull;
|
|||
import android.support.annotation.Nullable;
|
||||
|
||||
public class HistoryStore extends SQLiteOpenHelper {
|
||||
private static final int MAX_ITEMS_IN_DB = 100;
|
||||
private static final int MAX_ITEMS_IN_DB = 5000;
|
||||
|
||||
public static final String DATABASE_NAME = "history.db";
|
||||
private static final int VERSION = 1;
|
||||
|
|
@ -136,10 +136,14 @@ public class HistoryStore extends SQLiteOpenHelper {
|
|||
return containsId;
|
||||
}
|
||||
|
||||
public Cursor queryRecentIds() {
|
||||
public Cursor queryRecentIds(long cutoff) {
|
||||
final SQLiteDatabase database = getReadableDatabase();
|
||||
|
||||
return database.query(RecentStoreColumns.NAME,
|
||||
new String[]{RecentStoreColumns.ID}, null, null, null, null,
|
||||
new String[]{RecentStoreColumns.ID},
|
||||
RecentStoreColumns.TIME_PLAYED + ">?",
|
||||
new String[]{String.valueOf(cutoff)},
|
||||
null, null,
|
||||
RecentStoreColumns.TIME_PLAYED + " DESC");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.kabouzeid.gramophone.model.Playlist;
|
|||
import com.kabouzeid.gramophone.model.smartplaylist.HistoryPlaylist;
|
||||
import com.kabouzeid.gramophone.model.smartplaylist.LastAddedPlaylist;
|
||||
import com.kabouzeid.gramophone.model.smartplaylist.MyTopTracksPlaylist;
|
||||
import com.kabouzeid.gramophone.model.smartplaylist.NotRecentlyPlayedPlaylist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
|
@ -80,6 +81,7 @@ public class PlaylistsFragment extends AbsLibraryPagerRecyclerViewFragment<Playl
|
|||
|
||||
playlists.add(new LastAddedPlaylist(context));
|
||||
playlists.add(new HistoryPlaylist(context));
|
||||
playlists.add(new NotRecentlyPlayedPlaylist(context));
|
||||
playlists.add(new MyTopTracksPlaylist(context));
|
||||
|
||||
playlists.addAll(PlaylistLoader.getAllPlaylists(context));
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ public final class PreferenceUtil {
|
|||
public static final String GAPLESS_PLAYBACK = "gapless_playback";
|
||||
|
||||
public static final String LAST_ADDED_CUTOFF = "last_added_interval";
|
||||
public static final String RECENTLY_PLAYED_CUTOFF = "recently_played_interval";
|
||||
|
||||
public static final String ALBUM_ART_ON_LOCKSCREEN = "album_art_on_lockscreen";
|
||||
public static final String BLURRED_ALBUM_ART = "blurred_album_art";
|
||||
|
|
@ -266,11 +267,21 @@ public final class PreferenceUtil {
|
|||
return mPreferences.getString(GENRE_SORT_ORDER, SortOrder.GenreSortOrder.GENRE_A_Z);
|
||||
}
|
||||
|
||||
public long getLastAddedCutoff() {
|
||||
// The last added cutoff time is compared against the Android media store timestamps, which is seconds based.
|
||||
public long getLastAddedCutoffTimeSecs() {
|
||||
return getCutoffTimeMillis(LAST_ADDED_CUTOFF) / 1000;
|
||||
}
|
||||
|
||||
// The recently played cutoff time is compared against the internal (private) database timestamps, which is milliseconds based.
|
||||
public long getRecentlyPlayedCutoffTimeMillis() {
|
||||
return getCutoffTimeMillis(RECENTLY_PLAYED_CUTOFF);
|
||||
}
|
||||
|
||||
private long getCutoffTimeMillis(final String cutoff) {
|
||||
final CalendarUtil calendarUtil = new CalendarUtil();
|
||||
long interval;
|
||||
|
||||
switch (mPreferences.getString(LAST_ADDED_CUTOFF, "")) {
|
||||
switch (mPreferences.getString(cutoff, "")) {
|
||||
case "today":
|
||||
interval = calendarUtil.getElapsedToday();
|
||||
break;
|
||||
|
|
@ -293,7 +304,7 @@ public final class PreferenceUtil {
|
|||
break;
|
||||
}
|
||||
|
||||
return (System.currentTimeMillis() - interval) / 1000;
|
||||
return (System.currentTimeMillis() - interval);
|
||||
}
|
||||
|
||||
public int getLastSleepTimerValue() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue