kotlin conversion

This commit is contained in:
h4h13 2018-11-30 06:36:16 +05:30
parent 8e6ab40d93
commit b2c15ef186
316 changed files with 13055 additions and 22983 deletions

View file

@ -1,104 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.provider.MediaStore.Audio.AudioColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import code.name.monkey.retromusic.model.Album;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.PreferenceUtil;
import io.reactivex.Observable;
import java.util.ArrayList;
/**
* Created by hemanths on 11/08/17.
*/
public class AlbumLoader {
public static Observable<ArrayList<Album>> getAllAlbums(@NonNull Context context) {
Observable<ArrayList<Song>> songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
context,
null,
null,
getSongLoaderSortOrder(context))
);
return splitIntoAlbums(songs);
}
@NonNull
public static Observable<ArrayList<Album>> getAlbums(@NonNull final Context context,
String query) {
Observable<ArrayList<Song>> songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
context,
AudioColumns.ALBUM + " LIKE ?",
new String[]{"%" + query + "%"},
getSongLoaderSortOrder(context))
);
return splitIntoAlbums(songs);
}
@NonNull
public static Observable<Album> getAlbum(@NonNull final Context context, int albumId) {
return Observable.create(e -> {
Observable<ArrayList<Song>> songs = SongLoader.Companion.getSongs(SongLoader.Companion
.makeSongCursor(context, AudioColumns.ALBUM_ID + "=?",
new String[]{String.valueOf(albumId)}, getSongLoaderSortOrder(context)));
songs.subscribe(songs1 -> {
e.onNext(new Album(songs1));
e.onComplete();
});
});
}
@NonNull
public static Observable<ArrayList<Album>> splitIntoAlbums(
@Nullable final Observable<ArrayList<Song>> songs) {
return Observable.create(e -> {
ArrayList<Album> albums = new ArrayList<>();
if (songs != null) {
songs.subscribe(songs1 -> {
for (Song song : songs1) {
getOrCreateAlbum(albums, song.albumId).subscribe(album -> album.songs.add(song));
}
});
}
e.onNext(albums);
e.onComplete();
});
}
@NonNull
public static ArrayList<Album> splitIntoAlbums(@Nullable final ArrayList<Song> songs) {
ArrayList<Album> albums = new ArrayList<>();
if (songs != null) {
for (Song song : songs) {
getOrCreateAlbum(albums, song.albumId).subscribe(album -> album.songs.add(song));
}
}
return albums;
}
private static Observable<Album> getOrCreateAlbum(ArrayList<Album> albums, int albumId) {
return Observable.create(e -> {
for (Album album : albums) {
if (!album.songs.isEmpty() && album.songs.get(0).albumId == albumId) {
e.onNext(album);
e.onComplete();
return;
}
}
Album album = new Album();
albums.add(album);
e.onNext(album);
e.onComplete();
});
}
public static String getSongLoaderSortOrder(Context context) {
return PreferenceUtil.getInstance().getAlbumSortOrder() + ", " +
//PreferenceUtil.getInstance().getAlbumSongSortOrder() + "," +
PreferenceUtil.getInstance().getAlbumDetailSongSortOrder();
}
}

View file

@ -0,0 +1,95 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.provider.MediaStore.Audio.AudioColumns
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.Observable
import java.util.*
/**
* Created by hemanths on 11/08/17.
*/
open class AlbumLoader {
companion object {
fun getAllAlbums(context: Context): Observable<ArrayList<Album>> {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context, null, null,
getSongLoaderSortOrder())
)
return splitIntoAlbums(songs)
}
fun getAlbums(context: Context,
query: String): Observable<ArrayList<Album>> {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ALBUM + " LIKE ?",
arrayOf("%$query%"),
getSongLoaderSortOrder())
)
return splitIntoAlbums(songs)
}
fun getAlbum(context: Context, albumId: Int): Observable<Album> {
return Observable.create { e ->
val songs = SongLoader.getSongs(SongLoader
.makeSongCursor(context, AudioColumns.ALBUM_ID + "=?",
arrayOf(albumId.toString()), getSongLoaderSortOrder()))
songs.subscribe { songs1 ->
e.onNext(Album(songs1))
e.onComplete()
}
}
}
fun splitIntoAlbums(
songs: Observable<ArrayList<Song>>?): Observable<ArrayList<Album>> {
return Observable.create { e ->
val albums = ArrayList<Album>()
songs?.subscribe { songs1 ->
for (song in songs1) {
getOrCreateAlbum(albums, song.albumId).subscribe { album -> album.songs!!.add(song) }
}
}
e.onNext(albums)
e.onComplete()
}
}
fun splitIntoAlbums(songs: ArrayList<Song>?): ArrayList<Album> {
val albums = ArrayList<Album>()
if (songs != null) {
for (song in songs) {
getOrCreateAlbum(albums, song.albumId).subscribe { album -> album.songs!!.add(song) }
}
}
return albums
}
private fun getOrCreateAlbum(albums: ArrayList<Album>, albumId: Int): Observable<Album> {
return Observable.create { e ->
for (album in albums) {
if (!album.songs!!.isEmpty() && album.songs[0].albumId == albumId) {
e.onNext(album)
e.onComplete()
return@create
}
}
val album = Album()
albums.add(album)
e.onNext(album)
e.onComplete()
}
}
fun getSongLoaderSortOrder(): String {
return PreferenceUtil.getInstance().albumSortOrder + ", " +
//PreferenceUtil.getInstance().getAlbumSongSortOrder() + "," +
PreferenceUtil.getInstance().albumDetailSongSortOrder
}
}
}

View file

@ -1,101 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.provider.MediaStore.Audio.AudioColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import code.name.monkey.retromusic.model.Album;
import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.util.PreferenceUtil;
import io.reactivex.Observable;
public class ArtistLoader {
private static String getSongLoaderSortOrder(Context context) {
return PreferenceUtil.getInstance().getArtistSortOrder() + ", " +
PreferenceUtil.getInstance().getArtistAlbumSortOrder() + ", " +
PreferenceUtil.getInstance().getAlbumDetailSongSortOrder() + ", " +
PreferenceUtil.getInstance().getArtistDetailSongSortOrder();
}
@NonNull
public static Observable<Artist> getArtist(@NonNull final Context context, int artistId) {
return Observable.create(e -> SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
context,
AudioColumns.ARTIST_ID + "=?",
new String[]{String.valueOf(artistId)},
getSongLoaderSortOrder(context)))
.subscribe(songs -> {
Artist artist = new Artist(AlbumLoader.splitIntoAlbums(songs));
e.onNext(artist);
e.onComplete();
}));
}
@NonNull
public static Observable<ArrayList<Artist>> getAllArtists(@NonNull final Context context) {
return Observable.create(e -> SongLoader.Companion
.getSongs(SongLoader.Companion.makeSongCursor(
context,
null,
null,
getSongLoaderSortOrder(context))
).subscribe(songs -> {
e.onNext(splitIntoArtists(AlbumLoader.splitIntoAlbums(songs)));
e.onComplete();
}));
}
@NonNull
public static Observable<ArrayList<Artist>> getArtists(@NonNull final Context context, String query) {
return Observable.create(e -> SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
context,
AudioColumns.ARTIST + " LIKE ?",
new String[]{"%" + query + "%"},
getSongLoaderSortOrder(context))
).subscribe(songs -> {
e.onNext(splitIntoArtists(AlbumLoader.splitIntoAlbums(songs)));
e.onComplete();
}));
}
@NonNull
public static ArrayList<Artist> splitIntoArtists(@Nullable final ArrayList<Album> albums) {
ArrayList<Artist> artists = new ArrayList<>();
if (albums != null) {
for (Album album : albums) {
getOrCreateArtist(artists, album.getArtistId()).albums.add(album);
}
}
return artists;
}
private static Artist getOrCreateArtist(ArrayList<Artist> artists, int artistId) {
for (Artist artist : artists) {
if (!artist.albums.isEmpty() && !artist.albums.get(0).songs.isEmpty() && artist.albums.get(0).songs.get(0).artistId == artistId) {
return artist;
}
}
Artist album = new Artist();
artists.add(album);
return album;
}
public static Observable<ArrayList<Artist>> splitIntoArtists(Observable<ArrayList<Album>> albums) {
return Observable.create(e -> {
ArrayList<Artist> artists = new ArrayList<>();
albums.subscribe(localAlbums -> {
if (localAlbums != null) {
for (Album album : localAlbums) {
getOrCreateArtist(artists, album.getArtistId()).albums.add(album);
}
}
e.onNext(artists);
e.onComplete();
});
});
}
}

