Able to play songs from icarus and use a partial set of controls. Next up is the cover art.
This commit is contained in:
+6
-6
@@ -8,6 +8,11 @@
|
||||
<option name="LAST_KNOWN_AGP_VERSION" value="3.5.1" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="native-android-gradle" name="Native-Android-Gradle">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug-x86" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
@@ -19,7 +24,7 @@
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res;file://$MODULE_DIR$/build/generated/res/resValues/debug" />
|
||||
<option name="TEST_RES_FOLDERS_RELATIVE_PATH" value="" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
</configuration>
|
||||
@@ -53,11 +58,6 @@
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="native-android-gradle" name="Native-Android-Gradle">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug-x86" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/javac/debug/classes" />
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.os.IBinder
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
@@ -83,6 +84,7 @@ open class BaseServiceActivity: AppCompatActivity() {
|
||||
val suc = "Service is already running"
|
||||
}
|
||||
else {
|
||||
intent.putExtra("appPath", appDirectory())
|
||||
startService(intent)
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,8 @@ class LoginActivity : BaseServiceActivity() {
|
||||
usrRepo.saveCredentials(usr, pa)
|
||||
}
|
||||
tokenRepo.saveToken(myToken, pa)
|
||||
startActivity(Intent(this, IcarusSongActivity::class.java))
|
||||
//startActivity(Intent(this, IcarusSongActivity::class.java))
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val msg = ex.message
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.example.mear.listeners.TrackElaspingChange
|
||||
import com.example.mear.models.PlayControls
|
||||
import com.example.mear.R
|
||||
import com.example.mear.models.PlayCount
|
||||
import com.example.mear.models.Song
|
||||
import com.example.mear.repositories.PlayCountRepository
|
||||
import com.example.mear.repositories.RepeatRepository
|
||||
import com.example.mear.repositories.ShuffleRepository
|
||||
@@ -53,18 +54,20 @@ class MainActivity : BaseServiceActivity() {
|
||||
private var repeatOn: Boolean? = false
|
||||
private var shuffleOn: Boolean? = false
|
||||
|
||||
external fun test()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
setSupportActionBar(toolbar)
|
||||
try {
|
||||
setContentView(R.layout.activity_main)
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
test()
|
||||
//permissionPrompt()
|
||||
|
||||
permissionPrompt()
|
||||
|
||||
initialize()
|
||||
initialize()
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val msg = ex.message
|
||||
}
|
||||
}
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
@@ -263,33 +266,18 @@ class MainActivity : BaseServiceActivity() {
|
||||
runOnUiThread {
|
||||
playCountUpdated = false
|
||||
configurePlayControlsDisplay()
|
||||
val currTrack = musicService!!.getCurrentTrack()
|
||||
val trackTitle = currTrack.title
|
||||
val artistTitle = currTrack.artist
|
||||
val albumTitle = currTrack.album
|
||||
val trackDuration = currTrack.length
|
||||
var trackCover: ByteArray? = null
|
||||
val currSong= musicService!!.getCurrentSong()
|
||||
val dur = String.format(
|
||||
"%02d:%02d", TimeUnit.SECONDS.toMinutes(trackDuration.toLong()),
|
||||
(trackDuration % 60)
|
||||
"%02d:%02d", TimeUnit.SECONDS.toMinutes(currSong.duration.toLong()),
|
||||
(currSong.duration % 60)
|
||||
)
|
||||
|
||||
var coverExt = ExtractCover(currTrack.songPath)
|
||||
|
||||
if (coverExt.hasCover()) {
|
||||
trackCover = coverExt.retrieveCover()
|
||||
}
|
||||
resetControls()
|
||||
|
||||
TrackTitle.text = trackTitle
|
||||
ArtistTitle.text = artistTitle
|
||||
AlbumTitle.text = albumTitle
|
||||
TrackTitle.text = currSong.title
|
||||
ArtistTitle.text = currSong.artist
|
||||
AlbumTitle.text = currSong.album
|
||||
TrackDuration.text = dur
|
||||
if (trackCover != null) {
|
||||
val convertToBmp = ConvertByteArray(trackCover!!)
|
||||
var songImage = convertToBmp.convertToBmp()
|
||||
TrackCover.imageBitmap = songImage
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
@@ -305,8 +293,6 @@ class MainActivity : BaseServiceActivity() {
|
||||
}
|
||||
override fun updateTrackProgress() {
|
||||
musicHandler!!.postDelayed(musicTrackTimeUpdateTask, 100)
|
||||
coverArtHandler!!.postDelayed(updateCoverArt, 100)
|
||||
updateLibraryHandler!!.postDelayed(updateLibrary, 1000)
|
||||
}
|
||||
private fun configurePlayControlsDisplay() {
|
||||
PlayTrack.background = null
|
||||
@@ -322,6 +308,8 @@ class MainActivity : BaseServiceActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Might need this down the road for playing songs off an external
|
||||
// storage
|
||||
private fun permissionPrompt() {
|
||||
if (ContextCompat.checkSelfPermission(this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
@@ -348,10 +336,10 @@ class MainActivity : BaseServiceActivity() {
|
||||
startActivity(Intent(this, SettingsActivity::class.java))
|
||||
}
|
||||
R.id.action_song_view -> {
|
||||
startActivity(Intent(this, SongViewActivity::class.java))
|
||||
startActivity(Intent(this, IcarusSongActivity::class.java))
|
||||
}
|
||||
R.id.action_song_play_count-> {
|
||||
val trk = musicService!!.getCurrentTrack()
|
||||
val trk = musicService!!.getCurrentSong()
|
||||
val pc = PlayCountRepository(this).getPlayCount(trk.id)
|
||||
val playCount = pc.playCount
|
||||
Toast.makeText(this, "Song played $playCount times", Toast.LENGTH_LONG).show()
|
||||
@@ -379,42 +367,8 @@ class MainActivity : BaseServiceActivity() {
|
||||
musicHandler!!.postDelayed(this, 100)
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val exMsg = ex.message
|
||||
val exMsg = ex.message
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
init {
|
||||
System.loadLibrary("native-lib")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
package com.example.mear.activities
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.annotation.RequiresApi
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.view.View
|
||||
//import android.widget.SearchView
|
||||
import android.support.v7.widget.SearchView
|
||||
|
||||
import java.lang.Exception
|
||||
import kotlinx.android.synthetic.main.activity_song_view.*
|
||||
import kotlinx.android.synthetic.main.content_song_view.*
|
||||
|
||||
import com.example.mear.adapters.RecyclerAdapter
|
||||
import com.example.mear.models.TrackItems
|
||||
import com.example.mear.R
|
||||
import com.example.mear.repositories.TrackRepository
|
||||
import org.jetbrains.anko.appcompat.v7.tintedEditText
|
||||
import org.jetbrains.anko.backgroundColorResource
|
||||
import org.jetbrains.anko.editText
|
||||
import org.jetbrains.anko.textView
|
||||
import android.R as RDroid
|
||||
|
||||
|
||||
|
||||
class SongViewActivity : BaseServiceActivity() {
|
||||
|
||||
private var trackListItems = arrayListOf<TrackItems>()
|
||||
private lateinit var adapter: RecyclerAdapter
|
||||
private lateinit var linearLayoutManager: LinearLayoutManager
|
||||
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_song_view)
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
try {
|
||||
window.statusBarColor = resources.getColor(R.color.track_seek)
|
||||
doBindService()
|
||||
initializeAdapter()
|
||||
initializeSongSearchListener()
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
var exMsg = ex.message
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
if (trackListItems.size == 0) {
|
||||
val df = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun playTrack(trackItems: TrackItems) {
|
||||
val id = trackItems.id
|
||||
musicService!!.playTrack(id)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
private fun initializeAdapter() {
|
||||
try {
|
||||
linearLayoutManager = LinearLayoutManager(this)
|
||||
trackList.layoutManager = linearLayoutManager
|
||||
|
||||
trackListItems = retrieveTrackItems()
|
||||
trackListItems.sortedWith(compareBy { it.trackTitle })
|
||||
|
||||
adapter = RecyclerAdapter({trackItem: TrackItems -> playTrack(trackItem)}, trackListItems)
|
||||
adapter.configureActivity(this)
|
||||
|
||||
trackList.adapter = adapter
|
||||
|
||||
trackList.setHasFixedSize(true)
|
||||
trackList.setItemViewCacheSize(20);
|
||||
trackList.setDrawingCacheEnabled(true);
|
||||
trackList.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val exMsg = ex.message
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
private fun retrieveTrackItems(): ArrayList<TrackItems> {
|
||||
var trackItems: ArrayList<TrackItems>? = null
|
||||
try {
|
||||
trackItems = arrayListOf()
|
||||
|
||||
val tracks = TrackRepository(this).getAll()
|
||||
|
||||
for (track in tracks) {
|
||||
var trackCover = ByteArray(0)
|
||||
val trackItem = TrackItems(track.id, track.title, track.artist, track.songPath, trackCover!!)
|
||||
trackItems.add(trackItem)
|
||||
}
|
||||
return trackItems
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val exMsg = ex.message
|
||||
}
|
||||
|
||||
return trackItems!!
|
||||
}
|
||||
|
||||
private fun initializeSongSearchListener() {
|
||||
songSearch.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
try {
|
||||
adapter.filter.filter(query)
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val exMsg = ex.message
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
try {
|
||||
adapter.filter.filter(newText)
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val exMsg = ex.message
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -22,14 +22,12 @@ import com.example.mear.models.APIInfo
|
||||
import com.example.mear.models.Song
|
||||
import com.example.mear.models.Token
|
||||
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 com.example.mear.repositories.*
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class MusicService: Service() {
|
||||
class MusicService(var appPath: String = ""): Service() {
|
||||
|
||||
companion object {
|
||||
//fun curSongIndex(): Int = currentSongIndex
|
||||
@@ -37,7 +35,9 @@ class MusicService: Service() {
|
||||
|
||||
private var trackPlayer: MediaPlayer? = null
|
||||
private var trackMgr: TrackManager? = null
|
||||
private var songQueue = mutableListOf<Song>()
|
||||
private var currentTrack = Track()
|
||||
private var currentSong = Song()
|
||||
private var currentSongIndex: Int? = null
|
||||
private var addingMusic: Boolean? = false
|
||||
private var shuffleOn: Boolean? = null
|
||||
@@ -62,11 +62,13 @@ class MusicService: Service() {
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
val b = intent.extras
|
||||
appPath = b!!.get("appPath") as String
|
||||
initializeMediaPlayer()
|
||||
return Service.START_STICKY
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
val intent = Intent(this, mBinder.javaClass)
|
||||
onUnbind(intent)
|
||||
|
||||
@@ -81,44 +83,11 @@ class MusicService: Service() {
|
||||
return super.onUnbind(intent)
|
||||
}
|
||||
|
||||
fun playTrack(id: Int) {
|
||||
try {
|
||||
currentSongIndex = id
|
||||
trackPlayer!!.reset()
|
||||
currentTrack = TrackRepository(this).getTrack(id)
|
||||
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||
trackPlayer!!.prepare()
|
||||
trackPlayer!!.start()
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val exMsg = ex.message
|
||||
}
|
||||
}
|
||||
|
||||
fun icarusPlaySong(token: String, song: Song) {
|
||||
var uriBase = "https://www.soaricarus.com/api/v1/song/stream/"
|
||||
val id = song.id
|
||||
uriBase += "$id"
|
||||
var uri: Uri = Uri.parse(uriBase)
|
||||
var hddr: MutableMap<String, String> = mutableMapOf()
|
||||
hddr["Authorization"] = "Bearer $token"
|
||||
try {
|
||||
trackPlayer!!.reset()
|
||||
trackPlayer!!.setDataSource(this, uri, hddr)
|
||||
trackPlayer!!.prepare()
|
||||
trackPlayer!!.start()
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val msg = ex.message
|
||||
}
|
||||
}
|
||||
|
||||
fun icarusPlaySong(token: Token, song: Song, apiInfo: APIInfo) {
|
||||
val uriStr = "${apiInfo.uri}/api/v${apiInfo.version}/song/stream/${song.id}"
|
||||
val uri = Uri.parse(uriStr)
|
||||
var hddr: MutableMap<String, String> = mutableMapOf()
|
||||
hddr["Authorization"] = "Bearer ${token.accessToken}"
|
||||
hddr["Content-type"] = "Keep-alive"
|
||||
val uri = APIRepository.retrieveSongStreamUri(apiInfo, song)
|
||||
val hddr = APIRepository.retrieveSongStreamHeader(token)
|
||||
|
||||
try {
|
||||
trackPlayer!!.reset()
|
||||
trackPlayer!!.setDataSource(this, uri, hddr)
|
||||
@@ -130,27 +99,6 @@ class MusicService: Service() {
|
||||
}
|
||||
}
|
||||
|
||||
fun icarusPlaySong(ctx: Context, token: String, uriBase: String, song: Song) {
|
||||
var uriStr = uriBase
|
||||
val id = song.id
|
||||
uriStr += "/api/v1/song/stream/"
|
||||
uriStr += "$id"
|
||||
|
||||
var uri: Uri = Uri.parse(uriStr)
|
||||
var hddr: MutableMap<String, String> = mutableMapOf()
|
||||
hddr["Authorization"] = "Bearer $token"
|
||||
|
||||
try {
|
||||
trackPlayer!!.reset()
|
||||
trackPlayer!!.setDataSource(ctx, uri, hddr)
|
||||
trackPlayer!!.prepare()
|
||||
trackPlayer!!.start()
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val msg = ex.message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun goToPosition(progress: Int) {
|
||||
trackPlayer!!.seekTo(progress)
|
||||
@@ -175,17 +123,26 @@ class MusicService: Service() {
|
||||
try {
|
||||
val duration = trackPlayer!!.currentPosition / 1000
|
||||
shuffleOn = retrieveShuffleMode()
|
||||
val apiRepo = APIRepository()
|
||||
val tokenRepo = TokenRepository()
|
||||
|
||||
val token = tokenRepo.retrieveToken(appPath)
|
||||
val apiInfo = apiRepo.retrieveRecord(appPath)
|
||||
currentSong = songQueue[Random.nextInt(0, songQueue.size - 1)]
|
||||
|
||||
trackPlayer!!.reset()
|
||||
if (duration > seconds) {
|
||||
currentTrack = TrackRepository(this).getTrack(currentSongIndex!!)
|
||||
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||
trackPlayer!!.setDataSource(this,
|
||||
APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
|
||||
APIRepository.retrieveSongStreamHeader(token))
|
||||
trackPlayer!!.prepare()
|
||||
trackPlayer!!.start()
|
||||
|
||||
}
|
||||
else {
|
||||
val previousTrackNumber = fetchSongIndex(PlayTypes.PlayPreviousSong)
|
||||
currentTrack = TrackRepository(this).getTrack(previousTrackNumber)
|
||||
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||
trackPlayer!!.setDataSource(this,
|
||||
APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
|
||||
APIRepository.retrieveSongStreamHeader(token))
|
||||
trackPlayer!!.prepare()
|
||||
trackPlayer!!.start()
|
||||
}
|
||||
@@ -198,9 +155,16 @@ class MusicService: Service() {
|
||||
try {
|
||||
trackPlayer!!.reset()
|
||||
shuffleOn = retrieveShuffleMode()
|
||||
var nextTrack = fetchSongIndex(PlayTypes.PlayNextSong)
|
||||
currentTrack = TrackRepository(this).getTrack(nextTrack)
|
||||
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||
val apiRepo = APIRepository()
|
||||
val tokenRepo = TokenRepository()
|
||||
|
||||
val token = tokenRepo.retrieveToken(appPath)
|
||||
val apiInfo = apiRepo.retrieveRecord(appPath)
|
||||
currentSong = songQueue[Random.nextInt(0, songQueue.size - 1)]
|
||||
|
||||
trackPlayer!!.setDataSource(this,
|
||||
APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
|
||||
APIRepository.retrieveSongStreamHeader(token))
|
||||
trackPlayer!!.prepare()
|
||||
trackPlayer!!.start()
|
||||
}
|
||||
@@ -208,110 +172,17 @@ class MusicService: Service() {
|
||||
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
|
||||
repeatOn = controls.repeatOn
|
||||
}
|
||||
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 {
|
||||
|
||||
return currentTrack
|
||||
fun getCurrentSong(): Song {
|
||||
return currentSong
|
||||
}
|
||||
|
||||
|
||||
private fun fetchSongIndex(playType: PlayTypes): Int {
|
||||
var songIndex: Int? = currentSongIndex
|
||||
repeatOn = retrieveRepeatMode()
|
||||
if (repeatOn!!) {
|
||||
return songIndex!!
|
||||
}
|
||||
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
|
||||
}
|
||||
@@ -324,22 +195,28 @@ class MusicService: Service() {
|
||||
}
|
||||
|
||||
|
||||
fun updateLibrary() {
|
||||
checkForMusicChange()
|
||||
}
|
||||
|
||||
private fun initializeMediaPlayer() {
|
||||
try {
|
||||
if (trackPlayer == null) {
|
||||
trackPlayer = MediaPlayer()
|
||||
}
|
||||
if (trackRepositoryEmpty()!!) {
|
||||
populateTrackRepository()
|
||||
if (appPath.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
currentSongIndex = Random.nextInt(0, TrackRepository(this).getAll().count())
|
||||
currentTrack = TrackRepository(this).getTrack(currentSongIndex!!)
|
||||
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||
val trackRepo = TrackRepository()
|
||||
val apiRepo = APIRepository()
|
||||
val tokenRepo = TokenRepository()
|
||||
|
||||
val token = tokenRepo.retrieveToken(appPath)
|
||||
val apiInfo = apiRepo.retrieveRecord(appPath)
|
||||
val songs = trackRepo.fetchSongs(token, apiInfo.uri)
|
||||
songQueue = songs.toMutableList()
|
||||
|
||||
currentSong = songQueue[Random.nextInt(0, songs.size - 1)]
|
||||
trackPlayer!!.setDataSource(this,
|
||||
APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
|
||||
APIRepository.retrieveSongStreamHeader(token))
|
||||
trackPlayer!!.prepareAsync()
|
||||
trackPlayer!!.setOnCompletionListener {
|
||||
playNextTrack()
|
||||
@@ -349,46 +226,7 @@ class MusicService: Service() {
|
||||
val exMsg = ex.message
|
||||
}
|
||||
}
|
||||
private fun populateTrackRepository() {
|
||||
var mp3Paths = MusicFiles(Environment.getExternalStorageDirectory())
|
||||
mp3Paths.initialMp3Search()
|
||||
val paths = mp3Paths.allSongs
|
||||
|
||||
trackMgr = TrackManager(paths!!)
|
||||
trackMgr!!.initializeContext(this)
|
||||
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()
|
||||
@@ -422,58 +260,6 @@ 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? {
|
||||
val shuffleMode = ShuffleRepository(this).getShuffleMode()
|
||||
@@ -489,6 +275,7 @@ class MusicService: Service() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun retrieveRepeatMode(): Boolean? {
|
||||
val repeatMode = RepeatRepository(this).getRepeatMode()
|
||||
when (repeatMode) {
|
||||
@@ -503,26 +290,4 @@ class MusicService: Service() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun trackRepositoryEmpty(): Boolean? {
|
||||
val trackCount = retrieveSongCount()
|
||||
|
||||
if (trackCount!! < 1) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun retrieveSongCount(): Int? {
|
||||
|
||||
try {
|
||||
return TrackRepository(this).getAll().count()
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val exMsg = ex.message
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.example.mear.repositories
|
||||
|
||||
import android.net.Uri
|
||||
import com.example.mear.models.APIInfo
|
||||
import com.example.mear.models.Song
|
||||
import com.example.mear.models.Token
|
||||
|
||||
class APIRepository: BaseRepository() {
|
||||
|
||||
@@ -8,6 +11,22 @@ class APIRepository: BaseRepository() {
|
||||
init {
|
||||
System.loadLibrary("native-lib")
|
||||
}
|
||||
|
||||
|
||||
fun retrieveSongStreamHeader(token: Token): MutableMap<String, String> {
|
||||
val hddr: MutableMap<String, String> = mutableMapOf()
|
||||
hddr["Authorization"] = "Bearer ${token.accessToken}"
|
||||
hddr["Content-type"] = "Keep-alive"
|
||||
|
||||
return hddr
|
||||
}
|
||||
|
||||
|
||||
fun retrieveSongStreamUri(apiInfo: APIInfo, song: Song): Uri {
|
||||
val uriStr = "${apiInfo.uri}/api/v${apiInfo.version}/song/stream/${song.id}"
|
||||
|
||||
return Uri.parse(uriStr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/coordinatorLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:background="@color/color_background"
|
||||
tools:context=".activities.SongViewActivity">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/color_background"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
|
||||
<include
|
||||
android:id="@+id/include2"
|
||||
layout="@layout/content_song_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
Reference in New Issue
Block a user