Merge pull request #40 from h4h13/kotlin

Kotlin
main
Hemanth S 2018-11-28 13:26:31 +05:30 committed by GitHub
commit 4f1627876b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 267 additions and 247 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,5 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
android { android {
compileSdkVersion 28 compileSdkVersion 28
@ -143,4 +144,11 @@ dependencies {
implementation 'com.github.hannesa2:AndroidSlidingUpPanel:3.5.0' implementation 'com.github.hannesa2:AndroidSlidingUpPanel:3.5.0'
implementation 'com.github.AdrienPoupa:jaudiotagger:2.2.3' implementation 'com.github.AdrienPoupa:jaudiotagger:2.2.3'
implementation 'org.nanohttpd:nanohttpd:2.3.1' implementation 'org.nanohttpd:nanohttpd:2.3.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
repositories {
mavenCentral()
} }

View File

@ -409,7 +409,7 @@ public class MusicPlayerRemote {
MediaStore.Audio.AudioColumns._ID + "=?", MediaStore.Audio.AudioColumns._ID + "=?",
new String[]{songId} new String[]{songId}
));*/ ));*/
songs = SongLoader.getSongs(SongLoader.makeSongCursor( songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
musicService, musicService,
MediaStore.Audio.AudioColumns._ID + "=?", MediaStore.Audio.AudioColumns._ID + "=?",
new String[]{songId})) new String[]{songId}))
@ -431,7 +431,7 @@ public class MusicPlayerRemote {
songFile = new File(uri.getPath()); songFile = new File(uri.getPath());
} }
if (songFile != null) { if (songFile != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor( songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
musicService, musicService,
MediaStore.Audio.AudioColumns.DATA + "=?", MediaStore.Audio.AudioColumns.DATA + "=?",
new String[]{songFile.getAbsolutePath()} new String[]{songFile.getAbsolutePath()}

View File

@ -36,51 +36,51 @@ public class SearchQueryHelper {
ArrayList<Song> songs = new ArrayList<>(); ArrayList<Song> songs = new ArrayList<>();
if (artistName != null && albumName != null && titleName != null) { if (artistName != null && albumName != null && titleName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ARTIST_SELECTION + AND + ALBUM_SELECTION + AND + TITLE_SELECTION, new String[]{artistName.toLowerCase(), albumName.toLowerCase(), titleName.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ARTIST_SELECTION + AND + ALBUM_SELECTION + AND + TITLE_SELECTION, new String[]{artistName.toLowerCase(), albumName.toLowerCase(), titleName.toLowerCase()})).blockingFirst();
} }
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }
if (artistName != null && titleName != null) { if (artistName != null && titleName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ARTIST_SELECTION + AND + TITLE_SELECTION, new String[]{artistName.toLowerCase(), titleName.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ARTIST_SELECTION + AND + TITLE_SELECTION, new String[]{artistName.toLowerCase(), titleName.toLowerCase()})).blockingFirst();
} }
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }
if (albumName != null && titleName != null) { if (albumName != null && titleName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ALBUM_SELECTION + AND + TITLE_SELECTION, new String[]{albumName.toLowerCase(), titleName.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ALBUM_SELECTION + AND + TITLE_SELECTION, new String[]{albumName.toLowerCase(), titleName.toLowerCase()})).blockingFirst();
} }
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }
if (artistName != null) { if (artistName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ARTIST_SELECTION, new String[]{artistName.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ARTIST_SELECTION, new String[]{artistName.toLowerCase()})).blockingFirst();
} }
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }
if (albumName != null) { if (albumName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ALBUM_SELECTION, new String[]{albumName.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ALBUM_SELECTION, new String[]{albumName.toLowerCase()})).blockingFirst();
} }
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }
if (titleName != null) { if (titleName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, TITLE_SELECTION, new String[]{titleName.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, TITLE_SELECTION, new String[]{titleName.toLowerCase()})).blockingFirst();
} }
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ARTIST_SELECTION, new String[]{query.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ARTIST_SELECTION, new String[]{query.toLowerCase()})).blockingFirst();
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ALBUM_SELECTION, new String[]{query.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ALBUM_SELECTION, new String[]{query.toLowerCase()})).blockingFirst();
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, TITLE_SELECTION, new String[]{query.toLowerCase()})).blockingFirst(); songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, TITLE_SELECTION, new String[]{query.toLowerCase()})).blockingFirst();
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
return songs; return songs;
} }