View file

@ -0,0 +1,99 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.provider.MediaStore.Audio.AudioColumns
import java.util.ArrayList
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.Observable
object ArtistLoader {
private fun getSongLoaderSortOrder(): String {
return PreferenceUtil.getInstance().artistSortOrder + ", " +
PreferenceUtil.getInstance().artistAlbumSortOrder + ", " +
PreferenceUtil.getInstance().albumDetailSongSortOrder + ", " +
PreferenceUtil.getInstance().artistDetailSongSortOrder
}
fun getArtist(context: Context, artistId: Int): Observable<Artist> {
return Observable.create { e ->
SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST_ID + "=?",
arrayOf(artistId.toString()),
getSongLoaderSortOrder()))
.subscribe { songs ->
val artist = Artist(AlbumLoader.splitIntoAlbums(songs))
e.onNext(artist)
e.onComplete()
}
}
}
fun getAllArtists(context: Context): Observable<ArrayList<Artist>> {
return Observable.create { e ->
SongLoader
.getSongs(SongLoader.makeSongCursor(
context, null, null,
getSongLoaderSortOrder())
).subscribe { songs ->
e.onNext(splitIntoArtists(AlbumLoader.splitIntoAlbums(songs)))
e.onComplete()
}
}
}
fun getArtists(context: Context, query: String): Observable<ArrayList<Artist>> {
return Observable.create { e ->
SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST + " LIKE ?",
arrayOf("%$query%"),
getSongLoaderSortOrder())
).subscribe { songs ->
e.onNext(splitIntoArtists(AlbumLoader.splitIntoAlbums(songs)))
e.onComplete()
}
}
}
fun splitIntoArtists(albums: ArrayList<Album>?): ArrayList<Artist> {
val artists = ArrayList<Artist>()
if (albums != null) {
for (album in albums) {
getOrCreateArtist(artists, album.artistId).albums!!.add(album)
}
}
return artists
}
private fun getOrCreateArtist(artists: ArrayList<Artist>, artistId: Int): Artist {
for (artist in artists) {
if (!artist.albums!!.isEmpty() && !artist.albums[0].songs!!.isEmpty() && artist.albums[0].songs!![0].artistId == artistId) {
return artist
}
}
val album = Artist()
artists.add(album)
return album
}
fun splitIntoArtists(albums: Observable<ArrayList<Album>>): Observable<ArrayList<Artist>> {
return Observable.create { e ->
val artists = ArrayList<Artist>()
albums.subscribe { localAlbums ->
if (localAlbums != null) {
for (album in localAlbums) {
getOrCreateArtist(artists, album.artistId).albums!!.add(album)
}
}
e.onNext(artists)
e.onComplete()
}
}
}
}

View file

@ -1,37 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import androidx.annotation.NonNull;
import code.name.monkey.retromusic.model.Song;
import java.util.ArrayList;
import code.name.monkey.retromusic.util.PreferenceUtil;
import io.reactivex.Observable;
public class ArtistSongLoader extends SongLoader {
@NonNull
public static Observable<ArrayList<Song>> getArtistSongList(@NonNull final Context context, final int artistId) {
return Companion.getSongs(makeArtistSongCursor(context, artistId));
}
public static Cursor makeArtistSongCursor(@NonNull final Context context, final int artistId) {
try {
return Companion.makeSongCursor(
context,
MediaStore.Audio.AudioColumns.ARTIST_ID + "=?",
new String[]{
String.valueOf(artistId)
},
PreferenceUtil.getInstance().getArtistSongSortOrder()
);
} catch (SecurityException e) {
return null;
}
}
}

View file

@ -1,133 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore.Audio.Genres;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import code.name.monkey.retromusic.model.Genre;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.PreferenceUtil;
import io.reactivex.Observable;
public class GenreLoader {
@NonNull
public static Observable<ArrayList<Genre>> getAllGenres(@NonNull final Context context) {
return getGenresFromCursor(context, makeGenreCursor(context));
}
@NonNull
public static Observable<ArrayList<Song>> getSongs(@NonNull final Context context, final int genreId) {
// The genres table only stores songs that have a genre specified,
// so we need to get songs without a genre a different way.
if (genreId == -1) {
return getSongsWithNoGenre(context);
}
return SongLoader.Companion.getSongs(makeGenreSongCursor(context, genreId));
}
@NonNull
private static Genre getGenreFromCursor(@NonNull Context context, @NonNull final Cursor cursor) {
final int id = cursor.getInt(0);
final String name = cursor.getString(1);
final int songCount = getSongs(context, id).blockingFirst().size();
return new Genre(id, name, songCount);
}
@NonNull
private static Observable<ArrayList<Song>> getSongsWithNoGenre(@NonNull final Context context) {
String selection = BaseColumns._ID + " NOT IN " +
"(SELECT " + Genres.Members.AUDIO_ID + " FROM audio_genres_map)";
return SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, selection, null));
}
private static boolean hasSongsWithNoGenre(@NonNull final Context context) {
final Cursor allSongsCursor = SongLoader.Companion.makeSongCursor(context, null, null);
final Cursor allSongsWithGenreCursor = makeAllSongsWithGenreCursor(context);
if (allSongsCursor == null || allSongsWithGenreCursor == null) {
return false;
}
final boolean hasSongsWithNoGenre = allSongsCursor.getCount() > allSongsWithGenreCursor.getCount();
allSongsCursor.close();
allSongsWithGenreCursor.close();
return hasSongsWithNoGenre;
}
@Nullable
private static Cursor makeAllSongsWithGenreCursor(@NonNull final Context context) {
try {
return context.getContentResolver().query(
Uri.parse("content://media/external/audio/genres/all/members"),
new String[]{Genres.Members.AUDIO_ID}, null, null, null);
} catch (SecurityException e) {
return null;
}
}
@Nullable
private static Cursor makeGenreSongCursor(@NonNull final Context context, int genreId) {
try {
return context.getContentResolver().query(
Genres.Members.getContentUri("external", genreId),
SongLoader.Companion.getBASE_PROJECTION(), SongLoader.BASE_SELECTION, null, PreferenceUtil.getInstance().getSongSortOrder());
} catch (SecurityException e) {
return null;
}
}
@NonNull
private static Observable<ArrayList<Genre>> getGenresFromCursor(@NonNull final Context context, @Nullable final Cursor cursor) {
return Observable.create(e -> {
final ArrayList<Genre> genres = new ArrayList<>();
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
Genre genre = getGenreFromCursor(context, cursor);
if (genre.songCount > 0) {
genres.add(genre);
} else {
// try to remove the empty genre from the media store
try {
context.getContentResolver().delete(Genres.EXTERNAL_CONTENT_URI, Genres._ID + " == " + genre.id, null);
} catch (Exception ex) {
ex.printStackTrace();
// nothing we can do then
}
}
} while (cursor.moveToNext());
}
cursor.close();
}
e.onNext(genres);
e.onComplete();
});
}
@Nullable
private static Cursor makeGenreCursor(@NonNull final Context context) {
final String[] projection = new String[]{
Genres._ID,
Genres.NAME
};
try {
return context.getContentResolver().query(
Genres.EXTERNAL_CONTENT_URI,
projection, null, null, PreferenceUtil.getInstance().getGenreSortOrder());
} catch (SecurityException e) {
return null;
}
}
}

