Implemented Database #16 and resolved the issue of track cover not displaying #17

This commit is contained in:
amazing-username
2019-03-03 14:53:28 -05:00
parent bc24149e73
commit 10a898cfe6
10 changed files with 214 additions and 108 deletions
@@ -1,28 +1,22 @@
package com.example.mear package com.example.mear
import android.content.Context import android.graphics.Bitmap
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteQuery
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.media.MediaPlayer import android.media.MediaPlayer
import android.media.MediaMetadataRetriever
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity
import java.lang.Exception import java.lang.Exception
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.* import kotlinx.android.synthetic.main.content_main.*
import kotlinx.coroutines.selects.select
import kotlin.io.* import kotlin.io.*
import kotlin.random.Random import kotlin.random.Random
import org.jetbrains.anko.db.*
import com.example.mear.management.TrackRepository
import com.example.mear.management.DatabaseManager
import com.example.mear.management.MusicFiles import com.example.mear.management.MusicFiles
import com.example.mear.management.TrackManager import com.example.mear.management.TrackManager
import com.example.mear.models.Track import com.example.mear.repositories.TrackRepository
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@@ -31,10 +25,21 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
loadTracks(loadSongPaths()) //loadTracks(loadSongPaths())
initialize()
}
private fun initialize() {
songCount = TrackRepository(this).getSongCount()
currentSong = fetchSongIndex(PlayTypes.PlaySong)
initializeMediaPlayer() initializeMediaPlayer()
initializeClickListeners()
initializeCompletionListener()
}
private fun initializeClickListeners() {
PlayTrack.setOnClickListener { PlayTrack.setOnClickListener {
playSongTrack() playSongTrack()
} }
@@ -44,73 +49,78 @@ class MainActivity : AppCompatActivity() {
PreviousTrack.setOnClickListener { PreviousTrack.setOnClickListener {
playPreviousSongTrack() playPreviousSongTrack()
} }
TrackPayer!!.setOnCompletionListener { }
private fun initializeCompletionListener() {
trackPlayer!!.setOnCompletionListener {
playNextSongTrack() playNextSongTrack()
} }
} }
private fun initializeMediaPlayer() { private fun initializeMediaPlayer() {
if (TrackPayer == null) { if (trackPlayer == null) {
TrackPayer = MediaPlayer() trackPlayer = MediaPlayer()
playerInitialized = true playerInitialized = true
val tr = TrackRepository(this).getTrack(currentSong!!) val tr = TrackRepository(this).getTrack(currentSong!!)
TrackPayer!!.setDataSource(tr.songPath) trackPlayer!!.setDataSource(tr.songPath)
TrackPayer!!.prepare() trackPlayer!!.prepare()
} }
} }
private fun playSongTrack() { private fun playSongTrack() {
PlayTrack.isEnabled = true
try { try {
if (!TrackPayer!!.isPlaying) { if (!trackPlayer!!.isPlaying) {
TrackPayer!!.start() trackPlayer!!.start()
configureTrackDisplay() configureTrackDisplay()
} else { } else {
TrackPayer!!.pause() trackPlayer!!.pause()
} }
} }
catch (ex: Exception) { catch (ex: Exception) {
val exMsg = ex.message val exMsg = ex.message
} }
PlayTrack.isEnabled = true
} }
private fun playNextSongTrack() { private fun playNextSongTrack() {
NextTrack.isEnabled = false
try { try {
currentSong = fetchSongIndex(PlayTypes.PlayNextSong) currentSong = fetchSongIndex(PlayTypes.PlayNextSong)
if (TrackPayer!!.isPlaying) { if (trackPlayer!!.isPlaying) {
TrackPayer!!.stop() trackPlayer!!.stop()
} }
TrackPayer!!.reset() trackPlayer!!.reset()
TrackPayer!!.setDataSource(TrackRepository(this).getTrack(currentSong!!).songPath) trackPlayer!!.setDataSource(TrackRepository(this).getTrack(currentSong!!).songPath)
TrackPayer!!.prepare() trackPlayer!!.prepare()
TrackPayer!!.start() trackPlayer!!.start()
configureTrackDisplay() configureTrackDisplay()
} }
catch (ex: Exception) { catch (ex: Exception) {
val exMsg = ex.message val exMsg = ex.message
print(exMsg) print(exMsg)
} }
NextTrack.isEnabled = true
} }
private fun playPreviousSongTrack() { private fun playPreviousSongTrack() {
PreviousTrack.isEnabled = false
try { try {
currentSong = fetchSongIndex(PlayTypes.PlayPreviousSong) currentSong = fetchSongIndex(PlayTypes.PlayPreviousSong)
if (TrackPayer!!.isPlaying) { if (trackPlayer!!.isPlaying) {
TrackPayer!!.stop() trackPlayer!!.stop()
} }
TrackPayer!!.reset() trackPlayer!!.reset()
TrackPayer!!.setDataSource(TrackRepository(this).getTrack(currentSong!!).songPath) trackPlayer!!.setDataSource(TrackRepository(this).getTrack(currentSong!!).songPath)
TrackPayer!!.prepare() trackPlayer!!.prepare()
TrackPayer!!.start() trackPlayer!!.start()
configureTrackDisplay() configureTrackDisplay()
} }
catch (ex: Exception) { catch (ex: Exception) {
val exMsg = ex.message val exMsg = ex.message
print(exMsg) print(exMsg)
} }
PreviousTrack.isEnabled = true
} }
private fun configureTrackDisplay() { private fun configureTrackDisplay() {
val currTrack = TrackRepository(this).getTrack(currentSong!!) val currTrack = TrackRepository(this).getTrack(currentSong!!)
@@ -118,8 +128,11 @@ class MainActivity : AppCompatActivity() {
val albumTitle = currTrack.album val albumTitle = currTrack.album
var trackCover: ByteArray? = null var trackCover: ByteArray? = null
if (!(currTrack.TrackCover == null)) { var mmr = MediaMetadataRetriever()
trackCover = currTrack.TrackCover mmr.setDataSource(currTrack.songPath)
if (mmr.embeddedPicture != null) {
trackCover = mmr.embeddedPicture
} }
TrackTitle.text.clear() TrackTitle.text.clear()
@@ -129,8 +142,8 @@ class MainActivity : AppCompatActivity() {
TrackTitle.setText(trackTitle) TrackTitle.setText(trackTitle)
AlbumTitle.setText(albumTitle) AlbumTitle.setText(albumTitle)
if (trackCover != null) { if (trackCover != null) {
var songImage = BitmapFactory val songImage = BitmapFactory
.decodeByteArray(trackCover, 0, trackCover!!.size) .decodeByteArray(trackCover, 0, trackCover.size)
TrackCover.setImageBitmap(songImage) TrackCover.setImageBitmap(songImage)
} }
} }
@@ -141,9 +154,8 @@ class MainActivity : AppCompatActivity() {
try { try {
when (playType) { when (playType) {
PlayTypes.PlayPreviousSong -> { PlayTypes.PlayPreviousSong -> {
if (currentSong!! == 0) {
songIndex = songCount songIndex = songCount
} else { if (currentSong!! != 0) {
songIndex = currentSong!!.dec() songIndex = currentSong!!.dec()
} }
} }
@@ -151,9 +163,8 @@ class MainActivity : AppCompatActivity() {
songIndex = Random.nextInt(0, songCount!!) songIndex = Random.nextInt(0, songCount!!)
} }
PlayTypes.PlayNextSong -> { PlayTypes.PlayNextSong -> {
if (currentSong!! == songCount!!) {
songIndex = 0 songIndex = 0
} else { if (currentSong!! != songCount!!) {
songIndex = currentSong!!.inc() songIndex = currentSong!!.inc()
} }
} }
@@ -177,22 +188,9 @@ class MainActivity : AppCompatActivity() {
} }
private fun loadTracks(allSongs: MutableList<String>) { private fun loadTracks(allSongs: MutableList<String>) {
try { try {
val trackMgr = TrackManager(allSongs)
songCount = trackMgr.configureTracks(this)
//var trackMgr = TrackManager(allSongs!!)
//trackMgr.deleteTable(this)
//songCount = trackMgr.configureTracks(this)
//songCount = trackMgr.configureTracks(this)
//TrackRepository(this).createSongCount(songCount!!)
//var sC = TrackRepository(this).getSongCount()
//trackMgr.dumpToDatabase(this)
//trackMgr.dumpToDatabase()
//val allTracks = trackMgr.allTracks
//databaseInit(allTracks!!)
//databaseInit(trackMgr.allTracks!!)
//trackMgr = TrackManager( mutableListOf())
//val obk = TrackRepository(this).getAll()
//TrackRepository(this).songCount = TrackRepository(this).getAll().size
songCount = TrackRepository(this).getSongCount() songCount = TrackRepository(this).getSongCount()
currentSong = fetchSongIndex(PlayTypes.PlaySong) currentSong = fetchSongIndex(PlayTypes.PlaySong)
@@ -202,15 +200,8 @@ class MainActivity : AppCompatActivity() {
} }
} }
private fun databaseInit(allTracks: MutableList<Track>) {
TrackRepository(this).delete() private var trackPlayer: MediaPlayer? = null
for (songData in allTracks) {
TrackRepository(this).create(songData)
}
}
private var TrackPayer: MediaPlayer? = null
private var currentSong: Int? = null private var currentSong: Int? = null
private var playerInitialized: Boolean? = null private var playerInitialized: Boolean? = null
private var songCount: Int? = null private var songCount: Int? = null
@@ -5,6 +5,7 @@ import android.database.sqlite.SQLiteDatabase
import org.jetbrains.anko.db.* import org.jetbrains.anko.db.*
import org.jetbrains.anko.db.ManagedSQLiteOpenHelper import org.jetbrains.anko.db.ManagedSQLiteOpenHelper
import java.lang.Exception
class DatabaseManager(ctx: Context): ManagedSQLiteOpenHelper(ctx, "Mear", class DatabaseManager(ctx: Context): ManagedSQLiteOpenHelper(ctx, "Mear",
null, 1) { null, 1) {
@@ -22,24 +23,45 @@ class DatabaseManager(ctx: Context): ManagedSQLiteOpenHelper(ctx, "Mear",
override fun onCreate(db: SQLiteDatabase?) { override fun onCreate(db: SQLiteDatabase?) {
//db!!.dropTable("Track") try {
db!!.createTable("Track", true, db!!.createTable(
"Track", true,
"Id" to INTEGER + PRIMARY_KEY + UNIQUE, "Id" to INTEGER + PRIMARY_KEY + UNIQUE,
"Title" to TEXT, "Album" to TEXT, "Artist" to TEXT, "Title" to TEXT, "Album" to TEXT, "Artist" to TEXT,
"Cover" to BLOB, "Duration" to INTEGER, "Cover" to BLOB, "Duration" to INTEGER,
"FilePath" to TEXT) "FilePath" to TEXT
db!!.createTable("TrackCount", true, )
db!!.createTable(
"TrackCount", true,
"Id" to INTEGER + PRIMARY_KEY + UNIQUE, "Id" to INTEGER + PRIMARY_KEY + UNIQUE,
"TotalSongs" to INTEGER) "TotalSongs" to INTEGER
)
db!!.createTable(
"PlayCount", true,
"Id" to INTEGER + PRIMARY_KEY + AUTOINCREMENT,
"PlayCount" to INTEGER,
"TrackId" to INTEGER
)
db!!.createTable(
"Settings", true,
"Id" to INTEGER + PRIMARY_KEY + UNIQUE,
"DarkTheme" to org.jetbrains.anko.db.REAL
)
}
catch (ex: Exception) {
}
} }
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
try {
db!!.dropTable("Track") db!!.dropTable("Track")
db!!.dropTable("TrackCount") db!!.dropTable("TrackCount")
db!!.dropTable("PlayCount")
db!!.dropTable("Settings")
}
catch (ex: Exception) {
} }
private fun createSettingsTable() {
} }
} }
@@ -34,7 +34,6 @@ class MusicFiles (private val demoPath: File) {
} }
} }
} }
songCount = count
} }
catch (ex: Exception) { catch (ex: Exception) {
var exMsg = ex.message var exMsg = ex.message
@@ -43,6 +42,5 @@ class MusicFiles (private val demoPath: File) {
var allSongs: MutableList<String>?= null var allSongs: MutableList<String>?= null
var songCount: Int? = null
val musicSongLimit = Int.MAX_VALUE val musicSongLimit = Int.MAX_VALUE
} }
@@ -1,12 +1,13 @@
package com.example.mear.management package com.example.mear.management
import android.content.Context import android.content.Context
import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import java.lang.Exception import java.lang.Exception
import com.example.mear.models.Track import com.example.mear.models.Track
import com.example.mear.repositories.PlayCountRepository
import com.example.mear.repositories.TrackRepository
class TrackManager(var allSongPath: MutableList<String>) { class TrackManager(var allSongPath: MutableList<String>) {
@@ -37,7 +38,7 @@ class TrackManager(var allSongPath: MutableList<String>) {
println("dd") println("dd")
} }
var track = Track(id, trackTitle, trackArtist, trackAlbum, trackLength, val track = Track(id, trackTitle, trackArtist, trackAlbum, trackLength,
art!!, musicPath) art!!, musicPath)
dumpToDatabase(ctx, track) dumpToDatabase(ctx, track)
id++ id++
@@ -52,7 +53,7 @@ class TrackManager(var allSongPath: MutableList<String>) {
fun dumpToDatabase(ctx: Context) { fun dumpToDatabase(ctx: Context) {
TrackRepository(ctx).delete() TrackRepository(ctx).delete()
for (songData in allTracks!!) { for (songData in allTracks!!) {
TrackRepository(ctx).create(songData) TrackRepository(ctx).insertTrack(songData)
allTracks!!.removeAt(songData.id ) allTracks!!.removeAt(songData.id )
} }
} }
@@ -60,7 +61,8 @@ class TrackManager(var allSongPath: MutableList<String>) {
TrackRepository(ctx).delete() TrackRepository(ctx).delete()
} }
private fun dumpToDatabase(ctx: Context, track: Track) { private fun dumpToDatabase(ctx: Context, track: Track) {
TrackRepository(ctx).create(track) TrackRepository(ctx).insertTrack(track)
PlayCountRepository(ctx).insertPlayCount(track)
} }
var allTracks: MutableList<Track>? = null var allTracks: MutableList<Track>? = null
@@ -0,0 +1,4 @@
package com.example.mear.models
data class PlayCount(val id: Int, val playCount: Int, val trackId: Int) {
}
@@ -0,0 +1,4 @@
package com.example.mear.models
data class Settings(val id: Int, val darkTheme: Boolean) {
}
@@ -2,14 +2,4 @@ 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, val title: String, val artist: String, val album: String,
val length: Int, val TrackCover: ByteArray, val songPath: String) { val length: Int, val TrackCover: ByteArray, val songPath: String) {
companion object {
//val Track.COLUMN_ID = "id"
val TABLE_NAME = "Track"
val COLUMN_TITLE = "Title"
val COLUMN_ARTIST = "Artist"
val COLUMN_ALBUM = "Album"
val COLUMN_DURATION = "Duration"
val COLUMN_COVER = "Cover"
val COLUMN_SONGPATH = "SongPath"
}
} }
@@ -0,0 +1,62 @@
package com.example.mear.repositories
import android.content.Context
import org.jetbrains.anko.db.*
import com.example.mear.database
import com.example.mear.models.PlayCount
import com.example.mear.models.Track
class PlayCountRepository(val context: Context) {
fun getAll(): List<PlayCount> = context.database.use {
val playCounts = mutableListOf<PlayCount>()
select("PlayCount" )
.parseList(object : MapRowParser<PlayCount>{
override fun parseRow(columns: Map<String, Any?>): PlayCount {
val id = columns.getValue("Id").toString().toInt()
val songPlayedAmount = columns.getValue("PlayCount").toString().toInt()
val trackId = columns.getValue("TrackId").toString().toInt()
val playCount = PlayCount(id, songPlayedAmount, trackId)
playCounts.add(playCount)
return playCount
}
})
playCounts
}
fun getPlayCount(id: Int): PlayCount = context.database.use {
select("PlayCount").where("Id = $id")
.parseSingle(object: MapRowParser<PlayCount>{
override fun parseRow(columns: Map<String, Any?>): PlayCount {
val id = columns.getValue("Id").toString().toInt()
val songPlayedAmount = columns.getValue("PlayCount").toString().toInt()
val trackId = columns.getValue("TrackId").toString().toInt()
val playCount = PlayCount(id, songPlayedAmount, trackId)
return playCount
}
})
}
fun insertPlayCount(track: Track) = context.database.use {
insert("PlayCount",
"Id" to track.id,
"PlayCount" to 0,
"TrackId" to track.id)
}
fun updatePlayCount(playCount: PlayCount) = context.database.use {
update("PlayCount",
"PlayCount" to playCount.playCount + 1)
.where("Id = {playCountId}", "playCountId" to playCount.id).exec()
}
fun delete(table: PlayCount?) = context.database.use {
delete("PlayCount", whereClause = "id = {$table.id}")
}
fun delete() = context.database.use {
delete("PlayCount")
}
}
@@ -0,0 +1,41 @@
package com.example.mear.repositories
import android.content.Context
import org.jetbrains.anko.db.*
import com.example.mear.database
import com.example.mear.models.Settings
class SettingRepository(val context: Context) {
fun getSettings(id: Int): Settings = context.database.use {
select("Settings").where("Id = $id")
.parseSingle(object: MapRowParser<Settings>{
override fun parseRow(columns: Map<String, Any?>): Settings {
val id = columns.getValue("Id").toString().toInt()
val darkTheme = columns.getValue("DarkTheme").toString().toBoolean()
val settings = Settings (id, darkTheme)
return settings
}
})
}
fun insertSettings(settings: Settings) = context.database.use {
insert("Settings",
"Id" to settings.id,
"DarkTheme" to false)
}
fun updateSettings(settings: Settings) = context.database.use {
update("Settings",
"DarkTheme" to settings.darkTheme)
.where("Id = {settingId}", "settingId" to settings.id).exec()
}
fun delete(table: Settings?) = context.database.use {
delete("Settings", whereClause = "id = {$table.id}")
}
fun delete() = context.database.use {
delete("Settings")
}
}
@@ -1,4 +1,4 @@
package com.example.mear.management package com.example.mear.repositories
import android.content.Context import android.content.Context
@@ -30,7 +30,6 @@ class TrackRepository(val context: Context) {
return track return track
} }
}) })
sonC = tracks.count()
tracks tracks
} }
fun getTrack(id: Int): Track = context.database.use { fun getTrack(id: Int): Track = context.database.use {
@@ -62,7 +61,7 @@ class TrackRepository(val context: Context) {
}) })
} }
fun create(track: Track) = context.database.use { fun insertTrack(track: Track) = context.database.use {
insert("Track", insert("Track",
"Id" to track.id, "Id" to track.id,
"Title" to track.title, "Title" to track.title,
@@ -78,17 +77,10 @@ class TrackRepository(val context: Context) {
"TotalSongs" to songCount) "TotalSongs" to songCount)
} }
fun delete(track: Track) = context.database.use { fun delete(table: Any?) = context.database.use {
delete("Track", whereClause = "id = {$track.id}") delete("Track", whereClause = "id = {$table.id}")
} }
fun delete() = context.database.use { fun delete() = context.database.use {
delete("Track") delete("Track")
} }
var songCount: Int? = null
companion object {
var sonC: Int = 0
}
} }