View File

@ -17,7 +17,7 @@ import java.util.ArrayList;
public class AlbumLoader { public class AlbumLoader {
public static Observable<ArrayList<Album>> getAllAlbums(@NonNull Context context) { public static Observable<ArrayList<Album>> getAllAlbums(@NonNull Context context) {
Observable<ArrayList<Song>> songs = SongLoader.getSongs(SongLoader.makeSongCursor( Observable<ArrayList<Song>> songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
context, context,
null, null,
null, null,
@ -30,7 +30,7 @@ public class AlbumLoader {
@NonNull @NonNull
public static Observable<ArrayList<Album>> getAlbums(@NonNull final Context context, public static Observable<ArrayList<Album>> getAlbums(@NonNull final Context context,
String query) { String query) {
Observable<ArrayList<Song>> songs = SongLoader.getSongs(SongLoader.makeSongCursor( Observable<ArrayList<Song>> songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
context, context,
AudioColumns.ALBUM + " LIKE ?", AudioColumns.ALBUM + " LIKE ?",
new String[]{"%" + query + "%"}, new String[]{"%" + query + "%"},
@ -42,7 +42,7 @@ public class AlbumLoader {
@NonNull @NonNull
public static Observable<Album> getAlbum(@NonNull final Context context, int albumId) { public static Observable<Album> getAlbum(@NonNull final Context context, int albumId) {
return Observable.create(e -> { return Observable.create(e -> {
Observable<ArrayList<Song>> songs = SongLoader.getSongs(SongLoader Observable<ArrayList<Song>> songs = SongLoader.Companion.getSongs(SongLoader.Companion
.makeSongCursor(context, AudioColumns.ALBUM_ID + "=?", .makeSongCursor(context, AudioColumns.ALBUM_ID + "=?",
new String[]{String.valueOf(albumId)}, getSongLoaderSortOrder(context))); new String[]{String.valueOf(albumId)}, getSongLoaderSortOrder(context)));
songs.subscribe(songs1 -> { songs.subscribe(songs1 -> {

View File

@ -22,7 +22,7 @@ public class ArtistLoader {
@NonNull @NonNull
public static Observable<Artist> getArtist(@NonNull final Context context, int artistId) { public static Observable<Artist> getArtist(@NonNull final Context context, int artistId) {
return Observable.create(e -> SongLoader.getSongs(SongLoader.makeSongCursor( return Observable.create(e -> SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
context, context,
AudioColumns.ARTIST_ID + "=?", AudioColumns.ARTIST_ID + "=?",
new String[]{String.valueOf(artistId)}, new String[]{String.valueOf(artistId)},
@ -36,8 +36,8 @@ public class ArtistLoader {
@NonNull @NonNull
public static Observable<ArrayList<Artist>> getAllArtists(@NonNull final Context context) { public static Observable<ArrayList<Artist>> getAllArtists(@NonNull final Context context) {
return Observable.create(e -> SongLoader return Observable.create(e -> SongLoader.Companion
.getSongs(SongLoader.makeSongCursor( .getSongs(SongLoader.Companion.makeSongCursor(
context, context,
null, null,
null, null,
@ -51,7 +51,7 @@ public class ArtistLoader {
@NonNull @NonNull
public static Observable<ArrayList<Artist>> getArtists(@NonNull final Context context, String query) { public static Observable<ArrayList<Artist>> getArtists(@NonNull final Context context, String query) {
return Observable.create(e -> SongLoader.getSongs(SongLoader.makeSongCursor( return Observable.create(e -> SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
context, context,
AudioColumns.ARTIST + " LIKE ?", AudioColumns.ARTIST + " LIKE ?",
new String[]{"%" + query + "%"}, new String[]{"%" + query + "%"},

View File

@ -17,12 +17,12 @@ public class ArtistSongLoader extends SongLoader {
@NonNull @NonNull
public static Observable<ArrayList<Song>> getArtistSongList(@NonNull final Context context, final int artistId) { public static Observable<ArrayList<Song>> getArtistSongList(@NonNull final Context context, final int artistId) {
return getSongs(makeArtistSongCursor(context, artistId)); return Companion.getSongs(makeArtistSongCursor(context, artistId));
} }
public static Cursor makeArtistSongCursor(@NonNull final Context context, final int artistId) { public static Cursor makeArtistSongCursor(@NonNull final Context context, final int artistId) {
try { try {
return makeSongCursor( return Companion.makeSongCursor(
context, context,
MediaStore.Audio.AudioColumns.ARTIST_ID + "=?", MediaStore.Audio.AudioColumns.ARTIST_ID + "=?",
new String[]{ new String[]{

View File

@ -5,11 +5,11 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.provider.BaseColumns; import android.provider.BaseColumns;
import android.provider.MediaStore.Audio.Genres; import android.provider.MediaStore.Audio.Genres;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList; 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.Genre;
import code.name.monkey.retromusic.model.Song; import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.PreferenceUtil; import code.name.monkey.retromusic.util.PreferenceUtil;
@ -30,7 +30,7 @@ public class GenreLoader {
return getSongsWithNoGenre(context); return getSongsWithNoGenre(context);
} }
return SongLoader.getSongs(makeGenreSongCursor(context, genreId)); return SongLoader.Companion.getSongs(makeGenreSongCursor(context, genreId));
} }
@NonNull @NonNull
@ -46,11 +46,11 @@ public class GenreLoader {
private static Observable<ArrayList<Song>> getSongsWithNoGenre(@NonNull final Context context) { private static Observable<ArrayList<Song>> getSongsWithNoGenre(@NonNull final Context context) {
String selection = BaseColumns._ID + " NOT IN " + String selection = BaseColumns._ID + " NOT IN " +
"(SELECT " + Genres.Members.AUDIO_ID + " FROM audio_genres_map)"; "(SELECT " + Genres.Members.AUDIO_ID + " FROM audio_genres_map)";
return SongLoader.getSongs(SongLoader.makeSongCursor(context, selection, null)); return SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, selection, null));
} }
private static boolean hasSongsWithNoGenre(@NonNull final Context context) { private static boolean hasSongsWithNoGenre(@NonNull final Context context) {
final Cursor allSongsCursor = SongLoader.makeSongCursor(context, null, null); final Cursor allSongsCursor = SongLoader.Companion.makeSongCursor(context, null, null);
final Cursor allSongsWithGenreCursor = makeAllSongsWithGenreCursor(context); final Cursor allSongsWithGenreCursor = makeAllSongsWithGenreCursor(context);
if (allSongsCursor == null || allSongsWithGenreCursor == null) { if (allSongsCursor == null || allSongsWithGenreCursor == null) {
@ -79,7 +79,7 @@ public class GenreLoader {
try { try {
return context.getContentResolver().query( return context.getContentResolver().query(
Genres.Members.getContentUri("external", genreId), Genres.Members.getContentUri("external", genreId),
SongLoader.BASE_PROJECTION, SongLoader.BASE_SELECTION, null, PreferenceUtil.getInstance().getSongSortOrder()); SongLoader.Companion.getBASE_PROJECTION(), SongLoader.BASE_SELECTION, null, PreferenceUtil.getInstance().getSongSortOrder());
} catch (SecurityException e) { } catch (SecurityException e) {
return null; return null;
} }

View File

@ -21,13 +21,13 @@ public class LastAddedSongsLoader {
@NonNull @NonNull
public static Observable<ArrayList<Song>> getLastAddedSongs(@NonNull Context context) { public static Observable<ArrayList<Song>> getLastAddedSongs(@NonNull Context context) {
return SongLoader.getSongs(makeLastAddedCursor(context)); return SongLoader.Companion.getSongs(makeLastAddedCursor(context));
} }
public static Cursor makeLastAddedCursor(@NonNull final Context context) { public static Cursor makeLastAddedCursor(@NonNull final Context context) {
long cutoff = PreferenceUtil.getInstance().getLastAddedCutoff(); long cutoff = PreferenceUtil.getInstance().getLastAddedCutoff();
return SongLoader.makeSongCursor( return SongLoader.Companion.makeSongCursor(
context, context,
MediaStore.Audio.Media.DATE_ADDED + ">?", MediaStore.Audio.Media.DATE_ADDED + ">?",
new String[]{String.valueOf(cutoff)}, new String[]{String.valueOf(cutoff)},

View File

@ -14,7 +14,7 @@ public class SearchLoader {
ArrayList<Object> results = new ArrayList<>(); ArrayList<Object> results = new ArrayList<>();
return Observable.create(e -> { return Observable.create(e -> {
if (!TextUtils.isEmpty(query)) { if (!TextUtils.isEmpty(query)) {
SongLoader.getSongs(context, query) SongLoader.Companion.getSongs(context, query)
.subscribe(songs -> { .subscribe(songs -> {
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
results.add(context.getResources().getString(R.string.songs)); results.add(context.getResources().getString(R.string.songs));

View File

@ -1,196 +0,0 @@
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 java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import code.name.monkey.retromusic.helper.ShuffleHelper;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.providers.BlacklistStore;
import code.name.monkey.retromusic.util.PreferenceUtil;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;
/**
* Created by hemanths on 10/08/17.
*/
public class SongLoader {
protected static final String BASE_SELECTION =
AudioColumns.IS_MUSIC + "=1" + " AND " + AudioColumns.TITLE + " != ''";
protected static final String[] BASE_PROJECTION = new String[]{
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
};
@NonNull
public static Observable<ArrayList<Song>> getAllSongs(@NonNull Context context) {
Cursor cursor = makeSongCursor(context, null, null);
return getSongs(cursor);
}
@NonNull
public static Observable<ArrayList<Song>> getSongs(@NonNull final Context context,
final String query) {
Cursor cursor = makeSongCursor(context, AudioColumns.TITLE + " LIKE ?",
new String[]{"%" + query + "%"});
return getSongs(cursor);
}
@NonNull
public static Observable<ArrayList<Song>> getSongs(@Nullable final Cursor cursor) {
return Observable.create(e -> {
ArrayList<Song> songs = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
songs.add(getSongFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
e.onNext(songs);
e.onComplete();
});
}
@NonNull
private static Song getSongFromCursorImpl(@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 long dateModified = cursor.getLong(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);
}
@Nullable
public static Cursor makeSongCursor(@NonNull final Context context,
@Nullable final String selection, final String[] selectionValues) {
return makeSongCursor(context, selection, selectionValues,
PreferenceUtil.getInstance().getSongSortOrder());
}
@Nullable
public static Cursor makeSongCursor(@NonNull final Context context, @Nullable String selection,
String[] selectionValues, final String sortOrder) {
if (selection != null && !selection.trim().equals("")) {
selection = BASE_SELECTION + " AND " + selection;
} else {
selection = BASE_SELECTION;
}
// Blacklist
ArrayList<String> paths = BlacklistStore.getInstance(context).getPaths();
if (!paths.isEmpty()) {
selection = generateBlacklistSelection(selection, paths.size());
selectionValues = addBlacklistSelectionValues(selectionValues, paths);
}
try {
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
BASE_PROJECTION, selection, selectionValues, sortOrder);
} catch (SecurityException e) {
return null;
}
}
private static String generateBlacklistSelection(String selection, int pathCount) {
StringBuilder newSelection = new StringBuilder(
selection != null && !selection.trim().equals("") ? selection + " AND " : "");
newSelection.append(AudioColumns.DATA + " NOT LIKE ?");
for (int i = 0; i < pathCount - 1; i++) {
newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?");
}
return newSelection.toString();
}
private static String[] addBlacklistSelectionValues(String[] selectionValues,
ArrayList<String> paths) {
if (selectionValues == null) {
selectionValues = new String[0];
}
String[] newSelectionValues = new String[selectionValues.length + paths.size()];
System.arraycopy(selectionValues, 0, newSelectionValues, 0, selectionValues.length);
for (int i = selectionValues.length; i < newSelectionValues.length; i++) {
newSelectionValues[i] = paths.get(i - selectionValues.length) + "%";
}
return newSelectionValues;
}
@NonNull
public static Observable<Song> getSong(@Nullable Cursor cursor) {
return Observable.create(e -> {
Song song;
if (cursor != null && cursor.moveToFirst()) {
song = getSongFromCursorImpl(cursor);
} else {
song = Song.EMPTY_SONG;
}
if (cursor != null) {
cursor.close();
}
e.onNext(song);
e.onComplete();
});
}
@NonNull
public static Observable<Song> getSong(@NonNull final Context context, final int queryId) {
Cursor cursor = makeSongCursor(context, AudioColumns._ID + "=?",
new String[]{String.valueOf(queryId)});
return getSong(cursor);
}
public static Observable<ArrayList<Song>> suggestSongs(@NonNull Context context) {
return SongLoader.getAllSongs(context)
.flatMap((Function<ArrayList<Song>, ObservableSource<ArrayList<Song>>>) songs -> {
ArrayList<Song> list = new ArrayList<>();
ShuffleHelper.makeShuffleList(songs, -1);
if (songs.size() > 9) {
list.addAll(songs.subList(0, 9));
}
return Observable.just(list);
});
/*.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

@ -0,0 +1,182 @@
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.helper.ShuffleHelper
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.providers.BlacklistStore
import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.Observable
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
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(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
}
// 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;
});*/
}
}
}

View File

@ -23,12 +23,12 @@ public class TopAndRecentlyPlayedTracksLoader {
@NonNull @NonNull
public static Observable<ArrayList<Song>> getRecentlyPlayedTracks(@NonNull Context context) { public static Observable<ArrayList<Song>> getRecentlyPlayedTracks(@NonNull Context context) {
return SongLoader.getSongs(makeRecentTracksCursorAndClearUpDatabase(context)); return SongLoader.Companion.getSongs(makeRecentTracksCursorAndClearUpDatabase(context));
} }
@NonNull @NonNull
public static Observable<ArrayList<Song>> getTopTracks(@NonNull Context context) { public static Observable<ArrayList<Song>> getTopTracks(@NonNull Context context) {
return SongLoader.getSongs(makeTopTracksCursorAndClearUpDatabase(context)); return SongLoader.Companion.getSongs(makeTopTracksCursorAndClearUpDatabase(context));
} }
@Nullable @Nullable
@ -122,7 +122,7 @@ public class TopAndRecentlyPlayedTracksLoader {
selection.append(")"); selection.append(")");
// get a list of songs with the data given the selection statement // get a list of songs with the data given the selection statement
Cursor songCursor = SongLoader.makeSongCursor(context, selection.toString(), null); Cursor songCursor = SongLoader.Companion.makeSongCursor(context, selection.toString(), null);
if (songCursor != null) { if (songCursor != null) {
// now return the wrapped TopTracksCursor to handle sorting given order // now return the wrapped TopTracksCursor to handle sorting given order
return new SortedLongCursor(songCursor, order, BaseColumns._ID); return new SortedLongCursor(songCursor, order, BaseColumns._ID);

View File

@ -37,7 +37,7 @@ public class ShuffleAllPlaylist extends AbsSmartPlaylist {
@NonNull @NonNull
@Override @Override
public Observable<ArrayList<Song>> getSongs(@NonNull Context context) { public Observable<ArrayList<Song>> getSongs(@NonNull Context context) {
return SongLoader.getAllSongs(context); return SongLoader.Companion.getAllSongs(context);
} }
@Override @Override

View File

@ -198,6 +198,6 @@ public class MusicPlaybackQueueStore extends SQLiteOpenHelper {
private Observable<ArrayList<Song>> getQueue(@NonNull final String tableName) { private Observable<ArrayList<Song>> getQueue(@NonNull final String tableName) {
Cursor cursor = getReadableDatabase().query(tableName, null, Cursor cursor = getReadableDatabase().query(tableName, null,
null, null, null, null, null); null, null, null, null, null);
return SongLoader.getSongs(cursor); return SongLoader.Companion.getSongs(cursor);
} }
} }

View File

@ -48,17 +48,17 @@ public class RepositoryImpl implements Repository {
@Override @Override
public Observable<ArrayList<Song>> getAllSongs() { public Observable<ArrayList<Song>> getAllSongs() {
return SongLoader.getAllSongs(context); return SongLoader.Companion.getAllSongs(context);
} }
@Override @Override
public Observable<ArrayList<Song>> getSuggestionSongs() { public Observable<ArrayList<Song>> getSuggestionSongs() {
return SongLoader.suggestSongs(context); return SongLoader.Companion.suggestSongs(context);
} }
@Override @Override
public Observable<Song> getSong(int id) { public Observable<Song> getSong(int id) {
return SongLoader.getSong(context, id); return SongLoader.Companion.getSong(context, id);
} }
@Override @Override

View File

@ -238,7 +238,7 @@ public class WearBrowserService extends MediaBrowserService {
} }
break; break;
case TYPE_SONG: case TYPE_SONG:
List<Song> songList = SongLoader.getAllSongs(mContext).blockingFirst(); List<Song> songList = SongLoader.Companion.getAllSongs(mContext).blockingFirst();
for (Song song : songList) { for (Song song : songList) {
fillMediaItems(mediaItems, fillMediaItems(mediaItems,
String.valueOf(song.id), String.valueOf(song.id),
@ -326,7 +326,7 @@ public class WearBrowserService extends MediaBrowserService {
long songId = Long.parseLong(mediaId); long songId = Long.parseLong(mediaId);
setSessionActive(); setSessionActive();
ArrayList<Song> songs = new ArrayList<>(); ArrayList<Song> songs = new ArrayList<>();
songs.add(SongLoader.getSong(mContext, Integer.parseInt(mediaId)).blockingFirst()); songs.add(SongLoader.Companion.getSong(mContext, Integer.parseInt(mediaId)).blockingFirst());
MusicPlayerRemote.openQueue(songs, 0, true); MusicPlayerRemote.openQueue(songs, 0, true);
} }

View File

@ -92,7 +92,7 @@ public class RetroMusicAlbums extends DreamService {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.flatMap((Function<ArrayList<Song>, ObservableSource<ArrayList<Song>>>) songs -> Observable.create(e -> { .flatMap((Function<ArrayList<Song>, ObservableSource<ArrayList<Song>>>) songs -> Observable.create(e -> {
if (songs.isEmpty()) { if (songs.isEmpty()) {
e.onNext(SongLoader.getAllSongs(RetroMusicAlbums.this).blockingFirst()); e.onNext(SongLoader.Companion.getAllSongs(RetroMusicAlbums.this).blockingFirst());
} else { } else {
e.onNext(songs); e.onNext(songs);
} }

View File

@ -147,7 +147,7 @@ public class SongTagEditorActivity extends AbsTagEditorActivity implements TextW
@Override @Override
protected List<String> getSongPaths() { protected List<String> getSongPaths() {
ArrayList<String> paths = new ArrayList<>(1); ArrayList<String> paths = new ArrayList<>(1);
paths.add(SongLoader.getSong(this, getId()).blockingFirst().data); paths.add(SongLoader.Companion.getSong(this, getId()).blockingFirst().data);
return paths; return paths;
} }

View File

@ -363,7 +363,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
CreatePlaylistDialog.create().show(getChildFragmentManager(), "CREATE_PLAYLIST"); CreatePlaylistDialog.create().show(getChildFragmentManager(), "CREATE_PLAYLIST");
return true; return true;
case R.id.action_shuffle_all: case R.id.action_shuffle_all:
MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(getContext()) MusicPlayerRemote.openAndShuffleQueue(SongLoader.Companion.getAllSongs(getContext())
.blockingFirst(), true); .blockingFirst(), true);
return true; return true;
case R.id.action_equalizer: case R.id.action_equalizer:

View File

@ -341,7 +341,7 @@ public class BannerHomeFragment extends AbsMainActivityFragment implements MainA
if (activity != null) { if (activity != null) {
switch (view.getId()) { switch (view.getId()) {
case R.id.action_shuffle: case R.id.action_shuffle:
MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(activity).blockingFirst(), true); MusicPlayerRemote.openAndShuffleQueue(SongLoader.Companion.getAllSongs(activity).blockingFirst(), true);
break; break;
case R.id.last_added: case R.id.last_added:
NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity)); NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity));

View File

@ -4,8 +4,6 @@ import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.os.Environment; import android.os.Environment;
import android.provider.MediaStore; import android.provider.MediaStore;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -22,6 +20,8 @@ import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import code.name.monkey.retromusic.loaders.SongLoader; import code.name.monkey.retromusic.loaders.SongLoader;
import code.name.monkey.retromusic.loaders.SortedCursor; import code.name.monkey.retromusic.loaders.SortedCursor;
import code.name.monkey.retromusic.model.Song; import code.name.monkey.retromusic.model.Song;
@ -47,7 +47,7 @@ public final class FileUtil {
@NonNull @NonNull
public static Observable<ArrayList<Song>> matchFilesWithMediaStore(@NonNull Context context, public static Observable<ArrayList<Song>> matchFilesWithMediaStore(@NonNull Context context,
@Nullable List<File> files) { @Nullable List<File> files) {
return SongLoader.getSongs(makeSongCursor(context, files)); return SongLoader.Companion.getSongs(makeSongCursor(context, files));
} }
public static String safeGetCanonicalPath(File file) { public static String safeGetCanonicalPath(File file) {
@ -75,8 +75,7 @@ public final class FileUtil {
} }
} }
Cursor songCursor = SongLoader Cursor songCursor = SongLoader.Companion.makeSongCursor(context, selection, selection == null ? null : paths);
.makeSongCursor(context, selection, selection == null ? null : paths);
return songCursor == null ? null return songCursor == null ? null
: new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA); : new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA);

View File

@ -224,7 +224,7 @@ public class MusicUtil {
cursor.moveToFirst(); cursor.moveToFirst();
while (!cursor.isAfterLast()) { while (!cursor.isAfterLast()) {
final int id = cursor.getInt(0); final int id = cursor.getInt(0);
Song song = SongLoader.getSong(activity, id).blockingFirst(); Song song = SongLoader.Companion.getSong(activity, id).blockingFirst();
MusicPlayerRemote.removeFromQueue(song); MusicPlayerRemote.removeFromQueue(song);
cursor.moveToNext(); cursor.moveToNext();
} }