Add [Very hacky] genre support
Add a way to load genres! Except it creates duplicates. And requires creating like 20 music cursors. At least it works?
This commit is contained in:
parent
f8ae5d57a5
commit
160013bbe9
3 changed files with 105 additions and 39 deletions
|
@ -52,12 +52,12 @@ dependencies {
|
|||
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
|
||||
|
||||
/*
|
||||
// Room Database
|
||||
def room_version = "2.2.5"
|
||||
kapt "androidx.room:room-compiler:$room_version"
|
||||
implementation "androidx.room:room-runtime:$room_version"
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
|
||||
*/
|
||||
|
||||
// Lifecycle
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Application
|
|||
import android.content.ContentResolver
|
||||
import android.database.Cursor
|
||||
import android.provider.MediaStore
|
||||
import android.provider.MediaStore.Audio.Genres
|
||||
import android.provider.MediaStore.Audio.AudioColumns
|
||||
import android.util.Log
|
||||
import org.oxycblt.auxio.music.models.Song
|
||||
|
@ -17,8 +18,10 @@ enum class MusicLoaderResponse {
|
|||
class MusicLoader(private val app: Application) {
|
||||
|
||||
var songs = mutableListOf<Song>()
|
||||
var genres = mutableListOf<Pair<Long, String>>()
|
||||
|
||||
private var musicCursor: Cursor? = null
|
||||
private var genreCursor: Cursor? = null
|
||||
|
||||
val response: MusicLoaderResponse
|
||||
|
||||
|
@ -27,14 +30,15 @@ class MusicLoader(private val app: Application) {
|
|||
}
|
||||
|
||||
private fun findMusic(): MusicLoaderResponse {
|
||||
try {
|
||||
musicCursor = getCursor(
|
||||
genreCursor = getGenreCursor(
|
||||
app.contentResolver
|
||||
)
|
||||
|
||||
Log.i(this::class.simpleName, "Starting music search...")
|
||||
useGenreCursor()
|
||||
|
||||
useCursor()
|
||||
indexMusic()
|
||||
|
||||
try {
|
||||
} catch (error: Exception) {
|
||||
Log.e(this::class.simpleName, "Something went horribly wrong.")
|
||||
error.printStackTrace()
|
||||
|
@ -63,14 +67,30 @@ class MusicLoader(private val app: Application) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun getCursor(resolver: ContentResolver): Cursor? {
|
||||
private fun getGenreCursor(resolver: ContentResolver): Cursor? {
|
||||
Log.i(this::class.simpleName, "Getting genre cursor.")
|
||||
|
||||
// Get every Genre indexed by the android system, for some reason
|
||||
// you cant directly get this from the plain music cursor.
|
||||
return resolver.query(
|
||||
Genres.EXTERNAL_CONTENT_URI,
|
||||
arrayOf(
|
||||
Genres._ID, // 0
|
||||
Genres.NAME // 1
|
||||
),
|
||||
null, null,
|
||||
Genres.DEFAULT_SORT_ORDER
|
||||
)
|
||||
}
|
||||
|
||||
private fun getMusicCursor(resolver: ContentResolver, genreId: Long): Cursor? {
|
||||
Log.i(this::class.simpleName, "Getting music cursor.")
|
||||
|
||||
// Get all the values that can be retrieved by the cursor.
|
||||
// The rest are retrieved using MediaMetadataExtractor and
|
||||
// stored into a database.
|
||||
return resolver.query(
|
||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
Genres.Members.getContentUri("external", genreId),
|
||||
arrayOf(
|
||||
AudioColumns._ID, // 0
|
||||
AudioColumns.DISPLAY_NAME, // 1
|
||||
|
@ -86,11 +106,54 @@ class MusicLoader(private val app: Application) {
|
|||
)
|
||||
}
|
||||
|
||||
// Use the cursor index music files from the shared storage, returns true if any were found.
|
||||
private fun useCursor() {
|
||||
// Use the genre cursor to index all the genres the android system has indexed.
|
||||
private fun useGenreCursor() {
|
||||
// TODO: Move genre to its own model, even if its just two values
|
||||
|
||||
genreCursor?.use { cursor ->
|
||||
|
||||
// Don't even bother running if there's nothing to process.
|
||||
if (cursor.count == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
val idIndex = cursor.getColumnIndexOrThrow(Genres._ID)
|
||||
val nameIndex = cursor.getColumnIndexOrThrow(Genres.NAME)
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
genres.add(
|
||||
Pair<Long, String>(
|
||||
cursor.getLong(idIndex),
|
||||
cursor.getString(nameIndex)
|
||||
)
|
||||
)
|
||||
|
||||
Log.i(this::class.simpleName, cursor.getString(nameIndex))
|
||||
}
|
||||
|
||||
cursor.close()
|
||||
}
|
||||
|
||||
Log.i(this::class.simpleName, "Retrieved " + genres.size.toString() + " Genres.")
|
||||
}
|
||||
|
||||
// Use the cursor index music files from the shared storage.
|
||||
private fun indexMusic() {
|
||||
Log.i(this::class.simpleName, "Starting music search...")
|
||||
|
||||
// So, android has a brain aneurysm if you try to get an audio genre through
|
||||
// AudioColumns. As a result, I just index every genre's name & ID, create a cursor
|
||||
// of music for that genres ID, and then load and iterate through them normally,
|
||||
// creating using the genres name as that songs Genre.
|
||||
|
||||
// God why do I have to do this
|
||||
for (genre in genres) {
|
||||
val musicCursor = getMusicCursor(app.contentResolver, genre.first)
|
||||
|
||||
musicCursor?.use { cursor ->
|
||||
|
||||
// Don't run the more expensive file loading operations if there is no music to index.
|
||||
// Don't run the more expensive file loading operations if there
|
||||
// is no music to index.
|
||||
if (cursor.count == 0) {
|
||||
return
|
||||
}
|
||||
|
@ -106,9 +169,10 @@ class MusicLoader(private val app: Application) {
|
|||
|
||||
while (cursor.moveToNext()) {
|
||||
val id = cursor.getLong(idIndex)
|
||||
val display = cursor.getString(displayIndex)
|
||||
|
||||
// Get the basic metadata from the cursor
|
||||
val title = cursor.getString(titleIndex) ?: cursor.getString(displayIndex)
|
||||
val title = cursor.getString(titleIndex) ?: display
|
||||
val artist = cursor.getString(artistIndex)
|
||||
val album = cursor.getString(albumIndex)
|
||||
val year = cursor.getInt(yearIndex)
|
||||
|
@ -120,7 +184,7 @@ class MusicLoader(private val app: Application) {
|
|||
songs.add(
|
||||
Song(
|
||||
id, title, artist, album,
|
||||
year, track, duration
|
||||
genre.second, year, track, duration
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -129,3 +193,4 @@ class MusicLoader(private val app: Application) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ data class Song(
|
|||
val name: String?,
|
||||
val artist: String?,
|
||||
val album: String?,
|
||||
val genre: String?,
|
||||
val year: Int,
|
||||
val track: Int,
|
||||
val duration: Long,
|
||||
|
|
Loading…
Reference in a new issue