Rx Java and Normal compatible for all query

This commit is contained in:
h4h13 2019-08-02 14:29:40 +05:30
parent 850036e5cc
commit c2759e3ec0
89 changed files with 2900 additions and 1040 deletions

View file

@ -21,89 +21,164 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.Observable
import java.util.*
import kotlin.collections.ArrayList
/**
* 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())
)
object AlbumLoader {
fun getAllAlbumsFlowable(
context: Context
): Observable<ArrayList<Album>> {
val songs = SongLoader.getSongsFlowable(SongLoader.makeSongCursor(
context, null, null,
getSongLoaderSortOrder())
)
return splitIntoAlbums(songs)
}
return splitIntoAlbumsFlowable(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 getAlbumsFlowable(context: Context, query: String): Observable<ArrayList<Album>> {
val songs = SongLoader.getSongsFlowable(SongLoader.makeSongCursor(
context,
AudioColumns.ALBUM + " LIKE ?",
arrayOf("%$query%"),
getSongLoaderSortOrder())
)
return splitIntoAlbumsFlowable(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 getAlbums(
context: Context,
query: String
): ArrayList<Album> {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ALBUM + " LIKE ?",
arrayOf("%$query%"),
getSongLoaderSortOrder())
)
return splitIntoAlbums(songs)
}
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)
fun getAlbumFlowable(
context: Context,
albumId: Int
): Observable<Album> {
return Observable.create { e ->
val songs = SongLoader.getSongsFlowable(SongLoader.makeSongCursor(context, AudioColumns.ALBUM_ID + "=?", arrayOf(albumId.toString()), getSongLoaderSortOrder()))
songs.subscribe { songs1 ->
e.onNext(Album(songs1))
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()
}
}
private fun getSongLoaderSortOrder(): String {
return PreferenceUtil.getInstance().albumSortOrder + ", " +
//PreferenceUtil.getInstance().getAlbumSongSortOrder() + "," +
PreferenceUtil.getInstance().albumDetailSongSortOrder
}
}
fun getAlbum(
context: Context,
albumId: Int
): Album {
val songs = SongLoader.getSongs(
SongLoader.makeSongCursor(
context,
AudioColumns.ALBUM_ID + "=?",
arrayOf(albumId.toString()),
getSongLoaderSortOrder()))
val album = Album(songs)
sortSongsByTrackNumber(album)
return album
}
fun splitIntoAlbumsFlowable(
songs: Observable<ArrayList<Song>>?
): Observable<ArrayList<Album>> {
return Observable.create { e ->
val albums = ArrayList<Album>()
songs?.subscribe { songs1 ->
for (song in songs1) {
getOrCreateAlbumFlowable(albums, song.albumId).subscribe { album ->
album.songs!!.add(song)
}
}
}
for (album in albums) {
sortSongsByTrackNumber(album)
}
e.onNext(albums)
e.onComplete()
}
}
fun getAllAlbums(
context: Context
): ArrayList<Album> {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context, null, null,
getSongLoaderSortOrder())
)
return splitIntoAlbums(songs)
}
fun splitIntoAlbums(
songs: ArrayList<Song>?
): ArrayList<Album> {
val albums = ArrayList<Album>()
if (songs != null) {
for (song in songs) {
getOrCreateAlbum(albums, song.albumId).songs?.add(song)
}
}
for (album in albums) {
sortSongsByTrackNumber(album)
}
return albums
}
private fun getOrCreateAlbumFlowable(
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()
}
}
private fun getOrCreateAlbum(
albums: ArrayList<Album>,
albumId: Int
): Album {
for (album in albums) {
if (album.songs!!.isNotEmpty() && album.songs[0].albumId == albumId) {
return album
}
}
val album = Album()
albums.add(album)
return album
}
private fun sortSongsByTrackNumber(
album: Album
) {
album.songs?.sortWith(Comparator { o1, o2 -> o1.trackNumber - o2.trackNumber })
}
private fun getSongLoaderSortOrder(): String {
return PreferenceUtil.getInstance().albumSortOrder + ", " +
//PreferenceUtil.getInstance().getAlbumSongSortOrder() + "," +
PreferenceUtil.getInstance().albumDetailSongSortOrder
}
}

View file

@ -20,7 +20,7 @@ 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
import kotlin.collections.ArrayList
object ArtistLoader {
private fun getSongLoaderSortOrder(): String {
@ -30,36 +30,32 @@ object ArtistLoader {
PreferenceUtil.getInstance().artistDetailSongSortOrder
}
fun getArtist(context: Context, artistId: Int): Observable<Artist> {
fun getAllArtistsFlowable(
context: Context
): Observable<ArrayList<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()
}
SongLoader.getSongsFlowable(SongLoader.makeSongCursor(
context, null, null,
getSongLoaderSortOrder())
).subscribe { songs ->
e.onNext(splitIntoArtists(AlbumLoader.splitIntoAlbums(songs)))
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 getAllArtists(context: Context): ArrayList<Artist> {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
null, null,
getSongLoaderSortOrder())
)
return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs))
}
fun getArtists(context: Context, query: String): Observable<ArrayList<Artist>> {
fun getArtistsFlowable(context: Context, query: String): Observable<ArrayList<Artist>> {
return Observable.create { e ->
SongLoader.getSongs(SongLoader.makeSongCursor(
SongLoader.getSongsFlowable(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST + " LIKE ?",
arrayOf("%$query%"),
@ -71,6 +67,16 @@ object ArtistLoader {
}
}
fun getArtists(context: Context, query: String): ArrayList<Artist> {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST + " LIKE ?",
arrayOf("%$query%"),
getSongLoaderSortOrder())
)
return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs))
}
fun splitIntoArtists(albums: ArrayList<Album>?): ArrayList<Artist> {
val artists = ArrayList<Artist>()
if (albums != null) {
@ -83,7 +89,7 @@ object ArtistLoader {
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) {
if (artist.albums!!.isNotEmpty() && artist.albums[0].songs!!.isNotEmpty() && artist.albums[0].songs!![0].artistId == artistId) {
return artist
}
}
@ -106,4 +112,27 @@ object ArtistLoader {
}
}
}
fun getArtistFlowable(context: Context, artistId: Int): Observable<Artist> {
return Observable.create { e ->
SongLoader.getSongsFlowable(SongLoader.makeSongCursor(context, AudioColumns.ARTIST_ID + "=?",
arrayOf(artistId.toString()),
getSongLoaderSortOrder()))
.subscribe { songs ->
val artist = Artist(AlbumLoader.splitIntoAlbums(songs))
e.onNext(artist)
e.onComplete()
}
}
}
fun getArtist(context: Context, artistId: Int): Artist {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST_ID + "=?",
arrayOf(artistId.toString()),
getSongLoaderSortOrder())
)
return Artist(AlbumLoader.splitIntoAlbums(songs))
}
}

View file

@ -27,13 +27,27 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.Observable
import java.util.*
object GenreLoader {
fun getAllGenres(context: Context): Observable<ArrayList<Genre>> {
fun getAllGenresFlowable(context: Context): Observable<ArrayList<Genre>> {
return getGenresFromCursorFlowable(context, makeGenreCursor(context))
}
fun getAllGenres(context: Context): ArrayList<Genre> {
return getGenresFromCursor(context, makeGenreCursor(context))
}
fun getSongs(context: Context, genreId: Int): Observable<ArrayList<Song>> {
fun getSongsFlowable(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) {
getSongsWithNoGenreFlowable(context)
} else SongLoader.getSongsFlowable(makeGenreSongCursor(context, genreId))
}
fun getSongs(context: Context, genreId: Int): 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) {
@ -45,12 +59,18 @@ object GenreLoader {
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
val songCount = getSongs(context, id).size
return Genre(id, name, songCount)
}
private fun getSongsWithNoGenre(context: Context): Observable<ArrayList<Song>> {
private fun getSongsWithNoGenreFlowable(context: Context): Observable<ArrayList<Song>> {
val selection = BaseColumns._ID + " NOT IN " +
"(SELECT " + Genres.Members.AUDIO_ID + " FROM audio_genres_map)"
return SongLoader.getSongsFlowable(SongLoader.makeSongCursor(context, selection, null))
}
private fun getSongsWithNoGenre(context: Context): 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))
@ -92,7 +112,7 @@ object GenreLoader {
}
private fun getGenresFromCursor(context: Context, cursor: Cursor?): Observable<ArrayList<Genre>> {
private fun getGenresFromCursorFlowable(context: Context, cursor: Cursor?): Observable<ArrayList<Genre>> {
return Observable.create { e ->
val genres = ArrayList<Genre>()
if (cursor != null) {
@ -120,6 +140,31 @@ object GenreLoader {
}
}
private fun getGenresFromCursor(context: Context, cursor: Cursor?): ArrayList<Genre> {
val genres = arrayListOf<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 (e: Exception) {
e.printStackTrace()
// nothing we can do then
}
}
} while (cursor.moveToNext())
}
cursor.close()
}
return genres
}
private fun makeGenreCursor(context: Context): Cursor? {
val projection = arrayOf(Genres._ID, Genres.NAME)

View file

@ -25,47 +25,5 @@ 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

@ -22,8 +22,8 @@ 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
import java.util.*
import kotlin.collections.ArrayList
/**
* Created by hemanths on 16/08/17.
@ -31,12 +31,16 @@ import java.util.*
object LastAddedSongsLoader {
@NonNull
fun getLastAddedSongs(@NonNull context: Context): Observable<ArrayList<Song>> {
fun getLastAddedSongsFlowable(context: Context): Observable<ArrayList<Song>> {
return SongLoader.getSongsFlowable(makeLastAddedCursor(context))
}
fun getLastAddedSongs(context: Context): ArrayList<Song> {
return SongLoader.getSongs(makeLastAddedCursor(context))
}
private fun makeLastAddedCursor(@NonNull context: Context): Cursor? {
private fun makeLastAddedCursor(context: Context): Cursor? {
val cutoff = PreferenceUtil.getInstance().lastAddedCutoff
return SongLoader.makeSongCursor(
@ -46,13 +50,22 @@ object LastAddedSongsLoader {
MediaStore.Audio.Media.DATE_ADDED + " DESC")
}
@NonNull
fun getLastAddedAlbums(@NonNull context: Context): Observable<ArrayList<Album>> {
fun getLastAddedAlbumsFlowable(context: Context): Observable<ArrayList<Album>> {
return AlbumLoader.splitIntoAlbumsFlowable(getLastAddedSongsFlowable(context))
}
fun getLastAddedAlbums(context: Context): ArrayList<Album> {
return AlbumLoader.splitIntoAlbums(getLastAddedSongs(context))
}
@NonNull
fun getLastAddedArtists(@NonNull context: Context): Observable<ArrayList<Artist>> {
fun getLastAddedArtistsFlowable(context: Context): Observable<ArrayList<Artist>> {
return ArtistLoader.splitIntoArtists(getLastAddedAlbumsFlowable(context))
}
fun getLastAddedArtists(context: Context): ArrayList<Artist> {
return ArtistLoader.splitIntoArtists(getLastAddedAlbums(context))
}
}

View file

@ -19,31 +19,20 @@ import android.database.Cursor
import android.provider.BaseColumns
import android.provider.MediaStore
import android.provider.MediaStore.Audio.PlaylistsColumns
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.model.Playlist
import io.reactivex.Observable
import java.util.*
/**
* Created by hemanths on 16/08/17.
*/
object PlaylistLoader {
private fun makePlaylistCursor(context: Context, selection: String?, values: Array<String>?): Cursor? {
return try {
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) {
null
}
}
private fun getPlaylist(cursor: Cursor?): Observable<Playlist> {
private fun getPlaylistFlowable(
cursor: Cursor?
): Observable<Playlist> {
return Observable.create { e ->
var playlist = Playlist()
@ -55,11 +44,35 @@ object PlaylistLoader {
e.onNext(playlist)
e.onComplete()
}
}
fun getPlaylist(context: Context, playlistName: String): Observable<Playlist> {
fun getPlaylist(
cursor: Cursor?
): Playlist {
var playlist = Playlist()
if (cursor != null && cursor.moveToFirst()) {
playlist = getPlaylistFromCursorImpl(cursor)
}
cursor?.close()
return playlist
}
fun getPlaylistFlowable(
context: Context,
playlistName: String
): Observable<Playlist> {
return getPlaylistFlowable(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
arrayOf(playlistName)
))
}
fun getPlaylist(
context: Context,
playlistName: String
): Playlist {
return getPlaylist(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
@ -67,23 +80,31 @@ object PlaylistLoader {
))
}
fun getPlaylist(context: Context, playlistId: Int): Observable<Playlist> {
return getPlaylist(makePlaylistCursor(
fun getPlaylistFlowable(
context: Context,
playlistId: Int
): Observable<Playlist> {
return getPlaylistFlowable(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 getAllPlaylistsFlowoable(
context: Context
): Observable<ArrayList<Playlist>> {
return getAllPlaylistsFlowable(makePlaylistCursor(context, null, null))
}
fun getFavoritePlaylistFlowable(context: Context): Observable<ArrayList<Playlist>> {
return getAllPlaylistsFlowable(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
arrayOf(context.getString(code.name.monkey.retromusic.R.string.favorites))))
}
private fun getAllPlaylists(cursor: Cursor?): Observable<ArrayList<Playlist>> {
private fun getAllPlaylistsFlowable(cursor: Cursor?): Observable<ArrayList<Playlist>> {
return Observable.create { e ->
val playlists = ArrayList<Playlist>()
@ -99,15 +120,27 @@ object PlaylistLoader {
}
}
fun getAllPlaylists(context: Context): Observable<ArrayList<Playlist>> {
fun getAllPlaylists(context: Context): ArrayList<Playlist> {
return getAllPlaylists(makePlaylistCursor(context, null, null))
}
fun getFavoritePlaylist(context: Context): Observable<ArrayList<Playlist>> {
fun getFavoritePlaylist(context: Context): ArrayList<Playlist> {
return getAllPlaylists(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
arrayOf(context.getString(R.string.favorites))))
arrayOf(context.getString(code.name.monkey.retromusic.R.string.favorites))))
}
fun getAllPlaylists(cursor: Cursor?): ArrayList<Playlist> {
val playlists = ArrayList<Playlist>()
if (cursor != null && cursor.moveToFirst()) {
do {
playlists.add(getPlaylistFromCursorImpl(cursor))
} while (cursor.moveToNext())
}
cursor?.close()
return playlists
}
fun deletePlaylists(context: Context, playlistId: Long) {
@ -118,4 +151,42 @@ object PlaylistLoader {
localStringBuilder.append(")")
context.contentResolver.delete(localUri, localStringBuilder.toString(), null)
}
private fun makePlaylistCursor(
context: Context,
selection: String?,
values: Array<String>?
): Cursor? {
try {
return context.contentResolver.query(
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
arrayOf(BaseColumns._ID, /* 0 */
PlaylistsColumns.NAME), /* 1 */
selection,
values,
MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER)
} catch (e: SecurityException) {
return null
}
}
fun getPlaylist(
context: Context,
playlistId: Int
): 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)
}
}

View file

@ -24,23 +24,33 @@ 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>> {
fun getPlaylistSongListFlowable(
context: Context,
playlist: Playlist
): Observable<ArrayList<Song>> {
return (playlist as? AbsCustomPlaylist)?.getSongsFlowable(context)
?: getPlaylistSongListFlowable(context, playlist.id)
}
fun getPlaylistSongList(
context: Context,
playlist: Playlist
): ArrayList<Song> {
return (playlist as? AbsCustomPlaylist)?.getSongs(context)
?: getPlaylistSongList(context, playlist.id)
}
@NonNull
fun getPlaylistSongList(@NonNull context: Context, playlistId: Int): Observable<ArrayList<Song>> {
fun getPlaylistSongListFlowable(context: Context, playlistId: Int): Observable<ArrayList<Song>> {
return Observable.create { e ->
val songs = ArrayList<Song>()
val cursor = makePlaylistSongCursor(context, playlistId)
@ -56,8 +66,21 @@ object PlaylistSongsLoader {
}
}
@NonNull
private fun getPlaylistSongFromCursorImpl(@NonNull cursor: Cursor, playlistId: Int): PlaylistSong {
fun getPlaylistSongList(context: Context, playlistId: Int): ArrayList<Song> {
val songs = arrayListOf<Song>()
val cursor = makePlaylistSongCursor(context, playlistId)
if (cursor != null && cursor.moveToFirst()) {
do {
songs.add(getPlaylistSongFromCursorImpl(cursor, playlistId))
} while (cursor.moveToNext())
}
cursor?.close()
return songs
}
private fun getPlaylistSongFromCursorImpl(cursor: Cursor, playlistId: Int): PlaylistSong {
val id = cursor.getInt(0)
val title = cursor.getString(1)
val trackNumber = cursor.getInt(2)
@ -75,7 +98,7 @@ object PlaylistSongsLoader {
return PlaylistSong(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName, artistId, artistName, playlistId, idInPlaylist, composer)
}
private fun makePlaylistSongCursor(@NonNull context: Context, playlistId: Int): Cursor? {
private fun makePlaylistSongCursor(context: Context, playlistId: Int): Cursor? {
try {
return context.contentResolver.query(
MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId.toLong()),

View file

@ -15,42 +15,33 @@
package code.name.monkey.retromusic.loaders
import android.content.Context
import android.text.TextUtils
import code.name.monkey.retromusic.R
import io.reactivex.Observable
import java.util.*
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)
}
}
fun searchAll(context: Context, query: String?): MutableList<Any> {
val results = mutableListOf<Any>()
query?.let {
val songs = SongLoader.getSongs(context, it)
if (songs.isNotEmpty()) {
results.add(context.resources.getString(R.string.songs))
results.addAll(songs)
}
val artists = ArtistLoader.getArtists(context, it)
if (artists.isNotEmpty()) {
results.add(context.resources.getString(R.string.artists))
results.addAll(artists)
}
val albums = AlbumLoader.getAlbums(context, it)
if (albums.isNotEmpty()) {
results.add(context.resources.getString(R.string.albums))
results.addAll(albums)
}
e.onNext(results)
e.onComplete()
}
return results
}
}

View file

@ -27,24 +27,29 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.Observable
import java.util.*
/**
* Created by hemanths on 10/08/17.
*/
object SongLoader {
fun getAllSongsFlowable(
context: Context
): Observable<ArrayList<Song>> {
val cursor = makeSongCursor(context, null, null)
return getSongsFlowable(cursor)
}
fun getAllSongs(context: Context): Observable<ArrayList<Song>> {
fun getAllSongs(
context: Context
): 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(cursor: Cursor?): Observable<ArrayList<Song>> {
fun getSongsFlowable(
cursor: Cursor?
): Observable<ArrayList<Song>> {
return Observable.create { e ->
val songs = ArrayList<Song>()
if (cursor != null && cursor.moveToFirst()) {
@ -59,7 +64,96 @@ object SongLoader {
}
}
private fun getSongFromCursorImpl(cursor: Cursor): Song {
fun getSongs(
cursor: Cursor?
): ArrayList<Song> {
val songs = arrayListOf<Song>()
if (cursor != null && cursor.moveToFirst()) {
do {
songs.add(getSongFromCursorImpl(cursor))
} while (cursor.moveToNext())
}
cursor?.close()
return songs
}
fun getSongsFlowable(
context: Context,
query: String
): Observable<ArrayList<Song>> {
val cursor = makeSongCursor(context, AudioColumns.TITLE + " LIKE ?", arrayOf("%$query%"))
return getSongsFlowable(cursor)
}
fun getSongs(
context: Context,
query: String
): ArrayList<Song> {
val cursor = makeSongCursor(context, AudioColumns.TITLE + " LIKE ?", arrayOf("%$query%"))
return getSongs(cursor)
}
private fun getSongFlowable(
cursor: Cursor?
): Observable<Song> {
return Observable.create { e ->
val song: Song = if (cursor != null && cursor.moveToFirst()) {
getSongFromCursorImpl(cursor)
} else {
Song.emptySong
}
cursor?.close()
e.onNext(song)
e.onComplete()
}
}
fun getSong(
cursor: Cursor?
): Song {
val song: Song
if (cursor != null && cursor.moveToFirst()) {
song = getSongFromCursorImpl(cursor)
} else {
song = Song.emptySong
}
cursor?.close()
return song
}
fun getSongFlowable(
context: Context,
queryId: Int
): Observable<Song> {
val cursor = makeSongCursor(context, AudioColumns._ID + "=?",
arrayOf(queryId.toString()))
return getSongFlowable(cursor)
}
fun getSong(context: Context, queryId: Int): Song {
val cursor = makeSongCursor(context, AudioColumns._ID + "=?", arrayOf(queryId.toString()))
return getSong(cursor)
}
fun suggestSongs(
context: Context
): Observable<ArrayList<Song>> {
return SongLoader.getAllSongsFlowable(context)
.flatMap {
val list = ArrayList<Song>()
ShuffleHelper.makeShuffleList(it, -1)
if (it.size >= 7) {
list.addAll(it.subList(0, 7))
}
return@flatMap Observable.just(list)
}
}
private fun getSongFromCursorImpl(
cursor: Cursor
): Song {
val id = cursor.getInt(0)
val title = cursor.getString(1)
val trackNumber = cursor.getInt(2)
@ -78,7 +172,12 @@ object SongLoader {
}
@JvmOverloads
fun makeSongCursor(context: Context, selection: String?, selectionValues: Array<String>?, sortOrder: String = PreferenceUtil.getInstance().songSortOrder): Cursor? {
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 <= ' ' } != "") {
@ -103,7 +202,10 @@ object SongLoader {
}
private fun generateBlacklistSelection(selection: String?, pathCount: Int): String {
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 ?")
@ -113,8 +215,10 @@ object SongLoader {
return newSelection.toString()
}
private fun addBlacklistSelectionValues(selectionValues: Array<String>?,
paths: ArrayList<String>): Array<String>? {
private fun addBlacklistSelectionValues(
selectionValues: Array<String>?,
paths: ArrayList<String>
): Array<String>? {
var selectionValuesFinal = selectionValues
if (selectionValuesFinal == null) {
selectionValuesFinal = emptyArray()
@ -128,35 +232,4 @@ object SongLoader {
}
return newSelectionValues
}
private fun getSong(cursor: Cursor?): Observable<Song> {
return Observable.create { e ->
val song: Song = if (cursor != null && cursor.moveToFirst()) {
getSongFromCursorImpl(cursor)
} else {
Song.emptySong
}
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 >= 7) {
list.addAll(it.subList(0, 7))
}
return@flatMap Observable.just(list)
}
}
}

View file

@ -32,11 +32,19 @@ import java.util.*
object TopAndRecentlyPlayedTracksLoader {
fun getRecentlyPlayedTracks(context: Context): Observable<ArrayList<Song>> {
fun getRecentlyPlayedTracksFlowable(context: Context): Observable<ArrayList<Song>> {
return SongLoader.getSongsFlowable(makeRecentTracksCursorAndClearUpDatabase(context))
}
fun getRecentlyPlayedTracks(context: Context): ArrayList<Song> {
return SongLoader.getSongs(makeRecentTracksCursorAndClearUpDatabase(context))
}
fun getTopTracks(context: Context): Observable<ArrayList<Song>> {
fun getTopTracksFlowable(context: Context): Observable<ArrayList<Song>> {
return SongLoader.getSongsFlowable(makeTopTracksCursorAndClearUpDatabase(context))
}
fun getTopTracks(context: Context): ArrayList<Song> {
return SongLoader.getSongs(makeTopTracksCursorAndClearUpDatabase(context))
}
@ -130,9 +138,11 @@ object TopAndRecentlyPlayedTracksLoader {
return null
}
fun getTopAlbums(context: Context): Observable<ArrayList<Album>> {
fun getTopAlbumsFlowable(
context: Context
): Observable<ArrayList<Album>> {
return Observable.create { e ->
getTopTracks(context).subscribe { songs ->
getTopTracksFlowable(context).subscribe { songs ->
if (songs.size > 0) {
e.onNext(AlbumLoader.splitIntoAlbums(songs))
}
@ -141,9 +151,16 @@ object TopAndRecentlyPlayedTracksLoader {
}
}
fun getTopArtists(context: Context): Observable<ArrayList<Artist>> {
fun getTopAlbums(
context: Context
): ArrayList<Album> {
arrayListOf<Album>()
return AlbumLoader.splitIntoAlbums(getTopTracks(context))
}
fun getTopArtistsFlowable(context: Context): Observable<ArrayList<Artist>> {
return Observable.create { e ->
getTopAlbums(context).subscribe { albums ->
getTopAlbumsFlowable(context).subscribe { albums ->
if (albums.size > 0) {
e.onNext(ArtistLoader.splitIntoArtists(albums))
}
@ -151,4 +168,8 @@ object TopAndRecentlyPlayedTracksLoader {
}
}
}
fun getTopArtists(context: Context): ArrayList<Artist> {
return ArtistLoader.splitIntoArtists(getTopAlbums(context))
}
}