From ab1ed63fb0b66f318453d301938de72e244f9bd0 Mon Sep 17 00:00:00 2001 From: amazing-username Date: Sat, 20 Apr 2019 14:02:37 -0400 Subject: [PATCH] Finished #43 --- .../example/mear/activities/MainActivity.kt | 38 +++++- .../com/example/mear/constants/SongSearch.kt | 2 +- .../com/example/mear/management/MusicFiles.kt | 28 +++++ .../example/mear/management/TrackManager.kt | 69 +++++++++-- .../mear/playback/service/MusicService.kt | 115 +++++++++++++++--- .../mear/repositories/TrackRepository.kt | 14 +++ 6 files changed, 228 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/example/mear/activities/MainActivity.kt b/app/src/main/java/com/example/mear/activities/MainActivity.kt index 1ad2dc4..0c004e0 100644 --- a/app/src/main/java/com/example/mear/activities/MainActivity.kt +++ b/app/src/main/java/com/example/mear/activities/MainActivity.kt @@ -38,7 +38,9 @@ import com.example.mear.util.ExtractCover class MainActivity : BaseServiceActivity() { + private var coverArtHandler: Handler? = Handler() private var musicHandler: Handler? = Handler() + private var updateLibraryHandler: Handler? = Handler() private var serviceBinded: Boolean? = false private var repeatOn: Boolean? = false private var shuffleOn: Boolean? = false @@ -288,6 +290,8 @@ class MainActivity : BaseServiceActivity() { } override fun updateTrackProgress() { musicHandler!!.postDelayed(musicTrackTimeUpdateTask, 100) + coverArtHandler!!.postDelayed(updateCoverArt, 100) + updateLibraryHandler!!.postDelayed(updateLibrary, 1000) } private fun configurePlayControlsDisplay() { PlayTrack.background = null @@ -351,12 +355,6 @@ class MainActivity : BaseServiceActivity() { CurrentPosition.text = dur - val trackTitle = musicService!!.getCurrentTrack().title - - if (!(TrackTitle.text == trackTitle)) { - configureTrackDisplay() - } - musicHandler!!.postDelayed(this, 100) } catch (ex: Exception) { @@ -364,4 +362,32 @@ class MainActivity : BaseServiceActivity() { } } } + private var updateCoverArt = object: Runnable { + override fun run() { + try { + val trackTitle = musicService!!.getCurrentTrack().title + + if (!(TrackTitle.text == trackTitle)) { + configureTrackDisplay() + } + + coverArtHandler!!.postDelayed(this, 100) + } + catch (ex: Exception) { + val exMsg = ex.message + } + } + } + private var updateLibrary = object: Runnable { + override fun run() { + try { + musicService!!.updateLibrary() + + updateLibraryHandler!!.postDelayed(this, 1000) + } + catch (ex: Exception) { + val exMsg = ex.message + } + } + } } diff --git a/app/src/main/java/com/example/mear/constants/SongSearch.kt b/app/src/main/java/com/example/mear/constants/SongSearch.kt index ecf9a46..35722e5 100644 --- a/app/src/main/java/com/example/mear/constants/SongSearch.kt +++ b/app/src/main/java/com/example/mear/constants/SongSearch.kt @@ -1,5 +1,5 @@ package com.example.mear.constants object SongSearch { - val INITIAL_SEARCH_AMOUNT = 40 + const val INITIAL_SEARCH_AMOUNT = 1 } \ No newline at end of file diff --git a/app/src/main/java/com/example/mear/management/MusicFiles.kt b/app/src/main/java/com/example/mear/management/MusicFiles.kt index a826377..1629369 100644 --- a/app/src/main/java/com/example/mear/management/MusicFiles.kt +++ b/app/src/main/java/com/example/mear/management/MusicFiles.kt @@ -5,6 +5,7 @@ import java.lang.Exception import com.example.mear.constants.DirectoryIgnore import com.example.mear.constants.FileTypes +import com.example.mear.constants.SongSearch class MusicFiles (private val demoPath: File) { @@ -46,6 +47,33 @@ class MusicFiles (private val demoPath: File) { } } + fun initialMp3Search() { + try { + var pathList: MutableList? + pathList = mutableListOf() + var songsAdded = 0 + + var fileSearch = File(demoPath.absolutePath) + fileSearch.walkTopDown().forEach { + println(it.absolutePath) + if (!ignoreThisDirectory(it.absolutePath)) { + if (it.isFile) { + if (it.extension == (FileTypes.Mp3)) { + if (songsAdded >= SongSearch.INITIAL_SEARCH_AMOUNT) { + return + } + pathList.add(it.absolutePath) + allSongs = pathList + songsAdded = songsAdded.inc() + } + } + } + } + } + catch (ex: Exception) { + val exMsg = ex.message + } + } fun searchForMp3Songs() { try { var pathList: MutableList? diff --git a/app/src/main/java/com/example/mear/management/TrackManager.kt b/app/src/main/java/com/example/mear/management/TrackManager.kt index eeb046a..9ed1fda 100644 --- a/app/src/main/java/com/example/mear/management/TrackManager.kt +++ b/app/src/main/java/com/example/mear/management/TrackManager.kt @@ -13,9 +13,10 @@ import com.example.mear.models.Track import com.example.mear.repositories.PlayCountRepository import com.example.mear.repositories.TrackRepository import com.example.mear.util.ConvertByteArray +import org.jetbrains.anko.custom.async import kotlin.Exception -class TrackManager(var allSongPath: MutableList) { +class TrackManager(var allSongPath: MutableList?) { private var allTracks: MutableList? = null private var ctx: Context? = null @@ -32,7 +33,7 @@ class TrackManager(var allSongPath: MutableList) { var id = 0 try { allTracks = mutableListOf() - for (musicPath in allSongPath) { + for (musicPath in allSongPath!!) { var mmr = MediaMetadataRetriever() mmr.setDataSource(musicPath) val trackTitle = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) @@ -61,6 +62,42 @@ class TrackManager(var allSongPath: MutableList) { TrackRepository(ctx).createSongCount(id) return id.dec() } + fun initializeLibrary() { + var initTrack = initialTracks() + addToDatabase(initTrack) + } + fun addSongs() { + var initTracks = initialTracks() + addToDatabase(initTracks) + + if (moreSongs) { + GlobalScope.launch { + val allSongCount = allSongPath!!.size -1 + for (i in songIndex!! .. (allSongCount)) { + val songPath = allSongPath!![i] + val track = configureTrack(songPath, i) + songCount = songCount!!.inc() + addToDatabase(track) + } + } + } + } + fun addnewSongs(trackPaths: List, resumeIndex: Int) { + var resumeIndex = resumeIndex + + try { + //launchB + for (tPath in trackPaths) { + val track = configureTrack(tPath, resumeIndex) + addToDatabase(track) + resumeIndex = resumeIndex.inc() + } + //} + } + catch (ex: Exception) { + val exMsg = ex.message + } + } fun addTracks() { var initTracks = initialTracks() addToDatabase(initTracks) @@ -84,7 +121,7 @@ class TrackManager(var allSongPath: MutableList) { } } fun addRemainingTracks() = runBlocking { - val remainder = allSongPath.size - songCount!! + val remainder = allSongPath!!.size - songCount!! if (remainder > 10) { val rangeAmount = remainder / 10 @@ -99,7 +136,7 @@ class TrackManager(var allSongPath: MutableList) { var ranges = mutableListOf() try { var rangeCounter = 0 - val songAmount = allSongPath.size + val songAmount = allSongPath!!.size while (songIndex!! < songAmount) { val startIndex = songIndex var endIndex = songIndex!! + rangeAmount @@ -125,13 +162,13 @@ class TrackManager(var allSongPath: MutableList) { try { var initSongSearch = SongSearch.INITIAL_SEARCH_AMOUNT -1 - if (allSongPath!!.size < SongSearch.INITIAL_SEARCH_AMOUNT) { - initSongSearch = allSongPath.size + 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) tracks.add(track) } @@ -148,8 +185,8 @@ class TrackManager(var allSongPath: MutableList) { private fun remainingTracks(): MutableList { val tracks = mutableListOf() try { - for (i in songIndex!! .. (allSongPath.size - 1)) { - val songPath = allSongPath[i] + 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) @@ -169,12 +206,12 @@ class TrackManager(var allSongPath: MutableList) { try { val startIndex = rangeobjects.startIndex var endIndex = rangeobjects.endIndex - if (endIndex == allSongPath.size) { + if (endIndex == allSongPath!!.size) { endIndex-- } for (songPathIndex in startIndex.. endIndex) { - val songPath = allSongPath[songPathIndex] + val songPath = allSongPath!![songPathIndex] val track = configureTrack(songPath, songPathIndex) if (track.id != Int.MAX_VALUE) { tracks.add(track) @@ -244,6 +281,16 @@ class TrackManager(var allSongPath: MutableList) { PlayCountRepository(ctx!!).insertPlayCounts(tracks) TrackRepository(ctx!!).createSongCount(songCount!!) } + private fun addToDatabase(track: Track) { + try { + TrackRepository(ctx!!).insertTrack(track) + PlayCountRepository(ctx!!).insertPlayCount(track) + //TrackRepository(ctx!!).createSongCount(songCount!!) + } + catch (ex: Exception) { + val exMsg = ex.message + } + } private fun addToDatabase(ctx: Context, tracks: List) { TrackRepository(ctx).insertTracks(tracks) PlayCountRepository(ctx).insertPlayCounts(tracks) diff --git a/app/src/main/java/com/example/mear/playback/service/MusicService.kt b/app/src/main/java/com/example/mear/playback/service/MusicService.kt index 32b3370..c3876e6 100644 --- a/app/src/main/java/com/example/mear/playback/service/MusicService.kt +++ b/app/src/main/java/com/example/mear/playback/service/MusicService.kt @@ -4,6 +4,7 @@ import android.app.Service import android.content.Intent import android.media.MediaPlayer import android.os.Binder +import android.os.Environment import android.os.IBinder import android.widget.Toast @@ -18,6 +19,8 @@ import com.example.mear.models.Track import com.example.mear.repositories.RepeatRepository import com.example.mear.repositories.ShuffleRepository import com.example.mear.repositories.TrackRepository +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch class MusicService: Service() { @@ -30,6 +33,7 @@ class MusicService: Service() { private var trackMgr: TrackManager? = null private var currentTrack = Track() private var currentSongIndex: Int? = null + private var addingMusic: Boolean? = false private var shuffleOn: Boolean? = null private var repeatOn: Boolean? = null private val mBinder = LocalBinder() @@ -257,6 +261,10 @@ class MusicService: Service() { } + fun updateLibrary() { + checkForMusicChange() + } + private fun initializeMediaPlayer() { try { if (trackPlayer == null) { @@ -266,7 +274,7 @@ class MusicService: Service() { populateTrackRepository() } - currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount()) + currentSongIndex = Random.nextInt(0, TrackRepository(this).getAll().count()) currentTrack = TrackRepository(this).getTrack(currentSongIndex!!) trackPlayer!!.setDataSource(currentTrack.songPath) trackPlayer!!.prepareAsync() @@ -279,16 +287,45 @@ class MusicService: Service() { } } private fun populateTrackRepository() { - var mp3Paths = MusicFiles(android.os.Environment.getExternalStorageDirectory()) - mp3Paths.searchForMp3Songs() + var mp3Paths = MusicFiles(Environment.getExternalStorageDirectory()) + mp3Paths.initialMp3Search() val paths = mp3Paths.allSongs + trackMgr = TrackManager(paths!!) trackMgr!!.initializeContext(this) - //trackMgr!!.addTracks() - trackMgr!!.addTracksKx() + trackMgr!!.initializeLibrary() + initializeShuffleMode() initializeRepeatMode() } + private fun checkForMusicChange() { + + if (addingMusic!!) { + return + } + addingMusic = true + val ctx = this + val mp3Paths = MusicFiles(Environment.getExternalStorageDirectory()) + GlobalScope.launch { + mp3Paths.searchForMp3Songs() + val paths = mp3Paths.allSongs + val allTracks = TrackRepository(ctx).getAll() + val trackCount = allTracks.count() + val tracksToDelete = musicToDelete(allTracks!!, paths!!) + val trackPathsToAdd = musicToAdd(allTracks!!, paths!!) + + if (tracksToDelete!!.any()) { + TrackRepository(ctx).deleteTracks(tracksToDelete!!) + } + if (trackPathsToAdd!!.any()) { + val trkMgr = TrackManager(null) + trkMgr.initializeContext(ctx) + trkMgr.addnewSongs(trackPathsToAdd!!, trackCount) + addingMusic = false + } + } + + } private fun initializeShuffleMode() { try { val shuffleMode = ShuffleRepository(this).getShuffleMode() @@ -299,9 +336,6 @@ class MusicService: Service() { ControlTypes.SHUFFLE_OFF -> { shuffleOn = false } - null -> { - shuffleOn = false - } } } catch (ex: Exception) { @@ -318,9 +352,6 @@ class MusicService: Service() { ControlTypes.REPEAT_OFF -> { repeatOn = false } - null -> { - repeatOn = false - } } } catch (ex: Exception) { @@ -328,6 +359,58 @@ class MusicService: Service() { } } + private fun musicToDelete(allTracks: List?, paths: MutableList): List? { + try { + var missingTracks = mutableListOf() + allTracks!!.iterator().forEach { + val songExists = paths.contains(it.songPath) + if (!songExists) { + missingTracks.add(it) + } + } + + return missingTracks + } + catch (ex: Exception) { + val exMsg = ex.message + } + + return null + } + private fun musicToAdd(allTracks: List?, paths: MutableList): List? { + try { + var newTracks = mutableListOf() + + val trackPaths = retrieveTrackPaths(allTracks) + paths.iterator().forEach { + val songExists = trackPaths!!.contains(it) + if (!songExists) { + newTracks.add(it) + } + } + + return newTracks + } + catch (ex: Exception) { + val exMsg = ex.message + } + + return null + } + private fun retrieveTrackPaths(allTracks: List?): List? { + try { + val trackPaths = mutableListOf() + for (i in allTracks!!) { + trackPaths.add(i.songPath) + } + return trackPaths + } + catch (ex: Exception) { + val exMsg = ex.message + } + + return null + } private fun retrieveShuffleMode(): Boolean? { val shuffleMode = ShuffleRepository(this).getShuffleMode() @@ -338,9 +421,6 @@ class MusicService: Service() { ControlTypes.SHUFFLE_OFF -> { return false } - null -> { - return null - } else -> { return false } @@ -355,9 +435,6 @@ class MusicService: Service() { ControlTypes.REPEAT_OFF -> { return false } - null -> { - return null - } else -> { return false } @@ -377,9 +454,7 @@ class MusicService: Service() { private fun retrieveSongCount(): Int? { try { - var count = TrackRepository(this).getSongCount() - - return count + return TrackRepository(this).getAll().count() } catch (ex: Exception) { val exMsg = ex.message diff --git a/app/src/main/java/com/example/mear/repositories/TrackRepository.kt b/app/src/main/java/com/example/mear/repositories/TrackRepository.kt index bbf7656..24d2d06 100644 --- a/app/src/main/java/com/example/mear/repositories/TrackRepository.kt +++ b/app/src/main/java/com/example/mear/repositories/TrackRepository.kt @@ -94,6 +94,20 @@ class TrackRepository { fun delete() = context!!.database.use { delete("Track") } + fun deleteTracks(tracks: List) = context!!.database.use { + tracks.iterator().forEach { + transaction { + delete("Track", "id = {track_id}", "track_id" to it.id) + } + } + } + fun deleteTracksByPaths(trackPaths: List) = context!!.database.use { + trackPaths.iterator().forEach { + transaction { + delete("Track", "FilePath = {file_path}", "file_path" to it) + } + } + } fun getLibraryCount(): Int? { context!!.database.use {