View file

@ -0,0 +1,123 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.BaseColumns
import android.provider.MediaStore.Audio.Genres
import code.name.monkey.retromusic.Constants.BASE_PROJECTION
import code.name.monkey.retromusic.Constants.BASE_SELECTION
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.Observable
import java.util.*
object GenreLoader {
fun getAllGenres(context: Context): Observable<ArrayList<Genre>> {
return getGenresFromCursor(context, makeGenreCursor(context))
}
fun getSongs(context: Context, genreId: Int): Observable<ArrayList<Song>> {
// The genres table only stores songs that have a genre specified,
// so we need to get songs without a genre a different way.
return if (genreId == -1) {
getSongsWithNoGenre(context)
} else SongLoader.getSongs(makeGenreSongCursor(context, genreId))
}
private fun getGenreFromCursor(context: Context, cursor: Cursor): Genre {
val id = cursor.getInt(0)
val name = cursor.getString(1)
val songCount = getSongs(context, id).blockingFirst().size
return Genre(id, name, songCount)
}
private fun getSongsWithNoGenre(context: Context): Observable<ArrayList<Song>> {
val selection = BaseColumns._ID + " NOT IN " +
"(SELECT " + Genres.Members.AUDIO_ID + " FROM audio_genres_map)"
return SongLoader.getSongs(SongLoader.makeSongCursor(context, selection, null))
}
private fun hasSongsWithNoGenre(context: Context): Boolean {
val allSongsCursor = SongLoader.makeSongCursor(context, null, null)
val allSongsWithGenreCursor = makeAllSongsWithGenreCursor(context)
if (allSongsCursor == null || allSongsWithGenreCursor == null) {
return false
}
val hasSongsWithNoGenre = allSongsCursor.count > allSongsWithGenreCursor.count
allSongsCursor.close()
allSongsWithGenreCursor.close()
return hasSongsWithNoGenre
}
private fun makeAllSongsWithGenreCursor(context: Context): Cursor? {
try {
return context.contentResolver.query(
Uri.parse("content://media/external/audio/genres/all/members"),
arrayOf(Genres.Members.AUDIO_ID), null, null, null)
} catch (e: SecurityException) {
return null
}
}
private fun makeGenreSongCursor(context: Context, genreId: Int): Cursor? {
try {
return context.contentResolver.query(
Genres.Members.getContentUri("external", genreId.toLong()),
BASE_PROJECTION, BASE_SELECTION, null, PreferenceUtil.getInstance().songSortOrder)
} catch (e: SecurityException) {
return null
}
}
private fun getGenresFromCursor(context: Context, cursor: Cursor?): Observable<ArrayList<Genre>> {
return Observable.create { e ->
val genres = ArrayList<Genre>()
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
val genre = getGenreFromCursor(context, cursor)
if (genre.songCount > 0) {
genres.add(genre)
} else {
// try to remove the empty genre from the media store
try {
context.contentResolver.delete(Genres.EXTERNAL_CONTENT_URI, Genres._ID + " == " + genre.id, null)
} catch (ex: Exception) {
ex.printStackTrace()
// nothing we can do then
}
}
} while (cursor.moveToNext())
}
cursor.close()
}
e.onNext(genres)
e.onComplete()
}
}
private fun makeGenreCursor(context: Context): Cursor? {
val projection = arrayOf(Genres._ID, Genres.NAME)
try {
return context.contentResolver.query(
Genres.EXTERNAL_CONTENT_URI,
projection, null, null, PreferenceUtil.getInstance().genreSortOrder)
} catch (e: SecurityException) {
return null
}
}
}

View file

