Abstracted the MediaPlayer from the MainActivity and turned it into a service that has the ability to run regardless if an acitivity is present #28. Resolved issue where track display details was blank after switching from the settings view #26

This commit is contained in:
amazing-username
2019-03-10 00:43:03 -05:00
committed by amazing-username
parent 971da4b9d2
commit 040544e630
10 changed files with 452 additions and 147 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">
+3 -4
View File
@@ -15,15 +15,12 @@
android:name=".activities.SettingsActivity" android:name=".activities.SettingsActivity"
android:label="@string/title_activity_settings" android:label="@string/title_activity_settings"
android:parentActivityName=".activities.MainActivity" android:parentActivityName=".activities.MainActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.mear.activities.MainActivity" /> android:value="com.example.mear.activities.MainActivity" />
</activity> </activity>
<activity
android:name=".activities.fdh"
android:label="@string/title_activity_settings"
android:screenOrientation="portrait"></activity>
<activity <activity
android:name=".activities.MainActivity" android:name=".activities.MainActivity"
android:label="@string/title_activity_main" android:label="@string/title_activity_main"
@@ -35,6 +32,8 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<service android:name=".playback.service.MusicService" />
</application> </application>
</manifest> </manifest>
@@ -1,50 +1,91 @@
package com.example.mear.activities package com.example.mear.activities
import android.graphics.Color import android.app.ActivityManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.media.MediaPlayer import android.graphics.Color
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.IBinder
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import java.lang.Exception import java.lang.Exception
import java.lang.Runnable import java.lang.Runnable
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.io.*
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_play_controls.* import kotlinx.android.synthetic.main.fragment_play_controls.*
import kotlinx.android.synthetic.main.fragment_track_cover.* import kotlinx.android.synthetic.main.fragment_track_cover.*
import kotlinx.android.synthetic.main.fragment_track_details.* import kotlinx.android.synthetic.main.fragment_track_details.*
import kotlinx.android.synthetic.main.fragment_track_elapsing.* import kotlinx.android.synthetic.main.fragment_track_elapsing.*
import kotlinx.android.synthetic.main.fragment_track_flow.* import kotlinx.android.synthetic.main.fragment_track_flow.*
import kotlin.io.*
import kotlin.random.Random
import org.jetbrains.anko.image
import org.jetbrains.anko.imageBitmap
import com.example.mear.playback.service.MusicService
import com.example.mear.R import com.example.mear.R
import com.example.mear.repositories.TrackRepository import com.example.mear.models.PlayControls
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private var musicService: MusicService? = null
private var serviceBinded: Boolean? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
initialize() initialize()
} }
override fun onStop() {
super.onStop()
try {
if (serviceBinded == null || serviceBinded!! == false) {
unbindService(mConnection)
serviceBinded = true
}
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
override fun onDestroy() {
super.onDestroy()
try {
if (serviceBinded!!.equals(null) || serviceBinded!! == false ) {
unbindService(mConnection)
serviceBinded = true
}
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
private fun initialize() { private fun initialize() {
songCount = TrackRepository(this).getSongCount()
currentSong = fetchSongIndex(PlayTypes.PlaySong)
TrackElapsing.progress = 0 TrackElapsing.progress = 0
TrackElapsing.max = 100 TrackElapsing.max = 100
initializeMediaPlayer()
initializeClickListeners() try {
initializeCompletionListener() initializeServices()
initializeClickListeners()
}
catch (ex: Exception) {
val exMsg = ex.message
}
} }
private fun initializeClickListeners() { private fun initializeClickListeners() {
PlayTrack.setOnClickListener { PlayTrack.setOnClickListener {
@@ -62,8 +103,6 @@ class MainActivity : AppCompatActivity() {
SettingsLink.setOnClickListener { SettingsLink.setOnClickListener {
val intent = Intent(this, SettingsActivity::class.java) val intent = Intent(this, SettingsActivity::class.java)
try { try {
startActivity(intent) startActivity(intent)
} }
catch (ex: Exception) { catch (ex: Exception) {
@@ -72,19 +111,8 @@ class MainActivity : AppCompatActivity() {
} }
} }
} }
private fun initializeCompletionListener() { private fun initializeServices() {
trackPlayer!!.setOnCompletionListener { doBindService()
playNextSongTrack()
}
}
private fun initializeMediaPlayer() {
if (trackPlayer == null) {
trackPlayer = MediaPlayer()
playerInitialized = true
val tr = TrackRepository(this).getTrack(currentSong!!)
trackPlayer!!.setDataSource(tr.songPath)
trackPlayer!!.prepare()
}
} }
private fun toggleShuffle() { private fun toggleShuffle() {
@@ -108,12 +136,12 @@ class MainActivity : AppCompatActivity() {
} }
private fun playSongTrack() { private fun playSongTrack() {
PlayTrack.isEnabled = true PlayTrack.isEnabled = false
try { try {
if (!trackPlayer!!.isPlaying) { if (!musicService!!.isPlaying()) {
trackPlayer!!.start() musicService!!.playSongTrack()
} else { } else {
trackPlayer!!.pause() musicService!!.pauseSongTrack()
} }
configureTrackDisplay() configureTrackDisplay()
} }
@@ -125,16 +153,9 @@ class MainActivity : AppCompatActivity() {
private fun playNextSongTrack() { private fun playNextSongTrack() {
NextTrack.isEnabled = false NextTrack.isEnabled = false
try { try {
currentSong = fetchSongIndex(PlayTypes.PlayNextSong) val controls = PlayControls(shuffleOn!!)
musicService!!.playNextTrack(controls)
if (trackPlayer!!.isPlaying) {
trackPlayer!!.stop()
}
trackPlayer!!.reset()
trackPlayer!!.setDataSource(TrackRepository(this).getTrack(currentSong!!).songPath)
trackPlayer!!.prepare()
trackPlayer!!.start()
configureTrackDisplay() configureTrackDisplay()
} }
catch (ex: Exception) { catch (ex: Exception) {
@@ -146,16 +167,9 @@ class MainActivity : AppCompatActivity() {
private fun playPreviousSongTrack() { private fun playPreviousSongTrack() {
PreviousTrack.isEnabled = false PreviousTrack.isEnabled = false
try { try {
currentSong = fetchSongIndex(PlayTypes.PlayPreviousSong) val controls = PlayControls(shuffleOn!!)
musicService!!.playPreviousTrack(controls)
if (trackPlayer!!.isPlaying) {
trackPlayer!!.stop()
}
trackPlayer!!.reset()
trackPlayer!!.setDataSource(TrackRepository(this).getTrack(currentSong!!).songPath)
trackPlayer!!.prepare()
trackPlayer!!.start()
configureTrackDisplay() configureTrackDisplay()
} }
catch (ex: Exception) { catch (ex: Exception) {
@@ -166,54 +180,60 @@ class MainActivity : AppCompatActivity() {
} }
private fun configureTrackDisplay() { private fun configureTrackDisplay() {
try { try {
configurePlayControlsDisplay() runOnUiThread {
val currTrack = TrackRepository(this).getTrack(currentSong!!) configurePlayControlsDisplay()
val trackTitle = currTrack.title val currTrack = musicService!!.getCurrentTrack()
val artistTitle = currTrack.artist val trackTitle = currTrack.title
val albumTitle = currTrack.album val artistTitle = currTrack.artist
val trackDuration = currTrack.length val albumTitle = currTrack.album
var trackCover: ByteArray? = null val trackDuration = currTrack.length
val dur = String.format( var trackCover: ByteArray? = null
"%02d:%02d", TimeUnit.SECONDS.toMinutes(trackDuration.toLong()), val dur = String.format(
(trackDuration % 60) "%02d:%02d", TimeUnit.SECONDS.toMinutes(trackDuration.toLong()),
) (trackDuration % 60)
)
val mmr = MediaMetadataRetriever() val mmr = MediaMetadataRetriever()
mmr.setDataSource(currTrack.songPath) mmr.setDataSource(currTrack.songPath)
if (mmr.embeddedPicture != null) { if (mmr.embeddedPicture != null) {
trackCover = mmr.embeddedPicture trackCover = mmr.embeddedPicture
} }
updateTrackProgress() updateTrackProgress()
TrackTitle.text = null resetControls()
ArtistTitle.text = null
AlbumTitle.text = null
CurrentPosition.text = null
TrackCover.setImageBitmap(null)
TrackTitle.text = trackTitle
ArtistTitle.text = artistTitle TrackTitle.text = trackTitle
AlbumTitle.text = albumTitle ArtistTitle.text = artistTitle
TrackDuration.text = dur AlbumTitle.text = albumTitle
if (trackCover != null) { TrackDuration.text = dur
val songImage = BitmapFactory if (trackCover != null) {
.decodeByteArray(trackCover, 0, trackCover.size) val songImage = BitmapFactory
TrackCover.setImageBitmap(songImage) .decodeByteArray(trackCover, 0, trackCover.size)
TrackCover.imageBitmap = songImage
}
} }
} }
catch (ex: Exception) { catch (ex: Exception) {
val msg = ex.message val msg = ex.message
} }
} }
private fun resetControls() {
TrackTitle!!.text = null
ArtistTitle!!.text = null
AlbumTitle!!.text = null
CurrentPosition!!.text = null
TrackCover!!.imageBitmap = null
}
private fun updateTrackProgress() { private fun updateTrackProgress() {
musicHandler!!.postDelayed(musicTrackTimeUpdateTask, 100) musicHandler!!.postDelayed(musicTrackTimeUpdateTask, 250)
} }
private fun configurePlayControlsDisplay() { private fun configurePlayControlsDisplay() {
PlayTrack.background = null PlayTrack.background = null
PlayTrack.colorFilter = null PlayTrack.colorFilter = null
if (!trackPlayer!!.isPlaying) { if (!musicService!!.isPlaying()) {
PlayTrack.setImageResource(android.R.drawable.ic_media_pause) PlayTrack.setImageResource(android.R.drawable.ic_media_pause)
PlayTrack.setColorFilter(Color.RED) PlayTrack.setColorFilter(Color.RED)
} }
@@ -223,51 +243,25 @@ class MainActivity : AppCompatActivity() {
} }
} }
private fun fetchSongIndex(playType: PlayTypes): Int {
var songIndex: Int? = null
try { private fun isServiceRunning(serviceClass: Class<*>): Boolean {
when (playType) { val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
PlayTypes.PlayPreviousSong -> {
songIndex = songCount for (service in activityManager.getRunningServices(Integer.MAX_VALUE)) {
if (currentSong!! != 0) { if (serviceClass.name == service.service.className) {
if (!shuffleOn!!) { return true
songIndex = currentSong!!.dec()
}
else {
songIndex = Random.nextInt(0, songCount!!)
}
}
}
PlayTypes.PlaySong -> {
songIndex = Random.nextInt(0, songCount!!)
}
PlayTypes.PlayNextSong -> {
songIndex = 0
if (currentSong!! != songCount!!) {
if (!shuffleOn!!) {
songIndex = currentSong!!.inc()
}
else {
songIndex = Random.nextInt(0, songCount!!)
}
}
}
} }
} }
catch (ex: Exception) { return false
val exMsg = ex.message
println(exMsg)
}
return songIndex!!
} }
private var musicTrackTimeUpdateTask = object: Runnable { private var musicTrackTimeUpdateTask = object: Runnable {
override fun run() { override fun run() {
try {
var newPosition = 0 var newPosition = 0
val currentPosition = trackPlayer!!.currentPosition / 1000 val currentPosition = musicService!!.currentPositionOfTrack() / 1000
val totalDuration = trackPlayer!!.duration / 1000 val totalDuration = musicService!!.durationOfTrack() / 1000
newPosition = (((currentPosition).toDouble() / totalDuration) * 100).toInt() newPosition = (((currentPosition).toDouble() / totalDuration) * 100).toInt()
val dur = String.format( val dur = String.format(
"%02d:%02d", TimeUnit.SECONDS.toMinutes(currentPosition.toLong()), "%02d:%02d", TimeUnit.SECONDS.toMinutes(currentPosition.toLong()),
@@ -277,18 +271,69 @@ class MainActivity : AppCompatActivity() {
TrackElapsing.progress = newPosition TrackElapsing.progress = newPosition
musicHandler!!.postDelayed(this, 100) if (TrackCover.image == null && musicService!!.isPlaying()) {
configureTrackDisplay()
}
musicHandler!!.postDelayed(this, 250)
}
catch (ex: Exception) {
val exMsg = ex.message
}
} }
} }
private var musicHandler: Handler? = Handler() private val mConnection = object : ServiceConnection {
private var trackPlayer: MediaPlayer? = null override fun onServiceConnected(className: ComponentName, service: IBinder) {
private var currentSong: Int? = null resetControls()
private var playerInitialized: Boolean? = false
private var shuffleOn: Boolean? = false
private var songCount: Int? = null
private enum class PlayTypes { runBlocking {
PlayNextSong, PlaySong, PlayPreviousSong val demo = launch {
musicService = (service as MusicService.LocalBinder).service
}
demo.start()
}
if (musicService != null) {
if (musicService!!.isPlaying()) {
configureTrackDisplay()
}
}
Toast.makeText(
this@MainActivity, "Music Service Started",
Toast.LENGTH_SHORT
).show()
}
override fun onServiceDisconnected(className: ComponentName) {
resetControls()
Toast.makeText(
this@MainActivity, "Music Service Stopped",
Toast.LENGTH_SHORT
).show()
}
} }
fun doBindService() {
val intent = Intent(this, MusicService::class.java)
if (isServiceRunning(MusicService::class.java)) {
val suc = "Service is already running"
}
else {
startService(intent)
}
var result = bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
if (result) {
}
else {
}
}
private var musicHandler: Handler? = Handler()
private var shuffleOn: Boolean? = false
} }
@@ -42,6 +42,7 @@ class SettingsActivity : AppCompatActivity() {
try { try {
TrackRepository(this).delete() TrackRepository(this).delete()
val trackMgr = TrackManager(allSongs) val trackMgr = TrackManager(allSongs)
trackMgr.configureTracks(this)
} }
catch (ex: Exception) { catch (ex: Exception) {
val exMsg = ex.message val exMsg = ex.message
@@ -0,0 +1,7 @@
package com.example.mear.constants
object DirectoryIgnore {
const val Android_Root = "Android/"
const val Notifications = "Notifications/"
const val Ringtones = "Ringtones/"
}
@@ -0,0 +1,5 @@
package com.example.mear.constants
object FileTypes {
const val Mp3 = "mp3"
}
@@ -0,0 +1,4 @@
package com.example.mear.models
data class PlayControls(val shuffleOn: Boolean) {
}
@@ -1,45 +1,274 @@
package com.example.mear.playback.service package com.example.mear.playback.service
import android.app.NotificationManager
import android.app.Service 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.IBinder import android.os.IBinder
import android.R import android.os.Looper
import android.R.string.cancel
import android.widget.Toast import android.widget.Toast
import java.lang.Exception
import kotlin.random.Random
import com.example.mear.models.Track 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.PlayControls
import com.example.mear.models.Track
import com.example.mear.repositories.TrackRepository import com.example.mear.repositories.TrackRepository
class MusicService: Service() { class MusicService: Service() {
private var trackPlayer: MediaPlayer? = null private var trackPlayer: MediaPlayer? = null
private var currentSongIndex: Int? = null
private var shuffleOn: Boolean? = false
private val mBinder = LocalBinder() private val mBinder = LocalBinder()
private val seconds = 4
inner class LocalBinder : Binder() { inner class LocalBinder : Binder() {
internal val service: MusicService internal val service: MusicService
get() = this@MusicService get() = this@MusicService
} }
private enum class PlayTypes {
PlayNextSong, PlaySong, PlayPreviousSong
}
override fun onCreate() { override fun onCreate() {
initializeMediaPlayer()
} }
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return Service.START_NOT_STICKY return Service.START_STICKY
} }
override fun onDestroy() { override fun onDestroy() {
val intent = Intent(this, mBinder.javaClass)
onUnbind(intent)
Toast.makeText(this, "Music Service Stopped", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Music Service Stopped", Toast.LENGTH_SHORT).show()
} }
override fun onBind(intent: Intent): IBinder? { override fun onBind(intent: Intent): IBinder? {
return mBinder return mBinder
} }
override fun onUnbind(intent: Intent?): Boolean {
return super.onUnbind(intent)
}
fun playSongTrack() {
try {
trackPlayer!!.start()
}
catch (ex: Exception ) {
val exMsg = ex.message
}
}
fun pauseSongTrack() {
try {
trackPlayer!!.pause()
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
fun playPreviousTrack() {
try {
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
fun playNextTrack() {
try {
trackPlayer!!.reset()
var nextTrack = fetchSongIndex(PlayTypes.PlayNextSong)
val track = TrackRepository(this).getTrack(nextTrack)
trackPlayer!!.setDataSource(track.songPath)
trackPlayer!!.prepare()
trackPlayer!!.start()
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
fun playPreviousTrack(controls: PlayControls) {
try {
configureControl(controls)
val duration = trackPlayer!!.currentPosition / 1000
if (duration > seconds) {
trackPlayer!!.reset()
trackPlayer!!.setDataSource(TrackRepository(this).getTrack(currentSongIndex!!).songPath)
trackPlayer!!.prepare()
trackPlayer!!.start()
}
else {
var previousTrack = fetchSongIndex(PlayTypes.PlayPreviousSong)
val track = TrackRepository(this).getTrack(previousTrack)
trackPlayer!!.reset()
trackPlayer!!.setDataSource(track.songPath)
trackPlayer!!.prepare()
trackPlayer!!.start()
}
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
fun configureControl(controls: PlayControls) {
shuffleOn = controls.shuffleOn
}
fun playNextTrack(controls: PlayControls) {
try {
configureControl(controls)
val nextTrack = fetchSongIndex(PlayTypes.PlayNextSong)
val track = TrackRepository(this).getTrack(nextTrack)
trackPlayer!!.reset()
trackPlayer!!.setDataSource(track.songPath)
trackPlayer!!.prepare()
trackPlayer!!.start()
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
fun getCurrentTrack(): Track {
var track: Track? = null
track = TrackRepository(this).getTrack(currentSongIndex!!)
return track!!
}
private fun fetchSongIndex(playType: PlayTypes): Int {
var songIndex: Int? = currentSongIndex
val songCount = retrieveSongCount()
try {
when (playType) {
PlayTypes.PlayPreviousSong -> {
if (currentSongIndex!! != 0) {
if (!shuffleOn!!) {
currentSongIndex = currentSongIndex!!.dec()
songIndex = currentSongIndex!!
}
else {
currentSongIndex = Random.nextInt(0, songCount!!)
songIndex = currentSongIndex
}
}
}
PlayTypes.PlaySong -> {
if (shuffleOn!!) {
songIndex = Random.nextInt(0, songCount!!)
}
else {
songIndex = 0
}
}
PlayTypes.PlayNextSong -> {
if (currentSongIndex!! != songCount!!) {
if (!shuffleOn!!) {
currentSongIndex = currentSongIndex!!.inc()
songIndex = currentSongIndex!!
}
else {
currentSongIndex = Random.nextInt(0, songCount!!)
songIndex = currentSongIndex!!
}
}
}
}
}
catch (ex: Exception) {
val exMsg = ex.message
println(exMsg)
}
return songIndex!!
}
fun currentPositionOfTrack(): Int {
return trackPlayer!!.currentPosition
}
fun durationOfTrack(): Int {
return trackPlayer!!.duration
}
fun isPlaying(): Boolean {
return trackPlayer!!.isPlaying
}
private fun initializeMediaPlayer() {
if (trackPlayer == null) {
trackPlayer = MediaPlayer()
}
if (trackRepositoryEmpty()!!) {
populateTrackRepository()
}
currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount())
val trackToPlay = TrackRepository(this).getTrack(currentSongIndex!!)
trackPlayer!!.setDataSource(trackToPlay.songPath)
trackPlayer!!.prepareAsync()
trackPlayer!!.setOnCompletionListener {
playNextTrack()
}
}
private fun populateTrackRepository() {
var mp3Paths = MusicFiles(android.os.Environment.getExternalStorageDirectory())
mp3Paths.searchForMp3Songs()
val paths = mp3Paths.allSongs
val trackMgr = TrackManager(paths!!)
trackMgr.configureTracks(this)
}
private fun trackRepositoryEmpty(): Boolean? {
val trackCount = retrieveSongCount()
when (trackCount) {
null -> {
return true
}
0 -> {
return true
}
}
return false
}
private fun retrieveSongCount(): Int? {
try {
var db = DatabaseManager(this)
var trackDb = TrackRepository(this)
val count = trackDb.getSongCount()
return count
}
catch (ex: Exception) {
val exMsg = ex.message
}
return 0
}
} }
@@ -7,9 +7,15 @@ import org.jetbrains.anko.db.*
import com.example.mear.database import com.example.mear.database
import com.example.mear.models.Track import com.example.mear.models.Track
class TrackRepository(val context: Context) { class TrackRepository {
private var context: Context? = null
fun getAll(): List<Track> = context.database.use { constructor(context: Context)
{
this.context = context
}
fun getAll(): List<Track> = context!!.database.use {
val tracks = mutableListOf<Track>() val tracks = mutableListOf<Track>()
select("Track" ) select("Track" )
@@ -31,7 +37,7 @@ class TrackRepository(val context: Context) {
}) })
tracks tracks
} }
fun getTrack(id: Int): Track = context.database.use { fun getTrack(id: Int): Track = context!!.database.use {
select("Track").where("Id = $id") select("Track").where("Id = $id")
.parseSingle(object: MapRowParser<Track>{ .parseSingle(object: MapRowParser<Track>{
override fun parseRow(columns: Map<String, Any?>): Track { override fun parseRow(columns: Map<String, Any?>): Track {
@@ -49,7 +55,7 @@ class TrackRepository(val context: Context) {
} }
}) })
} }
fun getSongCount(): Int = context.database.use { fun getSongCount(): Int = context!!.database.use {
select("TrackCount").limit(1) select("TrackCount").limit(1)
.parseSingle(object : MapRowParser<Int>{ .parseSingle(object : MapRowParser<Int>{
override fun parseRow(columns: Map<String, Any?>): Int { override fun parseRow(columns: Map<String, Any?>): Int {
@@ -59,7 +65,7 @@ class TrackRepository(val context: Context) {
}) })
} }
fun insertTrack(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,
@@ -68,16 +74,25 @@ class TrackRepository(val context: Context) {
"Duration" to track.length, "Duration" to track.length,
"FilePath" to track.songPath) "FilePath" to track.songPath)
} }
fun createSongCount(songCount: Int) = context.database.use { fun createSongCount(songCount: Int) = context!!.database.use {
delete("TrackCount")
insert("TrackCount", insert("TrackCount",
"Id" to 0, "Id" to 0,
"TotalSongs" to songCount) "TotalSongs" to songCount)
} }
fun delete() = context!!.database.use {
fun delete(table: Any?) = context.database.use {
delete("Track", whereClause = "id = {$table.id}")
}
fun delete() = context.database.use {
delete("Track") delete("Track")
} }
fun getLibraryCount(): Int? {
context!!.database.use {
select("TrackCount").limit(1)
.parseList (object : MapRowParser<Int> {
override fun parseRow(columns: Map<String, Any?>): Int {
return columns.getValue("TotalSongs").toString().toInt()
}
})
}
return 0
}
} }
@@ -5,4 +5,4 @@ import android.content.Context
import com.example.mear.management.DatabaseManager import com.example.mear.management.DatabaseManager
val Context.database: DatabaseManager val Context.database: DatabaseManager
get() = DatabaseManager.getInstance(applicationContext) get() = DatabaseManager.getInstance(applicationContext)