Having issue with repeat a song when pressing the next button or if the song ends (which proceeds to the next song). Need to work on shuffling

This commit is contained in:
kdeng00
2019-10-29 21:13:51 -04:00
parent 6221969d6b
commit 2ba9dfd57a
6 changed files with 117 additions and 64 deletions
+3
View File
@@ -54,6 +54,7 @@ jobject songToObj(JNIEnv *env, const model::Song& song)
jmethodID songGenre = env->GetMethodID( songClass, "setGenre", "(Ljava/lang/String;)V" ); jmethodID songGenre = env->GetMethodID( songClass, "setGenre", "(Ljava/lang/String;)V" );
jmethodID songDuration = env->GetMethodID( songClass, "setDuration", "(I)V" ); jmethodID songDuration = env->GetMethodID( songClass, "setDuration", "(I)V" );
jmethodID songYear = env->GetMethodID( songClass, "setYear", "(I)V" ); jmethodID songYear = env->GetMethodID( songClass, "setYear", "(I)V" );
jmethodID songCoverArtId = env->GetMethodID(songClass, "setCoverArtId", "(I)V");
jint id = song.id; jint id = song.id;
jstring title = env->NewStringUTF(song.title.c_str()); jstring title = env->NewStringUTF(song.title.c_str());
@@ -62,6 +63,7 @@ jobject songToObj(JNIEnv *env, const model::Song& song)
jstring genre = env->NewStringUTF(song.genre.c_str()); jstring genre = env->NewStringUTF(song.genre.c_str());
jint duration = song.duration; jint duration = song.duration;
jint year = song.year; jint year = song.year;
jint coverArtId = song.coverArtId;
env->CallVoidMethod( songObj, songId, id ); env->CallVoidMethod( songObj, songId, id );
env->CallVoidMethod(songObj, songTitle, title); env->CallVoidMethod(songObj, songTitle, title);
@@ -70,6 +72,7 @@ jobject songToObj(JNIEnv *env, const model::Song& song)
env->CallVoidMethod(songObj, songGenre, genre); env->CallVoidMethod(songObj, songGenre, genre);
env->CallVoidMethod(songObj, songDuration, duration); env->CallVoidMethod(songObj, songDuration, duration);
env->CallVoidMethod(songObj, songYear, year); env->CallVoidMethod(songObj, songYear, year);
env->CallVoidMethod(songObj, songCoverArtId, coverArtId);
return songObj; return songObj;
} }
+7 -1
View File
@@ -22,7 +22,7 @@ namespace repository { namespace local {
const auto result = query.executeStep(); const auto result = query.executeStep();
auto repeatType = query.getColumn(1).getInt(); auto repeatType = query.getColumn(1).getInt();
auto val = static_cast<RepeatTypes>(result); auto val = static_cast<RepeatTypes>(repeatType);
return val; return val;
} catch (std::exception& ex) { } catch (std::exception& ex) {
auto msg = ex.what(); auto msg = ex.what();
@@ -40,6 +40,12 @@ namespace repository { namespace local {
queryString.append(" (Id INTEGER PRIMARY KEY, RepeatMode INT)"); queryString.append(" (Id INTEGER PRIMARY KEY, RepeatMode INT)");
db.exec(queryString); db.exec(queryString);
queryString = "INSERT INTO " + m_tableName + " (RepeatMode) VALUES(?)";
SQLite::Statement query(db, queryString);
query.bind(1, static_cast<int>(RepeatTypes::RepeatOff));
query.exec();
} catch (std::exception& ex) { } catch (std::exception& ex) {
auto msg = ex.what(); auto msg = ex.what();
} }
@@ -1,20 +1,5 @@
package com.example.mear.activities package com.example.mear.activities
import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.R as RDroid
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.view.MenuItem
import android.view.View
import android.widget.PopupMenu
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
@@ -26,21 +11,31 @@ 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 android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.view.MenuItem
import android.view.View
import android.widget.PopupMenu
import android.widget.Toast
import org.jetbrains.anko.imageBitmap import org.jetbrains.anko.imageBitmap
import com.example.mear.constants.ControlTypes import com.example.mear.constants.ControlTypes
import com.example.mear.listeners.TrackElaspingChange import com.example.mear.listeners.TrackElaspingChange
import com.example.mear.models.PlayControls import com.example.mear.models.PlayControls
import com.example.mear.R
import com.example.mear.models.PlayCount import com.example.mear.models.PlayCount
import com.example.mear.models.Song import com.example.mear.models.Song
import com.example.mear.R
import com.example.mear.repositories.PlayCountRepository import com.example.mear.repositories.PlayCountRepository
import com.example.mear.repositories.RepeatRepository import com.example.mear.repositories.RepeatRepository
import com.example.mear.repositories.RepeatRepository.RepeatTypes
import com.example.mear.repositories.ShuffleRepository import com.example.mear.repositories.ShuffleRepository
import com.example.mear.repositories.TrackRepository
import com.example.mear.util.ConvertByteArray
import com.example.mear.util.ExtractCover
import kotlinx.coroutines.delay
class MainActivity : BaseServiceActivity() { class MainActivity : BaseServiceActivity() {
@@ -111,6 +106,7 @@ class MainActivity : BaseServiceActivity() {
initializeRepeat() initializeRepeat()
initializeServices() initializeServices()
initializeClickListeners() initializeClickListeners()
configurePlayControlsDisplay()
} }
catch (ex: Exception) { catch (ex: Exception) {
val exMsg = ex.message val exMsg = ex.message
@@ -167,10 +163,10 @@ class MainActivity : BaseServiceActivity() {
val repeatRepo = RepeatRepository(null) val repeatRepo = RepeatRepository(null)
val repeatMode = repeatRepo.repeatMode(appDirectory()) val repeatMode = repeatRepo.repeatMode(appDirectory())
when (repeatMode) { when (repeatMode) {
RepeatRepository.RepeatTypes.RepeatSong -> { RepeatTypes.RepeatSong -> {
RepeatTrack.text = resources.getText(R.string.repeat_on) RepeatTrack.text = resources.getText(R.string.repeat_on)
} }
RepeatRepository.RepeatTypes.RepeatOff -> { RepeatTypes.RepeatOff -> {
RepeatTrack.text = resources.getText(R.string.repeat_off) RepeatTrack.text = resources.getText(R.string.repeat_off)
} }
} }
@@ -223,14 +219,13 @@ class MainActivity : BaseServiceActivity() {
val appPath = appDirectory() val appPath = appDirectory()
repeatRepo.alterRepeatMode(appPath) repeatRepo.alterRepeatMode(appPath)
val repeatMode = repeatRepo.repeatMode(appPath)
when (repeatMode) { when (repeatRepo.repeatMode(appPath)) {
RepeatRepository.RepeatTypes.RepeatOff -> { RepeatTypes.RepeatOff -> {
repeatOn = false repeatOn = false
RepeatTrack.text = resources.getText(R.string.repeat_off) RepeatTrack.text = resources.getText(R.string.repeat_off)
} }
RepeatRepository.RepeatTypes.RepeatSong -> { RepeatTypes.RepeatSong -> {
repeatOn = true repeatOn = true
RepeatTrack.text = resources.getText(R.string.repeat_on) RepeatTrack.text = resources.getText(R.string.repeat_on)
} }
@@ -317,14 +312,14 @@ class MainActivity : BaseServiceActivity() {
PlayTrack.background = null PlayTrack.background = null
PlayTrack.colorFilter = null PlayTrack.colorFilter = null
if (!musicService!!.isPlaying()) { if ((musicService == null || !musicService!!.isPlaying())) {
PlayTrack.setImageResource(android.R.drawable.ic_media_pause)
PlayTrack.setColorFilter(Color.RED)
}
else {
PlayTrack.setImageResource(android.R.drawable.ic_media_play) PlayTrack.setImageResource(android.R.drawable.ic_media_play)
PlayTrack.setColorFilter(Color.GREEN) PlayTrack.setColorFilter(Color.GREEN)
} }
else {
PlayTrack.setImageResource(android.R.drawable.ic_media_pause)
PlayTrack.setColorFilter(Color.RED)
}
} }
// TODO: Might need this down the road for playing songs off an external // TODO: Might need this down the road for playing songs off an external
@@ -1,4 +1,5 @@
package com.example.mear.models package com.example.mear.models
class Song (var id: Int = 3, var title: String = "", var album: String = "", var artist: String = "", class Song (var id: Int = 3, var title: String = "", var album: String = "", var artist: String = "",
var genre: String = "", var year: Int = 0, var duration: Int = 0) var genre: String = "", var year: Int = 0, var duration: Int = 0,
var coverArtId: Int = 0)
@@ -1,5 +1,8 @@
package com.example.mear.playback.service package com.example.mear.playback.service
import java.lang.Exception
import kotlin.random.Random
import android.app.Service import android.app.Service
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -10,9 +13,6 @@ import android.os.Environment
import android.os.IBinder import android.os.IBinder
import android.widget.Toast import android.widget.Toast
import java.lang.Exception
import kotlin.random.Random
import com.example.mear.constants.ControlTypes import com.example.mear.constants.ControlTypes
import com.example.mear.constants.Interval import com.example.mear.constants.Interval
import com.example.mear.management.MusicFiles import com.example.mear.management.MusicFiles
@@ -23,8 +23,7 @@ import com.example.mear.models.Song
import com.example.mear.models.Token import com.example.mear.models.Token
import com.example.mear.models.Track import com.example.mear.models.Track
import com.example.mear.repositories.* import com.example.mear.repositories.*
import kotlinx.coroutines.GlobalScope import com.example.mear.repositories.RepeatRepository.RepeatTypes
import kotlinx.coroutines.launch
class MusicService(var appPath: String = ""): Service() { class MusicService(var appPath: String = ""): Service() {
@@ -34,14 +33,14 @@ class MusicService(var appPath: String = ""): Service() {
} }
private var trackPlayer: MediaPlayer? = null private var trackPlayer: MediaPlayer? = null
private var trackMgr: TrackManager? = null //private var trackMgr: TrackManager? = null
private var songQueue = mutableListOf<Song>() private var songQueue = mutableListOf<Song>()
private var currentTrack = Track() //private var currentTrack = Track()
private var currentSong = Song() private var currentSong = Song()
private var currentSongIndex: Int? = null private var currentSongIndex: Int? = null
private var addingMusic: Boolean? = false //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()
private val seconds = Interval.SONG_REWIND private val seconds = Interval.SONG_REWIND
@@ -87,6 +86,7 @@ class MusicService(var appPath: String = ""): Service() {
fun icarusPlaySong(token: Token, song: Song, apiInfo: APIInfo) { fun icarusPlaySong(token: Token, song: Song, apiInfo: APIInfo) {
val uri = APIRepository.retrieveSongStreamUri(apiInfo, song) val uri = APIRepository.retrieveSongStreamUri(apiInfo, song)
val hddr = APIRepository.retrieveSongStreamHeader(token) val hddr = APIRepository.retrieveSongStreamHeader(token)
currentSong = song
try { try {
trackPlayer!!.reset() trackPlayer!!.reset()
@@ -99,10 +99,8 @@ class MusicService(var appPath: String = ""): Service() {
} }
} }
fun goToPosition(progress: Int) { trackPlayer!!.seekTo(progress) }
fun goToPosition(progress: Int) {
trackPlayer!!.seekTo(progress)
}
fun playSongTrack() { fun playSongTrack() {
try { try {
trackPlayer!!.start() trackPlayer!!.start()
@@ -111,6 +109,7 @@ class MusicService(var appPath: String = ""): Service() {
val exMsg = ex.message val exMsg = ex.message
} }
} }
fun pauseSongTrack() { fun pauseSongTrack() {
try { try {
trackPlayer!!.pause() trackPlayer!!.pause()
@@ -119,30 +118,47 @@ class MusicService(var appPath: String = ""): Service() {
val exMsg = ex.message val exMsg = ex.message
} }
} }
fun playPreviousTrack() { fun playPreviousTrack() {
try { try {
val duration = trackPlayer!!.currentPosition / 1000 val duration = trackPlayer!!.currentPosition / 1000
shuffleOn = retrieveShuffleMode() shuffleOn = retrieveShuffleMode()
val apiRepo = APIRepository() val apiRepo = APIRepository()
val repeatRepo = RepeatRepository(null)
val tokenRepo = TokenRepository() val tokenRepo = TokenRepository()
val repeatMode = repeatRepo.repeatMode(appPath)
val token = tokenRepo.retrieveToken(appPath) val token = tokenRepo.retrieveToken(appPath)
val apiInfo = apiRepo.retrieveRecord(appPath) val apiInfo = apiRepo.retrieveRecord(appPath)
currentSong = songQueue[Random.nextInt(0, songQueue.size - 1)] if (parseRepeatMode(repeatMode) || duration > seconds) {
/**
trackPlayer!!.reset()
if (duration > seconds) {
trackPlayer!!.setDataSource(this, trackPlayer!!.setDataSource(this,
APIRepository.retrieveSongStreamUri(apiInfo, currentSong), APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
APIRepository.retrieveSongStreamHeader(token)) APIRepository.retrieveSongStreamHeader(token))
trackPlayer!!.prepare() */
//trackPlayer!!.prepare()
trackPlayer!!.pause()
trackPlayer!!.seekTo(0)
trackPlayer!!.start() trackPlayer!!.start()
} }
else { else {
if (currentSongIndex == 0) {
currentSongIndex = songQueue.size - 1
}
else {
currentSongIndex = currentSongIndex!! - 1
}
currentSong = songQueue[currentSongIndex!!]
val uri = APIRepository.retrieveSongStreamUri(apiInfo, currentSong)
val hddr = APIRepository.retrieveSongStreamHeader(token)
trackPlayer!!.reset()
trackPlayer!!.setDataSource(this, trackPlayer!!.setDataSource(this,
uri, hddr)
/**
APIRepository.retrieveSongStreamUri(apiInfo, currentSong), APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
APIRepository.retrieveSongStreamHeader(token)) APIRepository.retrieveSongStreamHeader(token))
*/
trackPlayer!!.prepare() trackPlayer!!.prepare()
trackPlayer!!.start() trackPlayer!!.start()
} }
@@ -156,11 +172,27 @@ class MusicService(var appPath: String = ""): Service() {
trackPlayer!!.reset() trackPlayer!!.reset()
shuffleOn = retrieveShuffleMode() shuffleOn = retrieveShuffleMode()
val apiRepo = APIRepository() val apiRepo = APIRepository()
val repeatRepo = RepeatRepository(null)
val tokenRepo = TokenRepository() val tokenRepo = TokenRepository()
val token = tokenRepo.retrieveToken(appPath) val token = tokenRepo.retrieveToken(appPath)
val repeatMode = repeatRepo.repeatMode(appPath)
val apiInfo = apiRepo.retrieveRecord(appPath) val apiInfo = apiRepo.retrieveRecord(appPath)
currentSong = songQueue[Random.nextInt(0, songQueue.size - 1)]
/**
if (parseRepeatMode(repeatMode)) {
//trackPlayer!!.pause()
trackPlayer!!.seekTo(0)
//trackPlayer!!.start()
return
}
else*/ if ((currentSongIndex!! + 1) == songQueue.size) {
currentSongIndex = 0
}
else {
currentSongIndex = currentSongIndex!! + 1
}
currentSong = songQueue[currentSongIndex!!]
trackPlayer!!.setDataSource(this, trackPlayer!!.setDataSource(this,
APIRepository.retrieveSongStreamUri(apiInfo, currentSong), APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
@@ -173,26 +205,22 @@ class MusicService(var appPath: String = ""): Service() {
} }
} }
/**
fun configureControl(controls: PlayControls) { fun configureControl(controls: PlayControls) {
shuffleOn = controls.shuffleOn shuffleOn = controls.shuffleOn
repeatOn = controls.repeatOn repeatOn = controls.repeatOn
} }
*/
fun getCurrentSong(): Song { fun getCurrentSong(): Song { return currentSong }
return currentSong
}
fun currentPositionOfTrack(): Int { fun currentPositionOfTrack(): Int { return trackPlayer!!.currentPosition }
return trackPlayer!!.currentPosition
}
fun durationOfTrack(): Int {
return trackPlayer!!.duration
}
fun isPlaying(): Boolean { fun durationOfTrack(): Int { return trackPlayer!!.duration }
return trackPlayer!!.isPlaying
}
fun isPlaying(): Boolean { return trackPlayer!!.isPlaying }
private fun initializeMediaPlayer() { private fun initializeMediaPlayer() {
@@ -213,7 +241,8 @@ class MusicService(var appPath: String = ""): Service() {
val songs = trackRepo.fetchSongs(token, apiInfo.uri) val songs = trackRepo.fetchSongs(token, apiInfo.uri)
songQueue = songs.toMutableList() songQueue = songs.toMutableList()
currentSong = songQueue[Random.nextInt(0, songs.size - 1)] currentSongIndex = Random.nextInt(0, songs.size - 1)
currentSong = songQueue[currentSongIndex!!]
trackPlayer!!.setDataSource(this, trackPlayer!!.setDataSource(this,
APIRepository.retrieveSongStreamUri(apiInfo, currentSong), APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
APIRepository.retrieveSongStreamHeader(token)) APIRepository.retrieveSongStreamHeader(token))
@@ -227,6 +256,7 @@ class MusicService(var appPath: String = ""): Service() {
} }
} }
/**
private fun initializeShuffleMode() { private fun initializeShuffleMode() {
try { try {
val shuffleMode = ShuffleRepository(this).getShuffleMode() val shuffleMode = ShuffleRepository(this).getShuffleMode()
@@ -259,6 +289,7 @@ class MusicService(var appPath: String = ""): Service() {
val exMsg = ex.message val exMsg = ex.message
} }
} }
*/
private fun retrieveShuffleMode(): Boolean? { private fun retrieveShuffleMode(): Boolean? {
@@ -276,6 +307,17 @@ class MusicService(var appPath: String = ""): Service() {
} }
} }
private fun parseRepeatMode(repeatMode: RepeatTypes): Boolean {
var repeatOn: Boolean? = null
when (repeatMode) {
RepeatTypes.RepeatOff -> repeatOn = false
RepeatTypes.RepeatSong -> repeatOn = true
}
return repeatOn!!
}
/**
private fun retrieveRepeatMode(): Boolean? { private fun retrieveRepeatMode(): Boolean? {
val repeatMode = RepeatRepository(this).getRepeatMode() val repeatMode = RepeatRepository(this).getRepeatMode()
when (repeatMode) { when (repeatMode) {
@@ -290,4 +332,5 @@ class MusicService(var appPath: String = ""): Service() {
} }
} }
} }
*/
} }
@@ -23,6 +23,7 @@ class RepeatRepository(var context: Context?) {
private external fun updateRepeatMode(path: String) private external fun updateRepeatMode(path: String)
/**
fun getRepeatMode(): String = context!!.database.use { fun getRepeatMode(): String = context!!.database.use {
select("Repeat").limit(1) select("Repeat").limit(1)
.parseSingle(object: MapRowParser<String>{ .parseSingle(object: MapRowParser<String>{
@@ -33,6 +34,8 @@ class RepeatRepository(var context: Context?) {
}) })
} }
*/
fun repeatMode(path: String): RepeatTypes { fun repeatMode(path: String): RepeatTypes {
val repeatType = RepeatTypes.valueOf(retrieveRepeatMode(path)) val repeatType = RepeatTypes.valueOf(retrieveRepeatMode(path))
@@ -45,6 +48,7 @@ class RepeatRepository(var context: Context?) {
} }
/**
fun updateRepeatMode(playControls: PlayControls?) = context!!.database.use { fun updateRepeatMode(playControls: PlayControls?) = context!!.database.use {
var repeatMode = ControlTypes.REPEAT_OFF var repeatMode = ControlTypes.REPEAT_OFF
if (playControls!!.repeatOn!!) { if (playControls!!.repeatOn!!) {
@@ -53,6 +57,7 @@ class RepeatRepository(var context: Context?) {
update("Repeat", update("Repeat",
"Mode" to repeatMode).exec() "Mode" to repeatMode).exec()
} }
*/
enum class RepeatTypes(val value: Int) { enum class RepeatTypes(val value: Int) {
RepeatSong(0), RepeatSong(0),