@ -1,76 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AudioColumns;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import code.name.monkey.retromusic.model.Song;
import io.reactivex.Observable;
/**
* @author Hemanth S (h4h13).
*/
public class GenreSongsLoader {
public static Observable<ArrayList<Song>> getGenreSongsList(@NonNull Context context, int genreId) {
return Observable.create(e -> {
ArrayList<Song> list = new ArrayList<>();
Cursor cursor = makeGenreSongCursor(context, genreId);
if (cursor != null && cursor.moveToFirst()) {
do {
list.add(getGenreSongFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
e.onNext((ArrayList<Song>) (List) list);
e.onComplete();
});
}
@NonNull
private static Song getGenreSongFromCursorImpl(@NonNull Cursor cursor) {
final int id = cursor.getInt(0);
final String title = cursor.getString(1);
final int trackNumber = cursor.getInt(2);
final int year = cursor.getInt(3);
final long duration = cursor.getLong(4);
final String data = cursor.getString(5);
final int dateModified = cursor.getInt(6);
final int albumId = cursor.getInt(7);
final String albumName = cursor.getString(8);
final int artistId = cursor.getInt(9);
final String artistName = cursor.getString(10);
return new Song(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName, artistId, artistName);
}
private static Cursor makeGenreSongCursor(Context context, long genreId) {
try {
return context.getContentResolver().query(
MediaStore.Audio.Genres.Members.getContentUri("external", genreId),
new String[]{
MediaStore.Audio.Playlists.Members.AUDIO_ID,// 0
AudioColumns.TITLE,// 1
AudioColumns.TRACK,// 2
AudioColumns.YEAR,// 3
AudioColumns.DURATION,// 4
AudioColumns.DATA,// 5
AudioColumns.DATE_MODIFIED,// 6
AudioColumns.ALBUM_ID,// 7
AudioColumns.ALBUM,// 8
AudioColumns.ARTIST_ID,// 9
AudioColumns.ARTIST,// 10
}, SongLoader.BASE_SELECTION, null,
MediaStore.Audio.Genres.Members.DEFAULT_SORT_ORDER);
} catch (SecurityException e) {
return null;
}
}
}

View file

@ -1,63 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist;
import code.name.monkey.retromusic.model.smartplaylist.HistoryPlaylist;
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist;
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist;
import io.reactivex.Observable;
public class HomeLoader {
public static Observable<ArrayList<AbsSmartPlaylist>> getRecentAndTopThings(
@NonNull Context context) {
ArrayList<AbsSmartPlaylist> objects = new ArrayList<>();
return Observable.create(e -> {
new HistoryPlaylist(context).getSongs(context).subscribe(songs -> {
if (!songs.isEmpty()) {
objects.add(new HistoryPlaylist(context));
}
});
new LastAddedPlaylist(context).getSongs(context).subscribe(songs -> {
if (!songs.isEmpty()) {
objects.add(new LastAddedPlaylist(context));
}
});
new MyTopTracksPlaylist(context).getSongs(context).subscribe(songs -> {
if (!songs.isEmpty()) {
objects.add(new MyTopTracksPlaylist(context));
}
});
e.onNext(objects);
e.onComplete();
});
}
public static Observable<ArrayList<Playlist>> getHomeLoader(@NonNull Context context) {
ArrayList<Playlist> playlists = new ArrayList<>();
PlaylistLoader.getAllPlaylists(context)
.subscribe(playlists1 -> {
if (playlists1.size() > 0) {
for (Playlist playlist : playlists1) {
PlaylistSongsLoader.getPlaylistSongList(context, playlist)
.subscribe(songs -> {
if (songs.size() > 0) {
playlists.add(playlist);
}
});
}
}
});
return Observable.just(playlists);
}
}

View file

@ -0,0 +1,61 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import java.util.ArrayList
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
import code.name.monkey.retromusic.model.smartplaylist.HistoryPlaylist
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist
import io.reactivex.Observable
object HomeLoader {
fun getRecentAndTopThings(
context: Context): Observable<ArrayList<AbsSmartPlaylist>> {
val objects = ArrayList<AbsSmartPlaylist>()
return Observable.create { e ->
HistoryPlaylist(context).getSongs(context).subscribe { songs ->
if (!songs.isEmpty()) {
objects.add(HistoryPlaylist(context))
}
}
LastAddedPlaylist(context).getSongs(context).subscribe { songs ->
if (!songs.isEmpty()) {
objects.add(LastAddedPlaylist(context))
}
}
MyTopTracksPlaylist(context).getSongs(context).subscribe { songs ->
if (!songs.isEmpty()) {
objects.add(MyTopTracksPlaylist(context))
}
}
e.onNext(objects)
e.onComplete()
}
}
fun getHomeLoader(context: Context): Observable<ArrayList<Playlist>> {
val playlists = ArrayList<Playlist>()
PlaylistLoader.getAllPlaylists(context)
.subscribe { playlists1 ->
if (playlists1.size > 0) {
for (playlist in playlists1) {
PlaylistSongsLoader.getPlaylistSongList(context, playlist)
.subscribe { songs ->
if (songs.size > 0) {
playlists.add(playlist)
}
}
}
}
}
return Observable.just(playlists)
}
}

View file

@ -1,46 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import java.util.ArrayList;
import code.name.monkey.retromusic.model.Album;
import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.PreferenceUtil;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
/**
* Created by hemanths on 16/08/17.
*/
public class LastAddedSongsLoader {
@NonNull
public static Observable<ArrayList<Song>> getLastAddedSongs(@NonNull Context context) {
return SongLoader.Companion.getSongs(makeLastAddedCursor(context));
}
public static Cursor makeLastAddedCursor(@NonNull final Context context) {
long cutoff = PreferenceUtil.getInstance().getLastAddedCutoff();
return SongLoader.Companion.makeSongCursor(
context,
MediaStore.Audio.Media.DATE_ADDED + ">?",
new String[]{String.valueOf(cutoff)},
MediaStore.Audio.Media.DATE_ADDED + " DESC");
}
@NonNull
public static Observable<ArrayList<Album>> getLastAddedAlbums(@NonNull Context context) {
return AlbumLoader.splitIntoAlbums(getLastAddedSongs(context));
}
@NonNull
public static Observable<ArrayList<Artist>> getLastAddedArtists(@NonNull Context context) {
return ArtistLoader.splitIntoArtists(getLastAddedAlbums(context));
}
}

View file

@ -0,0 +1,46 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.database.Cursor
import android.provider.MediaStore
import java.util.ArrayList
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.Observable
import io.reactivex.annotations.NonNull
/**
* Created by hemanths on 16/08/17.
*/
object LastAddedSongsLoader {
@NonNull
fun getLastAddedSongs(@NonNull context: Context): Observable<ArrayList<Song>> {
return SongLoader.getSongs(makeLastAddedCursor(context))
}
fun makeLastAddedCursor(@NonNull context: Context): Cursor? {
val cutoff = PreferenceUtil.getInstance().lastAddedCutoff
return SongLoader.makeSongCursor(
context,
MediaStore.Audio.Media.DATE_ADDED + ">?",
arrayOf(cutoff.toString()),
MediaStore.Audio.Media.DATE_ADDED + " DESC")
}
@NonNull
fun getLastAddedAlbums(@NonNull context: Context): Observable<ArrayList<Album>> {
return AlbumLoader.splitIntoAlbums(getLastAddedSongs(context))
}
@NonNull
fun getLastAddedArtists(@NonNull context: Context): Observable<ArrayList<Artist>> {
return ArtistLoader.splitIntoArtists(getLastAddedAlbums(context))
}
}

View file

@ -1,118 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.PlaylistsColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import code.name.monkey.retromusic.model.Playlist;
import java.util.ArrayList;
import io.reactivex.Observable;
/**
* Created by hemanths on 16/08/17.
*/
public class PlaylistLoader {
@Nullable
public static Cursor makePlaylistCursor(@NonNull final Context context, final String selection, final String[] values) {
try {
return context.getContentResolver().query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
new String[]{
/* 0 */
BaseColumns._ID,
/* 1 */
PlaylistsColumns.NAME
}, selection, values, MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER);
} catch (SecurityException e) {
return null;
}
}
@NonNull
public static Observable<Playlist> getPlaylist(@Nullable final Cursor cursor) {
return Observable.create(e -> {
Playlist playlist = new Playlist();
if (cursor != null && cursor.moveToFirst()) {
playlist = getPlaylistFromCursorImpl(cursor);
}
if (cursor != null)
cursor.close();
e.onNext(playlist);
e.onComplete();
});
}
@NonNull
public static Observable<Playlist> getPlaylist(@NonNull final Context context, final String playlistName) {
return getPlaylist(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
new String[]{
playlistName
}
));
}
@NonNull
public static Observable<Playlist> getPlaylist(@NonNull final Context context, final int playlistId) {
return getPlaylist(makePlaylistCursor(
context,
BaseColumns._ID + "=?",
new String[]{
String.valueOf(playlistId)
}
));
}
@NonNull
private static Playlist getPlaylistFromCursorImpl(@NonNull final Cursor cursor) {
final int id = cursor.getInt(0);
final String name = cursor.getString(1);
return new Playlist(id, name);
}
@NonNull
public static Observable<ArrayList<Playlist>> getAllPlaylists(@Nullable final Cursor cursor) {
return Observable.create(e -> {
ArrayList<Playlist> playlists = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
playlists.add(getPlaylistFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
if (cursor != null)
cursor.close();
e.onNext(playlists);
e.onComplete();
});
}
@NonNull
public static Observable<ArrayList<Playlist>> getAllPlaylists(@NonNull final Context context) {
return getAllPlaylists(makePlaylistCursor(context, null, null));
}
public static void deletePlaylists(Context context, long playlistId) {
Uri localUri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
StringBuilder localStringBuilder = new StringBuilder();
localStringBuilder.append("_id IN (");
localStringBuilder.append((playlistId));
localStringBuilder.append(")");
context.getContentResolver().delete(localUri, localStringBuilder.toString(), null);
}
}

View file

@ -0,0 +1,103 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.BaseColumns
import android.provider.MediaStore
import android.provider.MediaStore.Audio.PlaylistsColumns
import code.name.monkey.retromusic.model.Playlist
import java.util.ArrayList
import io.reactivex.Observable
/**
* Created by hemanths on 16/08/17.
*/
object PlaylistLoader {
fun makePlaylistCursor(context: Context, selection: String?, values: Array<String>?): Cursor? {
try {
return context.contentResolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
arrayOf(
/* 0 */
BaseColumns._ID,
/* 1 */
PlaylistsColumns.NAME), selection, values, MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER)
} catch (e: SecurityException) {
return null
}
}
fun getPlaylist(cursor: Cursor?): Observable<Playlist> {
return Observable.create { e ->
var playlist = Playlist()
if (cursor != null && cursor.moveToFirst()) {
playlist = getPlaylistFromCursorImpl(cursor)
}
cursor?.close()
e.onNext(playlist)
e.onComplete()
}
}
fun getPlaylist(context: Context, playlistName: String): Observable<Playlist> {
return getPlaylist(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
arrayOf(playlistName)
))
}
fun getPlaylist(context: Context, playlistId: Int): Observable<Playlist> {
return getPlaylist(makePlaylistCursor(
context,
BaseColumns._ID + "=?",
arrayOf(playlistId.toString())
))
}
private fun getPlaylistFromCursorImpl(cursor: Cursor): Playlist {
val id = cursor.getInt(0)
val name = cursor.getString(1)
return Playlist(id, name)
}
fun getAllPlaylists(cursor: Cursor?): Observable<ArrayList<Playlist>> {
return Observable.create { e ->
val playlists = ArrayList<Playlist>()
if (cursor != null && cursor.moveToFirst()) {
do {
playlists.add(getPlaylistFromCursorImpl(cursor))
} while (cursor.moveToNext())
}
cursor?.close()
e.onNext(playlists)
e.onComplete()
}
}
fun getAllPlaylists(context: Context): Observable<ArrayList<Playlist>> {
return getAllPlaylists(makePlaylistCursor(context, null, null))
}
fun deletePlaylists(context: Context, playlistId: Long) {
val localUri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI
val localStringBuilder = StringBuilder()
localStringBuilder.append("_id IN (")
localStringBuilder.append(playlistId)
localStringBuilder.append(")")
context.contentResolver.delete(localUri, localStringBuilder.toString(), null)
}
}

