When adding tracks to the library only 40 tracks are added initially. A background coroutine for adding the remainder of the tracks continues. The coroutine does not block the main thread. #43

This commit is contained in:
amazing-username
2019-04-07 10:59:54 -04:00
parent 10d399afa7
commit 9e79ebb8d0
9 changed files with 109 additions and 44 deletions
@@ -48,7 +48,7 @@ class MusicFiles (private val demoPath: File) {
fun searchForMp3Songs() { fun searchForMp3Songs() {
try { try {
var pathList: MutableList<String>? = null var pathList: MutableList<String>?
pathList = mutableListOf() pathList = mutableListOf()
var fileSearch = File(demoPath.absolutePath) var fileSearch = File(demoPath.absolutePath)
@@ -56,12 +56,13 @@ class MusicFiles (private val demoPath: File) {
println(it.absolutePath) println(it.absolutePath)
if (!ignoreThisDirectory(it.absolutePath)) { if (!ignoreThisDirectory(it.absolutePath)) {
if (it.isFile) { if (it.isFile) {
if (it.extension.toString().equals(FileTypes.Mp3)) { if (it.extension == (FileTypes.Mp3)) {
pathList.add(it.absolutePath) pathList.add(it.absolutePath)
} }
} }
} }
} }
allSongs = pathList allSongs = pathList
} }
catch (ex: Exception) { catch (ex: Exception) {
@@ -3,7 +3,9 @@ package com.example.mear.management
import android.content.Context import android.content.Context
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import java.io.FileInputStream
import java.lang.Exception import java.lang.Exception
import kotlinx.coroutines.*
import com.example.mear.constants.Filenames import com.example.mear.constants.Filenames
import com.example.mear.constants.SongSearch import com.example.mear.constants.SongSearch
@@ -13,8 +15,17 @@ import com.example.mear.repositories.TrackRepository
import com.example.mear.util.ConvertByteArray import com.example.mear.util.ConvertByteArray
class TrackManager(var allSongPath: MutableList<String>) { class TrackManager(var allSongPath: MutableList<String>) {
private var songCount: Int? = null
private var allTracks: MutableList<Track>? = null private var allTracks: MutableList<Track>? = null
private var ctx: Context? = null
private var songCount: Int? = null
private var songIndex: Int? = null
private var moreSongs = true
var allTracksAdded = false
fun initializeContext(context: Context) {
ctx = context
}
fun configureTracks(ctx: Context): Int { fun configureTracks(ctx: Context): Int {
var id = 0 var id = 0
@@ -49,21 +60,57 @@ class TrackManager(var allSongPath: MutableList<String>) {
TrackRepository(ctx).createSongCount(id) TrackRepository(ctx).createSongCount(id)
return id.dec() return id.dec()
} }
fun addTracks(ctx: Context) { fun addTracks() {
var initTracks = initialTracks() var initTracks = initialTracks()
addToDatabase(ctx, initTracks) addToDatabase(initTracks)
TrackRepository(ctx).createSongCount(songCount!!)
if (moreSongs) {
GlobalScope.launch {
val remainingTracks = remainingTracks()
addToDatabase(remainingTracks)
allTracksAdded = true
}
}
} }
private fun initialTracks(): MutableList<Track> { private fun initialTracks(): MutableList<Track> {
var tracks = mutableListOf<Track>() var tracks = mutableListOf<Track>()
try { try {
for (i in 0.. (SongSearch.INITIAL_SEARCH_AMOUNT - 1)) { var initSongSearch = SongSearch.INITIAL_SEARCH_AMOUNT -1
if (allSongPath!!.size < SongSearch.INITIAL_SEARCH_AMOUNT) {
initSongSearch = allSongPath.size
moreSongs = false
}
for (i in 0.. initSongSearch) {
var songPath = allSongPath[i] var songPath = allSongPath[i]
val track = configureTrack(songPath, i) val track = configureTrack(songPath, i)
tracks.add(track) tracks.add(track)
} }
songCount = tracks.size songCount = tracks.size
songIndex = songCount!!
}
catch (ex: Exception) {
val exMsg = ex.message
}
return tracks
}
private fun remainingTracks(): MutableList<Track> {
val tracks = mutableListOf<Track>()
try {
for (i in songIndex!! .. (allSongPath.size - 1)) {
val songPath = allSongPath[i]
val track = configureTrack(songPath, i)
if (track.id != Int.MAX_VALUE) {
tracks.add(track)
}
}
songCount = songCount!!.plus(tracks.size)
} }
catch (ex: Exception) { catch (ex: Exception) {
val exMsg = ex.message val exMsg = ex.message
@@ -73,17 +120,33 @@ class TrackManager(var allSongPath: MutableList<String>) {
} }
private fun configureTrack(songPath: String, id: Int): Track { private fun configureTrack(songPath: String, id: Int): Track {
try {
val metaData = MediaMetadataRetriever() val metaData = MediaMetadataRetriever()
metaData.setDataSource(songPath) val fp = FileInputStream(songPath)
metaData.setDataSource(fp.fd)
val title = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) val title = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
val artist = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST) val artist = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)
val album = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) val album = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)
val duration = (metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toInt()) / 1000 val duration = (metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toInt()) / 1000
fp.close()
metaData.release()
return Track(id, title, artist, album, duration, ByteArray(0), songPath) return Track(id, title, artist, album, duration, ByteArray(0), songPath)
} }
catch (ex: Exception) {
val exMsg = ex.message
}
return Track()
}
private fun addToDatabase(tracks: List<Track>) {
TrackRepository(ctx!!).insertTracks(tracks)
PlayCountRepository(ctx!!).insertPlayCounts(tracks)
TrackRepository(ctx!!).createSongCount(songCount!!)
}
private fun addToDatabase(ctx: Context, tracks: List<Track>) { private fun addToDatabase(ctx: Context, tracks: List<Track>) {
TrackRepository(ctx).insertTracks(tracks) TrackRepository(ctx).insertTracks(tracks)
PlayCountRepository(ctx).insertPlayCounts(tracks) PlayCountRepository(ctx).insertPlayCounts(tracks)
@@ -1,5 +1,6 @@
package com.example.mear.models package com.example.mear.models
data class Track (val id: Int, val title: String, val artist: String, val album: String, data class Track (val id: Int = Int.MAX_VALUE, val title: String = "UNTITLED", val artist: String = "UNTITLED",
val length: Int, val TrackCover: ByteArray, val songPath: String) { val album: String = "UNTITLED", val length: Int = Int.MAX_VALUE,
val TrackCover: ByteArray = ByteArray(0), val songPath: String = "UNTITLED") {
} }
@@ -27,6 +27,8 @@ class MusicService: Service() {
} }
private var trackPlayer: MediaPlayer? = null private var trackPlayer: MediaPlayer? = null
private var trackMgr: TrackManager? = null
private var currentTrack = Track()
private var currentSongIndex: Int? = null private var currentSongIndex: Int? = null
private var shuffleOn: Boolean? = null private var shuffleOn: Boolean? = null
private var repeatOn: Boolean? = null private var repeatOn: Boolean? = null
@@ -70,12 +72,18 @@ class MusicService: Service() {
} }
fun playTrack(id: Int) { fun playTrack(id: Int) {
try {
currentSongIndex = id currentSongIndex = id
trackPlayer!!.reset() trackPlayer!!.reset()
trackPlayer!!.setDataSource(TrackRepository(this).getTrack(id).songPath) currentTrack = TrackRepository(this).getTrack(id)
trackPlayer!!.setDataSource(currentTrack.songPath)
trackPlayer!!.prepare() trackPlayer!!.prepare()
trackPlayer!!.start() trackPlayer!!.start()
} }
catch (ex: Exception) {
val exMsg = ex.message
}
}
fun goToPosition(progress: Int) { fun goToPosition(progress: Int) {
trackPlayer!!.seekTo(progress) trackPlayer!!.seekTo(progress)
@@ -102,14 +110,15 @@ class MusicService: Service() {
shuffleOn = retrieveShuffleMode() shuffleOn = retrieveShuffleMode()
trackPlayer!!.reset() trackPlayer!!.reset()
if (duration > seconds) { if (duration > seconds) {
trackPlayer!!.setDataSource(TrackRepository(this).getTrack(currentSongIndex!!).songPath) currentTrack = TrackRepository(this).getTrack(currentSongIndex!!)
trackPlayer!!.setDataSource(currentTrack.songPath)
trackPlayer!!.prepare() trackPlayer!!.prepare()
trackPlayer!!.start() trackPlayer!!.start()
} }
else { else {
val previousTrackNumber = fetchSongIndex(PlayTypes.PlayPreviousSong) val previousTrackNumber = fetchSongIndex(PlayTypes.PlayPreviousSong)
val track = TrackRepository(this).getTrack(previousTrackNumber) currentTrack = TrackRepository(this).getTrack(previousTrackNumber)
trackPlayer!!.setDataSource(track.songPath) trackPlayer!!.setDataSource(currentTrack.songPath)
trackPlayer!!.prepare() trackPlayer!!.prepare()
trackPlayer!!.start() trackPlayer!!.start()
} }
@@ -123,8 +132,9 @@ class MusicService: Service() {
trackPlayer!!.reset() trackPlayer!!.reset()
shuffleOn = retrieveShuffleMode() shuffleOn = retrieveShuffleMode()
var nextTrack = fetchSongIndex(PlayTypes.PlayNextSong) var nextTrack = fetchSongIndex(PlayTypes.PlayNextSong)
val track = TrackRepository(this).getTrack(nextTrack) val allTracks = TrackRepository(this).getAll()
trackPlayer!!.setDataSource(track.songPath) currentTrack = TrackRepository(this).getTrack(nextTrack)
trackPlayer!!.setDataSource(currentTrack.songPath)
trackPlayer!!.prepare() trackPlayer!!.prepare()
trackPlayer!!.start() trackPlayer!!.start()
} }
@@ -180,16 +190,8 @@ class MusicService: Service() {
} }
fun getCurrentTrack(): Track { fun getCurrentTrack(): Track {
var track: Track? = null
track = TrackRepository(this).getTrack(currentSongIndex!!) return currentTrack
val info = trackPlayer!!.trackInfo
if (trackPlayer!!.isPlaying) {
val res = "songs are being played"
}
return track!!
} }
@@ -266,8 +268,8 @@ class MusicService: Service() {
} }
currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount()) currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount())
val trackToPlay = TrackRepository(this).getTrack(currentSongIndex!!) currentTrack = TrackRepository(this).getTrack(currentSongIndex!!)
trackPlayer!!.setDataSource(trackToPlay.songPath) trackPlayer!!.setDataSource(currentTrack.songPath)
trackPlayer!!.prepareAsync() trackPlayer!!.prepareAsync()
trackPlayer!!.setOnCompletionListener { trackPlayer!!.setOnCompletionListener {
playNextTrack() playNextTrack()
@@ -281,8 +283,9 @@ class MusicService: Service() {
var mp3Paths = MusicFiles(android.os.Environment.getExternalStorageDirectory()) var mp3Paths = MusicFiles(android.os.Environment.getExternalStorageDirectory())
mp3Paths.searchForMp3Songs() mp3Paths.searchForMp3Songs()
val paths = mp3Paths.allSongs val paths = mp3Paths.allSongs
val trackMgr = TrackManager(paths!!) trackMgr = TrackManager(paths!!)
trackMgr.addTracks(this) trackMgr!!.initializeContext(this)
trackMgr!!.addTracks()
initializeShuffleMode() initializeShuffleMode()
initializeRepeatMode() initializeRepeatMode()
} }
@@ -375,11 +378,8 @@ class MusicService: Service() {
try { try {
val count = TrackRepository(this).getSongCount() val count = TrackRepository(this).getSongCount()
TrackRepository(this).delete()
// TODO: Replace this with the local count varialbe when issue #43 is resolved return count
// as well as remove the call to delete the Track table
return 0
} }
catch (ex: Exception) { catch (ex: Exception) {
val exMsg = ex.message val exMsg = ex.message
Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B