This commit is contained in:
amazing-username
2019-04-20 14:02:37 -04:00
parent 95ad867743
commit ab1ed63fb0
6 changed files with 228 additions and 38 deletions
@@ -38,7 +38,9 @@ import com.example.mear.util.ExtractCover
class MainActivity : BaseServiceActivity() { class MainActivity : BaseServiceActivity() {
private var coverArtHandler: Handler? = Handler()
private var musicHandler: Handler? = Handler() private var musicHandler: Handler? = Handler()
private var updateLibraryHandler: Handler? = Handler()
private var serviceBinded: Boolean? = false private var serviceBinded: Boolean? = false
private var repeatOn: Boolean? = false private var repeatOn: Boolean? = false
private var shuffleOn: Boolean? = false private var shuffleOn: Boolean? = false
@@ -288,6 +290,8 @@ class MainActivity : BaseServiceActivity() {
} }
override fun updateTrackProgress() { override fun updateTrackProgress() {
musicHandler!!.postDelayed(musicTrackTimeUpdateTask, 100) musicHandler!!.postDelayed(musicTrackTimeUpdateTask, 100)
coverArtHandler!!.postDelayed(updateCoverArt, 100)
updateLibraryHandler!!.postDelayed(updateLibrary, 1000)
} }
private fun configurePlayControlsDisplay() { private fun configurePlayControlsDisplay() {
PlayTrack.background = null PlayTrack.background = null
@@ -351,12 +355,6 @@ class MainActivity : BaseServiceActivity() {
CurrentPosition.text = dur CurrentPosition.text = dur
val trackTitle = musicService!!.getCurrentTrack().title
if (!(TrackTitle.text == trackTitle)) {
configureTrackDisplay()
}
musicHandler!!.postDelayed(this, 100) musicHandler!!.postDelayed(this, 100)
} }
catch (ex: Exception) { 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
}
}
}
} }
@@ -1,5 +1,5 @@
package com.example.mear.constants package com.example.mear.constants
object SongSearch { object SongSearch {
val INITIAL_SEARCH_AMOUNT = 40 const val INITIAL_SEARCH_AMOUNT = 1
} }
@@ -5,6 +5,7 @@ import java.lang.Exception
import com.example.mear.constants.DirectoryIgnore import com.example.mear.constants.DirectoryIgnore
import com.example.mear.constants.FileTypes import com.example.mear.constants.FileTypes
import com.example.mear.constants.SongSearch
class MusicFiles (private val demoPath: File) { class MusicFiles (private val demoPath: File) {
@@ -46,6 +47,33 @@ class MusicFiles (private val demoPath: File) {
} }
} }
fun initialMp3Search() {
try {
var pathList: MutableList<String>?
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() { fun searchForMp3Songs() {
try { try {
var pathList: MutableList<String>? var pathList: MutableList<String>?
@@ -13,9 +13,10 @@ import com.example.mear.models.Track
import com.example.mear.repositories.PlayCountRepository import com.example.mear.repositories.PlayCountRepository
import com.example.mear.repositories.TrackRepository import com.example.mear.repositories.TrackRepository
import com.example.mear.util.ConvertByteArray import com.example.mear.util.ConvertByteArray
import org.jetbrains.anko.custom.async
import kotlin.Exception import kotlin.Exception
class TrackManager(var allSongPath: MutableList<String>) { class TrackManager(var allSongPath: MutableList<String>?) {
private var allTracks: MutableList<Track>? = null private var allTracks: MutableList<Track>? = null
private var ctx: Context? = null private var ctx: Context? = null
@@ -32,7 +33,7 @@ class TrackManager(var allSongPath: MutableList<String>) {
var id = 0 var id = 0
try { try {
allTracks = mutableListOf() allTracks = mutableListOf()
for (musicPath in allSongPath) { for (musicPath in allSongPath!!) {
var mmr = MediaMetadataRetriever() var mmr = MediaMetadataRetriever()
mmr.setDataSource(musicPath) mmr.setDataSource(musicPath)
val trackTitle = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) val trackTitle = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
@@ -61,6 +62,42 @@ class TrackManager(var allSongPath: MutableList<String>) {
TrackRepository(ctx).createSongCount(id) TrackRepository(ctx).createSongCount(id)
return id.dec() 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<String>, 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() { fun addTracks() {
var initTracks = initialTracks() var initTracks = initialTracks()
addToDatabase(initTracks) addToDatabase(initTracks)
@@ -84,7 +121,7 @@ class TrackManager(var allSongPath: MutableList<String>) {
} }
} }
fun addRemainingTracks() = runBlocking { fun addRemainingTracks() = runBlocking {
val remainder = allSongPath.size - songCount!! val remainder = allSongPath!!.size - songCount!!
if (remainder > 10) { if (remainder > 10) {
val rangeAmount = remainder / 10 val rangeAmount = remainder / 10
@@ -99,7 +136,7 @@ class TrackManager(var allSongPath: MutableList<String>) {
var ranges = mutableListOf<AddMusicRange>() var ranges = mutableListOf<AddMusicRange>()
try { try {
var rangeCounter = 0 var rangeCounter = 0
val songAmount = allSongPath.size val songAmount = allSongPath!!.size
while (songIndex!! < songAmount) { while (songIndex!! < songAmount) {
val startIndex = songIndex val startIndex = songIndex
var endIndex = songIndex!! + rangeAmount var endIndex = songIndex!! + rangeAmount
@@ -125,13 +162,13 @@ class TrackManager(var allSongPath: MutableList<String>) {
try { try {
var initSongSearch = SongSearch.INITIAL_SEARCH_AMOUNT -1 var initSongSearch = SongSearch.INITIAL_SEARCH_AMOUNT -1
if (allSongPath!!.size < SongSearch.INITIAL_SEARCH_AMOUNT) { if (allSongPath!!!!.size < SongSearch.INITIAL_SEARCH_AMOUNT) {
initSongSearch = allSongPath.size initSongSearch = allSongPath!!.size
moreSongs = false moreSongs = false
} }
for (i in 0.. initSongSearch) { 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)
} }
@@ -148,8 +185,8 @@ class TrackManager(var allSongPath: MutableList<String>) {
private fun remainingTracks(): MutableList<Track> { private fun remainingTracks(): MutableList<Track> {
val tracks = mutableListOf<Track>() val tracks = mutableListOf<Track>()
try { try {
for (i in songIndex!! .. (allSongPath.size - 1)) { for (i in songIndex!! .. (allSongPath!!.size - 1)) {
val songPath = allSongPath[i] val songPath = allSongPath!![i]
val track = configureTrack(songPath, i) val track = configureTrack(songPath, i)
if (track.id != Int.MAX_VALUE) { if (track.id != Int.MAX_VALUE) {
tracks.add(track) tracks.add(track)
@@ -169,12 +206,12 @@ class TrackManager(var allSongPath: MutableList<String>) {
try { try {
val startIndex = rangeobjects.startIndex val startIndex = rangeobjects.startIndex
var endIndex = rangeobjects.endIndex var endIndex = rangeobjects.endIndex
if (endIndex == allSongPath.size) { if (endIndex == allSongPath!!.size) {
endIndex-- endIndex--
} }
for (songPathIndex in startIndex.. endIndex) { for (songPathIndex in startIndex.. endIndex) {
val songPath = allSongPath[songPathIndex] val songPath = allSongPath!![songPathIndex]
val track = configureTrack(songPath, songPathIndex) val track = configureTrack(songPath, songPathIndex)
if (track.id != Int.MAX_VALUE) { if (track.id != Int.MAX_VALUE) {
tracks.add(track) tracks.add(track)
@@ -244,6 +281,16 @@ class TrackManager(var allSongPath: MutableList<String>) {
PlayCountRepository(ctx!!).insertPlayCounts(tracks) PlayCountRepository(ctx!!).insertPlayCounts(tracks)
TrackRepository(ctx!!).createSongCount(songCount!!) 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<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)
@@ -4,6 +4,7 @@ import android.app.Service
import android.content.Intent import android.content.Intent
import android.media.MediaPlayer import android.media.MediaPlayer
import android.os.Binder import android.os.Binder
import android.os.Environment
import android.os.IBinder import android.os.IBinder
import android.widget.Toast 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.RepeatRepository
import com.example.mear.repositories.ShuffleRepository import com.example.mear.repositories.ShuffleRepository
import com.example.mear.repositories.TrackRepository import com.example.mear.repositories.TrackRepository
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MusicService: Service() { class MusicService: Service() {
@@ -30,6 +33,7 @@ class MusicService: Service() {
private var trackMgr: TrackManager? = null private var trackMgr: TrackManager? = null
private var currentTrack = Track() private var currentTrack = Track()
private var currentSongIndex: Int? = null private var currentSongIndex: Int? = null
private var addingMusic: Boolean? = false
private var shuffleOn: Boolean? = null private var shuffleOn: Boolean? = null
private var repeatOn: Boolean? = null private var repeatOn: Boolean? = null
private val mBinder = LocalBinder() private val mBinder = LocalBinder()
@@ -257,6 +261,10 @@ class MusicService: Service() {
} }
fun updateLibrary() {
checkForMusicChange()
}
private fun initializeMediaPlayer() { private fun initializeMediaPlayer() {
try { try {
if (trackPlayer == null) { if (trackPlayer == null) {
@@ -266,7 +274,7 @@ class MusicService: Service() {
populateTrackRepository() populateTrackRepository()
} }
currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount()) currentSongIndex = Random.nextInt(0, TrackRepository(this).getAll().count())
currentTrack = TrackRepository(this).getTrack(currentSongIndex!!) currentTrack = TrackRepository(this).getTrack(currentSongIndex!!)
trackPlayer!!.setDataSource(currentTrack.songPath) trackPlayer!!.setDataSource(currentTrack.songPath)
trackPlayer!!.prepareAsync() trackPlayer!!.prepareAsync()
@@ -279,16 +287,45 @@ class MusicService: Service() {
} }
} }
private fun populateTrackRepository() { private fun populateTrackRepository() {
var mp3Paths = MusicFiles(android.os.Environment.getExternalStorageDirectory()) var mp3Paths = MusicFiles(Environment.getExternalStorageDirectory())
mp3Paths.searchForMp3Songs() mp3Paths.initialMp3Search()
val paths = mp3Paths.allSongs val paths = mp3Paths.allSongs
trackMgr = TrackManager(paths!!) trackMgr = TrackManager(paths!!)
trackMgr!!.initializeContext(this) trackMgr!!.initializeContext(this)
//trackMgr!!.addTracks() trackMgr!!.initializeLibrary()
trackMgr!!.addTracksKx()
initializeShuffleMode() initializeShuffleMode()
initializeRepeatMode() 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() { private fun initializeShuffleMode() {
try { try {
val shuffleMode = ShuffleRepository(this).getShuffleMode() val shuffleMode = ShuffleRepository(this).getShuffleMode()
@@ -299,9 +336,6 @@ class MusicService: Service() {
ControlTypes.SHUFFLE_OFF -> { ControlTypes.SHUFFLE_OFF -> {
shuffleOn = false shuffleOn = false
} }
null -> {
shuffleOn = false
}
} }
} }
catch (ex: Exception) { catch (ex: Exception) {
@@ -318,9 +352,6 @@ class MusicService: Service() {
ControlTypes.REPEAT_OFF -> { ControlTypes.REPEAT_OFF -> {
repeatOn = false repeatOn = false
} }
null -> {
repeatOn = false
}
} }
} }
catch (ex: Exception) { catch (ex: Exception) {
@@ -328,6 +359,58 @@ class MusicService: Service() {
} }
} }
private fun musicToDelete(allTracks: List<Track>?, paths: MutableList<String>): List<Track>? {
try {
var missingTracks = mutableListOf<Track>()
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<Track>?, paths: MutableList<String>): List<String>? {
try {
var newTracks = mutableListOf<String>()
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<Track>?): List<String>? {
try {
val trackPaths = mutableListOf<String>()
for (i in allTracks!!) {
trackPaths.add(i.songPath)
}
return trackPaths
}
catch (ex: Exception) {
val exMsg = ex.message
}
return null
}
private fun retrieveShuffleMode(): Boolean? { private fun retrieveShuffleMode(): Boolean? {
val shuffleMode = ShuffleRepository(this).getShuffleMode() val shuffleMode = ShuffleRepository(this).getShuffleMode()
@@ -338,9 +421,6 @@ class MusicService: Service() {
ControlTypes.SHUFFLE_OFF -> { ControlTypes.SHUFFLE_OFF -> {
return false return false
} }
null -> {
return null
}
else -> { else -> {
return false return false
} }
@@ -355,9 +435,6 @@ class MusicService: Service() {
ControlTypes.REPEAT_OFF -> { ControlTypes.REPEAT_OFF -> {
return false return false
} }
null -> {
return null
}
else -> { else -> {
return false return false
} }
@@ -377,9 +454,7 @@ class MusicService: Service() {
private fun retrieveSongCount(): Int? { private fun retrieveSongCount(): Int? {
try { try {
var count = TrackRepository(this).getSongCount() return TrackRepository(this).getAll().count()
return count
} }
catch (ex: Exception) { catch (ex: Exception) {
val exMsg = ex.message val exMsg = ex.message
@@ -94,6 +94,20 @@ class TrackRepository {
fun delete() = context!!.database.use { fun delete() = context!!.database.use {
delete("Track") delete("Track")
} }
fun deleteTracks(tracks: List<Track>) = context!!.database.use {
tracks.iterator().forEach {
transaction {
delete("Track", "id = {track_id}", "track_id" to it.id)
}
}
}
fun deleteTracksByPaths(trackPaths: List<String>) = context!!.database.use {
trackPaths.iterator().forEach {
transaction {
delete("Track", "FilePath = {file_path}", "file_path" to it)
}
}
}
fun getLibraryCount(): Int? { fun getLibraryCount(): Int? {
context!!.database.use { context!!.database.use {