View file

@ -1,94 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AudioColumns;
import java.util.ArrayList;
import java.util.List;
import code.name.monkey.retromusic.model.AbsCustomPlaylist;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.PlaylistSong;
import code.name.monkey.retromusic.model.Song;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
/**
* Created by hemanths on 16/08/17.
*/
public class PlaylistSongsLoader {
@NonNull
public static Observable<ArrayList<Song>> getPlaylistSongList(@NonNull Context context, Playlist playlist) {
if (playlist instanceof AbsCustomPlaylist) {
return ((AbsCustomPlaylist) playlist).getSongs(context);
} else {
//noinspection unchecked
return getPlaylistSongList(context, playlist.id);
}
}
@NonNull
public static Observable<ArrayList<Song>> getPlaylistSongList(@NonNull Context context, final int playlistId) {
return Observable.create(e -> {
ArrayList<PlaylistSong> songs = new ArrayList<>();
Cursor cursor = makePlaylistSongCursor(context, playlistId);
if (cursor != null && cursor.moveToFirst()) {
do {
songs.add(getPlaylistSongFromCursorImpl(cursor, playlistId));
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
e.onNext((ArrayList<Song>) (List) songs);
e.onComplete();
});
}
@NonNull
private static PlaylistSong getPlaylistSongFromCursorImpl(@NonNull Cursor cursor, int playlistId) {
final int id = cursor.getInt(0);
final String title = cursor.getString(1);
final int trackNumber = cursor.getInt(2);
final int year = cursor.getInt(3);
final long duration = cursor.getLong(4);
final String data = cursor.getString(5);
final int dateModified = cursor.getInt(6);
final int albumId = cursor.getInt(7);
final String albumName = cursor.getString(8);
final int artistId = cursor.getInt(9);
final String artistName = cursor.getString(10);
final int idInPlaylist = cursor.getInt(11);
return new PlaylistSong(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName, artistId, artistName, playlistId, idInPlaylist);
}
private static Cursor makePlaylistSongCursor(@NonNull final Context context, final int playlistId) {
try {
return context.getContentResolver().query(
MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId),
new String[]{
MediaStore.Audio.Playlists.Members.AUDIO_ID,// 0
AudioColumns.TITLE,// 1
AudioColumns.TRACK,// 2
AudioColumns.YEAR,// 3
AudioColumns.DURATION,// 4
AudioColumns.DATA,// 5
AudioColumns.DATE_MODIFIED,// 6
AudioColumns.ALBUM_ID,// 7
AudioColumns.ALBUM,// 8
AudioColumns.ARTIST_ID,// 9
AudioColumns.ARTIST,// 10
MediaStore.Audio.Playlists.Members._ID, // 11
}, SongLoader.BASE_SELECTION, null,
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER);
} catch (SecurityException e) {
return null;
}
}
}

View file

@ -0,0 +1,86 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.database.Cursor
import android.provider.MediaStore
import android.provider.MediaStore.Audio.AudioColumns
import code.name.monkey.retromusic.Constants.BASE_SELECTION
import code.name.monkey.retromusic.model.AbsCustomPlaylist
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.PlaylistSong
import code.name.monkey.retromusic.model.Song
import io.reactivex.Observable
import io.reactivex.annotations.NonNull
import java.util.*
/**
* Created by hemanths on 16/08/17.
*/
object PlaylistSongsLoader {
@NonNull
fun getPlaylistSongList(@NonNull context: Context, playlist: Playlist): Observable<ArrayList<Song>> {
return (playlist as? AbsCustomPlaylist)?.getSongs(context)
?: getPlaylistSongList(context, playlist.id)
}
@NonNull
fun getPlaylistSongList(@NonNull context: Context, playlistId: Int): Observable<ArrayList<Song>> {
return Observable.create { e ->
val songs = ArrayList<Song>()
val cursor = makePlaylistSongCursor(context, playlistId)
if (cursor != null && cursor.moveToFirst()) {
do {
songs.add(getPlaylistSongFromCursorImpl(cursor, playlistId))
} while (cursor.moveToNext())
}
cursor?.close()
e.onNext(songs)
e.onComplete()
}
}
@NonNull
private fun getPlaylistSongFromCursorImpl(@NonNull cursor: Cursor, playlistId: Int): PlaylistSong {
val id = cursor.getInt(0)
val title = cursor.getString(1)
val trackNumber = cursor.getInt(2)
val year = cursor.getInt(3)
val duration = cursor.getLong(4)
val data = cursor.getString(5)
val dateModified = cursor.getInt(6)
val albumId = cursor.getInt(7)
val albumName = cursor.getString(8)
val artistId = cursor.getInt(9)
val artistName = cursor.getString(10)
val idInPlaylist = cursor.getInt(11)
return PlaylistSong(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName, artistId, artistName, playlistId, idInPlaylist)
}
private fun makePlaylistSongCursor(@NonNull context: Context, playlistId: Int): Cursor? {
try {
return context.contentResolver.query(
MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId.toLong()),
arrayOf(MediaStore.Audio.Playlists.Members.AUDIO_ID, // 0
AudioColumns.TITLE, // 1
AudioColumns.TRACK, // 2
AudioColumns.YEAR, // 3
AudioColumns.DURATION, // 4
AudioColumns.DATA, // 5
AudioColumns.DATE_MODIFIED, // 6
AudioColumns.ALBUM_ID, // 7
AudioColumns.ALBUM, // 8
AudioColumns.ARTIST_ID, // 9
AudioColumns.ARTIST, // 10
MediaStore.Audio.Playlists.Members._ID)// 11
, BASE_SELECTION, null,
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER)
} catch (e: SecurityException) {
return null
}
}
}

View file

@ -1,44 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import java.util.ArrayList;
import code.name.monkey.retromusic.R;
import io.reactivex.Observable;
public class SearchLoader {
public static Observable<ArrayList<Object>> searchAll(@NonNull Context context, @NonNull String query) {
ArrayList<Object> results = new ArrayList<>();
return Observable.create(e -> {
if (!TextUtils.isEmpty(query)) {
SongLoader.Companion.getSongs(context, query)
.subscribe(songs -> {
if (!songs.isEmpty()) {
results.add(context.getResources().getString(R.string.songs));
results.addAll(songs);
}
});
ArtistLoader.getArtists(context, query)
.subscribe(artists -> {
if (!artists.isEmpty()) {
results.add(context.getResources().getString(R.string.artists));
results.addAll(artists);
}
});
AlbumLoader.getAlbums(context, query)
.subscribe(albums -> {
if (!albums.isEmpty()) {
results.add(context.getResources().getString(R.string.albums));
results.addAll(albums);
}
});
}
e.onNext(results);
e.onComplete();
});
}
}

View file

@ -0,0 +1,43 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.text.TextUtils
import java.util.ArrayList
import code.name.monkey.retromusic.R
import io.reactivex.Observable
object SearchLoader {
fun searchAll(context: Context, query: String): Observable<ArrayList<Any>> {
val results = ArrayList<Any>()
return Observable.create { e ->
if (!TextUtils.isEmpty(query)) {
SongLoader.getSongs(context, query)
.subscribe { songs ->
if (!songs.isEmpty()) {
results.add(context.resources.getString(R.string.songs))
results.addAll(songs)
}
}
ArtistLoader.getArtists(context, query)
.subscribe { artists ->
if (!artists.isEmpty()) {
results.add(context.resources.getString(R.string.artists))
results.addAll(artists)
}
}
AlbumLoader.getAlbums(context, query)
.subscribe { albums ->
if (!albums.isEmpty()) {
results.add(context.resources.getString(R.string.albums))
results.addAll(albums)
}
}
}
e.onNext(results)
e.onComplete()
}
}
}

View file

@ -2,9 +2,10 @@ package code.name.monkey.retromusic.loaders
import android.content.Context
import android.database.Cursor
import android.provider.BaseColumns
import android.provider.MediaStore
import android.provider.MediaStore.Audio.AudioColumns
import code.name.monkey.retromusic.Constants.BASE_PROJECTION
import code.name.monkey.retromusic.Constants.BASE_SELECTION
import code.name.monkey.retromusic.helper.ShuffleHelper
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.providers.BlacklistStore
@ -16,167 +17,152 @@ import java.util.*
* Created by hemanths on 10/08/17.
*/
open class SongLoader {
companion object {
const val BASE_SELECTION = AudioColumns.IS_MUSIC + "=1" + " AND " + AudioColumns.TITLE + " != ''"
val BASE_PROJECTION = arrayOf(BaseColumns._ID, // 0
AudioColumns.TITLE, // 1
AudioColumns.TRACK, // 2
AudioColumns.YEAR, // 3
AudioColumns.DURATION, // 4
AudioColumns.DATA, // 5
AudioColumns.DATE_MODIFIED, // 6
AudioColumns.ALBUM_ID, // 7
AudioColumns.ALBUM, // 8
AudioColumns.ARTIST_ID, // 9
AudioColumns.ARTIST)// 10
object SongLoader {
fun getAllSongs(context: Context): Observable<ArrayList<Song>> {
val cursor = makeSongCursor(context, null, null)
return getSongs(cursor)
}
fun getAllSongs(context: Context): Observable<ArrayList<Song>> {
val cursor = makeSongCursor(context, null, null)
return getSongs(cursor)
}
fun getSongs(context: Context, query: String): Observable<ArrayList<Song>> {
val cursor = makeSongCursor(context, AudioColumns.TITLE + " LIKE ?", arrayOf("%$query%"))
return getSongs(cursor)
}
fun getSongs(context: Context, query: String): Observable<ArrayList<Song>> {
val cursor = makeSongCursor(context, AudioColumns.TITLE + " LIKE ?", arrayOf("%$query%"))
return getSongs(cursor)
}
fun getSongs(cursor: Cursor?): Observable<ArrayList<Song>> {
return Observable.create { e ->
val songs = ArrayList<Song>()
if (cursor != null && cursor.moveToFirst()) {
do {
songs.add(getSongFromCursorImpl(cursor))
} while (cursor.moveToNext())
}
cursor?.close()
e.onNext(songs)
e.onComplete()
}
}
private fun getSongFromCursorImpl(cursor: Cursor): Song {
val id = cursor.getInt(0)
val title = cursor.getString(1)
val trackNumber = cursor.getInt(2)
val year = cursor.getInt(3)
val duration = cursor.getLong(4)
val data = cursor.getString(5)
val dateModified = cursor.getLong(6)
val albumId = cursor.getInt(7)
val albumName = cursor.getString(8)
val artistId = cursor.getInt(9)
val artistName = cursor.getString(10)
return Song(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName,
artistId, artistName)
}
@JvmOverloads
fun makeSongCursor(context: Context, selection: String?, selectionValues: Array<String>?, sortOrder: String = PreferenceUtil.getInstance().songSortOrder): Cursor? {
var selectionFinal = selection
var selectionValuesFinal = selectionValues
selectionFinal = if (selection != null && selection.trim { it <= ' ' } != "") {
"$BASE_SELECTION AND $selectionFinal"
} else {
BASE_SELECTION
fun getSongs(cursor: Cursor?): Observable<ArrayList<Song>> {
return Observable.create { e ->
val songs = ArrayList<Song>()
if (cursor != null && cursor.moveToFirst()) {
do {
songs.add(getSongFromCursorImpl(cursor))
} while (cursor.moveToNext())
}
// Blacklist
val paths = BlacklistStore.getInstance(context).paths
if (!paths.isEmpty()) {
selectionFinal = generateBlacklistSelection(selectionFinal, paths.size)
selectionValuesFinal = addBlacklistSelectionValues(selectionValuesFinal, paths)
}
try {
return context.contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
BASE_PROJECTION, selectionFinal, selectionValuesFinal, sortOrder)
} catch (e: SecurityException) {
return null
}
}
private fun generateBlacklistSelection(selection: String?, pathCount: Int): String {
val newSelection = StringBuilder(
if (selection != null && selection.trim { it <= ' ' } != "") "$selection AND " else "")
newSelection.append(AudioColumns.DATA + " NOT LIKE ?")
for (i in 0 until pathCount - 1) {
newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?")
}
return newSelection.toString()
}
private fun addBlacklistSelectionValues(selectionValues: Array<String>?,
paths: ArrayList<String>): Array<String>? {
var selectionValuesFinal = selectionValues
if (selectionValuesFinal == null) {
selectionValuesFinal = emptyArray()
}
val newSelectionValues = Array(selectionValuesFinal.size + paths.size) {
"n = $it"
}
System.arraycopy(selectionValuesFinal, 0, newSelectionValues, 0, selectionValuesFinal.size)
for (i in selectionValuesFinal.size until newSelectionValues.size) {
newSelectionValues[i] = paths[i - selectionValuesFinal.size] + "%"
}
return newSelectionValues
}
fun getSong(cursor: Cursor?): Observable<Song> {
return Observable.create { e ->
val song: Song
if (cursor != null && cursor.moveToFirst()) {
song = getSongFromCursorImpl(cursor)
} else {
song = Song.EMPTY_SONG
}
cursor?.close()
e.onNext(song)
e.onComplete()
}
}
fun getSong(context: Context, queryId: Int): Observable<Song> {
val cursor = makeSongCursor(context, AudioColumns._ID + "=?",
arrayOf(queryId.toString()))
return getSong(cursor)
}
fun suggestSongs(context: Context): Observable<ArrayList<Song>> {
return SongLoader.getAllSongs(context)
.flatMap {
val list = ArrayList<Song>()
ShuffleHelper.makeShuffleList(it, -1)
if (it.size > 9) {
list.addAll(it.subList(0, 9))
}
return@flatMap Observable.just(list)
}
/*.flatMap({ songs ->
val list = ArrayList<Song>()
ShuffleHelper.makeShuffleList(songs, -1)
if (songs.size > 9) {
list.addAll(songs.subList(0, 9))
}
Observable.just(list)
} as Function<ArrayList<Song>, ObservableSource<ArrayList<Song>>>)*/
/*.subscribe(songs -> {
ArrayList<Song> list = new ArrayList<>();
if (songs.isEmpty()) {
return;
}
ShuffleHelper.makeShuffleList(songs, -1);
if (songs.size() > 10) {
list.addAll(songs.subList(0, 10));
} else {
list.addAll(songs);
}
return;
});*/
cursor?.close()
e.onNext(songs)
e.onComplete()
}
}
private fun getSongFromCursorImpl(cursor: Cursor): Song {
val id = cursor.getInt(0)
val title = cursor.getString(1)
val trackNumber = cursor.getInt(2)
val year = cursor.getInt(3)
val duration = cursor.getLong(4)
val data = cursor.getString(5)
val dateModified = cursor.getLong(6)
val albumId = cursor.getInt(7)
val albumName = cursor.getString(8)
val artistId = cursor.getInt(9)
val artistName = cursor.getString(10)
return Song(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName,
artistId, artistName)
}
@JvmOverloads
fun makeSongCursor(context: Context, selection: String?, selectionValues: Array<String>?, sortOrder: String = PreferenceUtil.getInstance().songSortOrder): Cursor? {
var selectionFinal = selection
var selectionValuesFinal = selectionValues
selectionFinal = if (selection != null && selection.trim { it <= ' ' } != "") {
"$BASE_SELECTION AND $selectionFinal"
} else {
BASE_SELECTION
}
// Blacklist
val paths = BlacklistStore.getInstance(context).paths
if (!paths.isEmpty()) {
selectionFinal = generateBlacklistSelection(selectionFinal, paths.size)
selectionValuesFinal = addBlacklistSelectionValues(selectionValuesFinal, paths)
}
try {
return context.contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
BASE_PROJECTION, selectionFinal, selectionValuesFinal, sortOrder)
} catch (e: SecurityException) {
return null
}
}
private fun generateBlacklistSelection(selection: String?, pathCount: Int): String {
val newSelection = StringBuilder(
if (selection != null && selection.trim { it <= ' ' } != "") "$selection AND " else "")
newSelection.append(AudioColumns.DATA + " NOT LIKE ?")
for (i in 0 until pathCount - 1) {
newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?")
}
return newSelection.toString()
}
private fun addBlacklistSelectionValues(selectionValues: Array<String>?,
paths: ArrayList<String>): Array<String>? {
var selectionValuesFinal = selectionValues
if (selectionValuesFinal == null) {
selectionValuesFinal = emptyArray()
}
val newSelectionValues = Array(selectionValuesFinal.size + paths.size) {
"n = $it"
}
System.arraycopy(selectionValuesFinal, 0, newSelectionValues, 0, selectionValuesFinal.size)
for (i in selectionValuesFinal.size until newSelectionValues.size) {
newSelectionValues[i] = paths[i - selectionValuesFinal.size] + "%"
}
return newSelectionValues
}
fun getSong(cursor: Cursor?): Observable<Song> {
return Observable.create { e ->
val song: Song = if (cursor != null && cursor.moveToFirst()) {
getSongFromCursorImpl(cursor)
} else {
Song.EMPTY_SONG
}
cursor?.close()
e.onNext(song)
e.onComplete()
}
}
fun getSong(context: Context, queryId: Int): Observable<Song> {
val cursor = makeSongCursor(context, AudioColumns._ID + "=?",
arrayOf(queryId.toString()))
return getSong(cursor)
}
fun suggestSongs(context: Context): Observable<ArrayList<Song>> {
return SongLoader.getAllSongs(context)
.flatMap {
val list = ArrayList<Song>()
ShuffleHelper.makeShuffleList(it, -1)
if (it.size > 9) {
list.addAll(it.subList(0, 9))
}
return@flatMap Observable.just(list)
}
/*.flatMap({ songs ->
val list = ArrayList<Song>()
ShuffleHelper.makeShuffleList(songs, -1)
if (songs.size > 9) {
list.addAll(songs.subList(0, 9))
}
Observable.just(list)
} as Function<ArrayList<Song>, ObservableSource<ArrayList<Song>>>)*/
/*.subscribe(songs -> {
ArrayList<Song> list = new ArrayList<>();
if (songs.isEmpty()) {
return;
}
ShuffleHelper.makeShuffleList(songs, -1);
if (songs.size() > 10) {
list.addAll(songs.subList(0, 10));
} else {
list.addAll(songs);
}
return;
});*/
}
}

View file

@ -1,158 +0,0 @@
package code.name.monkey.retromusic.loaders;
import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import code.name.monkey.retromusic.model.Album;
import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.providers.HistoryStore;
import code.name.monkey.retromusic.providers.SongPlayCountStore;
import io.reactivex.Observable;
import java.util.ArrayList;
/**
* Created by hemanths on 16/08/17.
*/
public class TopAndRecentlyPlayedTracksLoader {
private static final int NUMBER_OF_TOP_TRACKS = 99;
@NonNull
public static Observable<ArrayList<Song>> getRecentlyPlayedTracks(@NonNull Context context) {
return SongLoader.Companion.getSongs(makeRecentTracksCursorAndClearUpDatabase(context));
}
@NonNull
public static Observable<ArrayList<Song>> getTopTracks(@NonNull Context context) {
return SongLoader.Companion.getSongs(makeTopTracksCursorAndClearUpDatabase(context));
}
@Nullable
private static Cursor makeRecentTracksCursorAndClearUpDatabase(@NonNull final Context context) {
SortedLongCursor retCursor = makeRecentTracksCursorImpl(context);
// clean up the databases with any ids not found
if (retCursor != null) {
ArrayList<Long> missingIds = retCursor.getMissingIds();
if (missingIds != null && missingIds.size() > 0) {
for (long id : missingIds) {
HistoryStore.getInstance(context).removeSongId(id);
}
}
}
return retCursor;
}
@Nullable
private static Cursor makeTopTracksCursorAndClearUpDatabase(@NonNull final Context context) {
SortedLongCursor retCursor = makeTopTracksCursorImpl(context);
// clean up the databases with any ids not found
if (retCursor != null) {
ArrayList<Long> missingIds = retCursor.getMissingIds();
if (missingIds != null && missingIds.size() > 0) {
for (long id : missingIds) {
SongPlayCountStore.getInstance(context).removeItem(id);
}
}
}
return retCursor;
}
@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();
try {
return makeSortedCursor(context, songs,
songs.getColumnIndex(HistoryStore.RecentStoreColumns.ID));
} finally {
if (songs != null) {
songs.close();
}
}
}
@Nullable
private static SortedLongCursor makeTopTracksCursorImpl(@NonNull final Context context) {
// first get the top results ids from the internal database
Cursor songs = SongPlayCountStore.getInstance(context)
.getTopPlayedResults(NUMBER_OF_TOP_TRACKS);
try {
return makeSortedCursor(context, songs,
songs.getColumnIndex(SongPlayCountStore.SongPlayCountColumns.ID));
} finally {
if (songs != null) {
songs.close();
}
}
}
@Nullable
private static SortedLongCursor makeSortedCursor(@NonNull final Context context,
@Nullable final Cursor cursor, final int idColumn) {
if (cursor != null && cursor.moveToFirst()) {
// create the list of ids to select against
StringBuilder selection = new StringBuilder();
selection.append(BaseColumns._ID);
selection.append(" IN (");
// this tracks the order of the ids
long[] order = new long[cursor.getCount()];
long id = cursor.getLong(idColumn);
selection.append(id);
order[cursor.getPosition()] = id;
while (cursor.moveToNext()) {
selection.append(",");
id = cursor.getLong(idColumn);
order[cursor.getPosition()] = id;
selection.append(String.valueOf(id));
}
selection.append(")");
// get a list of songs with the data given the selection statement
Cursor songCursor = SongLoader.Companion.makeSongCursor(context, selection.toString(), null);
if (songCursor != null) {
// now return the wrapped TopTracksCursor to handle sorting given order
return new SortedLongCursor(songCursor, order, BaseColumns._ID);
}
}
return null;
}
@NonNull
public static Observable<ArrayList<Album>> getTopAlbums(@NonNull Context context) {
return Observable.create(e -> {
getTopTracks(context).subscribe(songs -> {
if (songs.size() > 0) {
e.onNext(AlbumLoader.splitIntoAlbums(songs));
}
e.onComplete();
});
});
}
@NonNull
public static Observable<ArrayList<Artist>> getTopArtists(@NonNull Context context) {
return Observable.create(e -> {
getTopAlbums(context).subscribe(albums -> {
if (albums.size() > 0) {
e.onNext(ArtistLoader.splitIntoArtists(albums));
}
e.onComplete();
});
});
}
}

View file

@ -0,0 +1,142 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.database.Cursor
import android.provider.BaseColumns
import code.name.monkey.retromusic.Constants.NUMBER_OF_TOP_TRACKS
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.providers.HistoryStore
import code.name.monkey.retromusic.providers.SongPlayCountStore
import io.reactivex.Observable
import java.util.*
/**
* Created by hemanths on 16/08/17.
*/
object TopAndRecentlyPlayedTracksLoader {
fun getRecentlyPlayedTracks(context: Context): Observable<ArrayList<Song>> {
return SongLoader.getSongs(makeRecentTracksCursorAndClearUpDatabase(context))
}
fun getTopTracks(context: Context): Observable<ArrayList<Song>> {
return SongLoader.getSongs(makeTopTracksCursorAndClearUpDatabase(context))
}
private fun makeRecentTracksCursorAndClearUpDatabase(context: Context): Cursor? {
val retCursor = makeRecentTracksCursorImpl(context)
// clean up the databases with any ids not found
if (retCursor != null) {
val missingIds = retCursor.missingIds
if (missingIds != null && missingIds.size > 0) {
for (id in missingIds) {
HistoryStore.getInstance(context).removeSongId(id)
}
}
}
return retCursor
}
private fun makeTopTracksCursorAndClearUpDatabase(context: Context): Cursor? {
val retCursor = makeTopTracksCursorImpl(context)
// clean up the databases with any ids not found
if (retCursor != null) {
val missingIds = retCursor.missingIds
if (missingIds != null && missingIds.size > 0) {
for (id in missingIds) {
SongPlayCountStore.getInstance(context).removeItem(id)
}
}
}
return retCursor
}
private fun makeRecentTracksCursorImpl(context: Context): SortedLongCursor? {
// first get the top results ids from the internal database
val songs = HistoryStore.getInstance(context).queryRecentIds()
try {
return makeSortedCursor(context, songs,
songs!!.getColumnIndex(HistoryStore.RecentStoreColumns.ID))
} finally {
songs?.close()
}
}
private fun makeTopTracksCursorImpl(context: Context): SortedLongCursor? {
// first get the top results ids from the internal database
val songs = SongPlayCountStore.getInstance(context)
.getTopPlayedResults(NUMBER_OF_TOP_TRACKS)
try {
return makeSortedCursor(context, songs,
songs!!.getColumnIndex(SongPlayCountStore.SongPlayCountColumns.ID))
} finally {
songs?.close()
}
}
private fun makeSortedCursor(context: Context,
cursor: Cursor?, idColumn: Int): SortedLongCursor? {
if (cursor != null && cursor.moveToFirst()) {
// create the list of ids to select against
val selection = StringBuilder()
selection.append(BaseColumns._ID)
selection.append(" IN (")
// this tracks the order of the ids
val order = LongArray(cursor.count)
var id = cursor.getLong(idColumn)
selection.append(id)
order[cursor.position] = id
while (cursor.moveToNext()) {
selection.append(",")
id = cursor.getLong(idColumn)
order[cursor.position] = id
selection.append(id.toString())
}
selection.append(")")
// get a list of songs with the data given the selection statement
val songCursor = SongLoader.makeSongCursor(context, selection.toString(), null)
if (songCursor != null) {
// now return the wrapped TopTracksCursor to handle sorting given order
return SortedLongCursor(songCursor, order, BaseColumns._ID)
}
}
return null
}
fun getTopAlbums(context: Context): Observable<ArrayList<Album>> {
return Observable.create { e ->
getTopTracks(context).subscribe { songs ->
if (songs.size > 0) {
e.onNext(AlbumLoader.splitIntoAlbums(songs))
}
e.onComplete()
}
}
}
fun getTopArtists(context: Context): Observable<ArrayList<Artist>> {
return Observable.create { e ->
getTopAlbums(context).subscribe { albums ->
if (albums.size > 0) {
e.onNext(ArtistLoader.splitIntoArtists(albums))
}
e.onComplete()
}
}
}
}