Downloading songs in the background is now in effect!
This commit is contained in:
+2
-1
@@ -30,7 +30,7 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</facet>
|
</facet>
|
||||||
<facet type="kotlin-language" name="Kotlin">
|
<facet type="kotlin-language" name="Kotlin">
|
||||||
<configuration version="3" platform="JVM 1.6" allPlatforms="JVM [1.6]" useProjectSettings="false">
|
<configuration version="3" platform="JVM 1.8" allPlatforms="JVM [1.8]" useProjectSettings="false">
|
||||||
<compilerSettings />
|
<compilerSettings />
|
||||||
<compilerArguments>
|
<compilerArguments>
|
||||||
<option name="destination" value="$MODULE_DIR$/build/tmp/kotlin-classes/debug" />
|
<option name="destination" value="$MODULE_DIR$/build/tmp/kotlin-classes/debug" />
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
<option name="noStdlib" value="true" />
|
<option name="noStdlib" value="true" />
|
||||||
<option name="noReflect" value="true" />
|
<option name="noReflect" value="true" />
|
||||||
<option name="moduleName" value="app_debug" />
|
<option name="moduleName" value="app_debug" />
|
||||||
|
<option name="jvmTarget" value="1.8" />
|
||||||
<option name="languageVersion" value="1.3" />
|
<option name="languageVersion" value="1.3" />
|
||||||
<option name="apiVersion" value="1.3" />
|
<option name="apiVersion" value="1.3" />
|
||||||
<option name="pluginOptions">
|
<option name="pluginOptions">
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ android {
|
|||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||||
|
}
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
path "src/main/cpp/CMakeLists.txt"
|
path "src/main/cpp/CMakeLists.txt"
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import android.content.ComponentName
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class LoginActivity : BaseServiceActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
window.statusBarColor = resources.getColor(R.color.track_seek)
|
||||||
setContentView(R.layout.activity_login)
|
setContentView(R.layout.activity_login)
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
|
|
||||||
|
|||||||
@@ -11,25 +11,19 @@ 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.Intent
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.PopupMenu
|
import android.widget.PopupMenu
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
/**
|
import androidx.lifecycle.Observer
|
||||||
import androidx.work.Data
|
import androidx.work.Data
|
||||||
import androidx.work.NetworkType
|
import androidx.work.NetworkType
|
||||||
import androidx.work.OneTimeWorkRequest
|
import androidx.work.OneTimeWorkRequest
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
*/
|
|
||||||
import org.jetbrains.anko.image
|
import org.jetbrains.anko.image
|
||||||
import org.jetbrains.anko.imageBitmap
|
import org.jetbrains.anko.imageBitmap
|
||||||
|
|
||||||
@@ -39,18 +33,14 @@ import com.example.mear.repositories.*
|
|||||||
import com.example.mear.repositories.RepeatRepository.RepeatTypes
|
import com.example.mear.repositories.RepeatRepository.RepeatTypes
|
||||||
import com.example.mear.repositories.ShuffleRepository.ShuffleTypes
|
import com.example.mear.repositories.ShuffleRepository.ShuffleTypes
|
||||||
import com.example.mear.util.ConvertByteArray
|
import com.example.mear.util.ConvertByteArray
|
||||||
// import com.example.mear.workers.IcarusSyncManager
|
import com.example.mear.workers.IcarusSyncManager
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : BaseServiceActivity() {
|
class MainActivity : BaseServiceActivity() {
|
||||||
|
|
||||||
private val ctx: Context? = this
|
|
||||||
private var coverArtHandler: Handler? = Handler()
|
|
||||||
private var musicHandler: Handler? = Handler()
|
private var musicHandler: Handler? = Handler()
|
||||||
private var updateLibraryHandler: Handler? = Handler()
|
|
||||||
private var playCountUpdated: Boolean? = false
|
private var playCountUpdated: Boolean? = false
|
||||||
private var serviceBinded: Boolean? = false
|
private var serviceBinded: Boolean? = false
|
||||||
private var metadataInitialized: Boolean = false
|
|
||||||
private var repeatOn: Boolean? = false
|
private var repeatOn: Boolean? = false
|
||||||
private var shuffleOn: Boolean? = false
|
private var shuffleOn: Boolean? = false
|
||||||
|
|
||||||
@@ -58,18 +48,6 @@ class MainActivity : BaseServiceActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
try {
|
try {
|
||||||
/**
|
|
||||||
val workManager = WorkManager.getInstance()
|
|
||||||
|
|
||||||
val constraints = androidx.work.Constraints.Builder()
|
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED).build()
|
|
||||||
|
|
||||||
val task = OneTimeWorkRequest.Builder(IcarusSyncManager::class.java)
|
|
||||||
.setConstraints(constraints).build()
|
|
||||||
workManager.enqueue(task)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
|
|
||||||
@@ -354,22 +332,6 @@ class MainActivity : BaseServiceActivity() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
|
||||||
|
|
||||||
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
|
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ActivityCompat.requestPermissions(this,
|
|
||||||
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showPopup(view: View) {
|
private fun showPopup(view: View) {
|
||||||
try {
|
try {
|
||||||
@@ -390,12 +352,9 @@ class MainActivity : BaseServiceActivity() {
|
|||||||
startActivity(Intent(this, IcarusSongActivity::class.java))
|
startActivity(Intent(this, IcarusSongActivity::class.java))
|
||||||
}
|
}
|
||||||
R.id.action_song_delete -> {
|
R.id.action_song_delete -> {
|
||||||
// TODO: handle song deletion
|
|
||||||
val ss = true
|
|
||||||
val appPath = appDirectory()
|
val appPath = appDirectory()
|
||||||
val trackRepo = TrackRepository()
|
val trackRepo = TrackRepository()
|
||||||
// The method I am calling has not been implemented on the C++
|
|
||||||
// side
|
|
||||||
var currSong = musicService!!.getCurrentSong()
|
var currSong = musicService!!.getCurrentSong()
|
||||||
Toast.makeText(this, "Deleting song", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Deleting song", Toast.LENGTH_SHORT).show()
|
||||||
val result = trackRepo.delete(currSong, appPath)
|
val result = trackRepo.delete(currSong, appPath)
|
||||||
@@ -405,46 +364,49 @@ class MainActivity : BaseServiceActivity() {
|
|||||||
}
|
}
|
||||||
R.id.action_song_download -> {
|
R.id.action_song_download -> {
|
||||||
val appPath = appDirectory()
|
val appPath = appDirectory()
|
||||||
val apiRepo = APIRepository()
|
|
||||||
val tokenRepo = TokenRepository()
|
|
||||||
val trackRepo = TrackRepository()
|
|
||||||
var song = musicService!!.getCurrentSong()
|
var song = musicService!!.getCurrentSong()
|
||||||
|
|
||||||
val token = tokenRepo.retrieveToken(appPath)
|
|
||||||
// val apiInfo = apiRepo.retrieveRecord(appPath)
|
|
||||||
// song = trackRepo.download(token, song, appPath)
|
|
||||||
// musicService!!.changeSongDownloadStatus(song)
|
|
||||||
// TODO: implement something to include the downloaded song into the songQueue
|
|
||||||
// essentially replacing the song that already exists, that way one can
|
|
||||||
// actually access the file without having to restart the app
|
|
||||||
Toast.makeText(this, "Downloading song", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Downloading song", Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
// val dMgr = IcarusSyncManager
|
|
||||||
musicService!!.downloadSong(token, song, appPath)
|
|
||||||
|
|
||||||
|
|
||||||
//val workManager = WorkManager.getInstance()
|
|
||||||
/**
|
|
||||||
val constraints = androidx.work.Constraints.Builder()
|
val constraints = androidx.work.Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED).build()
|
.setRequiredNetworkType(NetworkType.CONNECTED).build()
|
||||||
|
|
||||||
val task = OneTimeWorkRequest.Builder(IcarusSyncManager::class.java)
|
|
||||||
.setConstraints(constraints)
|
|
||||||
val data = Data.Builder()
|
val data = Data.Builder()
|
||||||
data.putString("accessToken", token.accessToken)
|
|
||||||
data.putString("appPath", appPath)
|
data.putString("appPath", appPath)
|
||||||
|
|
||||||
data.putInt("songId", song.id)
|
data.putInt("songId", song.id)
|
||||||
task.setInputData(data.build())
|
data.putString("songTitle", song.title)
|
||||||
*/
|
data.putString("songArtist", song.artist)
|
||||||
//workManager.enqueue(task)
|
data.putString("songAlbum", song.album)
|
||||||
//WorkManager.getInstance().enqueue(task.build())
|
data.putString("songAlbumArtist", song.albumArtist)
|
||||||
|
data.putString("songGenre", song.genre)
|
||||||
|
data.putInt("songYear", song.year)
|
||||||
|
data.putInt("songDuration", song.duration)
|
||||||
|
data.putInt("songCoverArtId", song.coverArtId)
|
||||||
|
data.putBoolean("songDownloaded", false)
|
||||||
|
data.putInt("songDisc", song.disc)
|
||||||
|
data.putInt("songTrack", song.track)
|
||||||
|
|
||||||
|
val task = OneTimeWorkRequest.Builder(IcarusSyncManager::class.java)
|
||||||
|
.setInputData(data.build())
|
||||||
|
.setConstraints(constraints)
|
||||||
|
.build()
|
||||||
|
WorkManager.getInstance().enqueue(task)
|
||||||
|
|
||||||
|
WorkManager.getInstance(this).getWorkInfoByIdLiveData(task.id)
|
||||||
|
.observe(this, Observer { info ->
|
||||||
|
if (info != null && info.state.isFinished) {
|
||||||
|
song.path = info.outputData.getString("songPath")!!
|
||||||
|
song.filename = info.outputData.getString("songFilename")!!
|
||||||
|
song.downloaded = info.outputData.getBoolean("songDownloaded", true)!!
|
||||||
|
musicService!!.changeSongDownloadStatus(song)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
R.id.action_song_play_count-> {
|
R.id.action_song_play_count-> {
|
||||||
// TODO: not implemented
|
// TODO: not implemented
|
||||||
val trk = musicService!!.getCurrentSong()
|
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()
|
Toast.makeText(this, "Song played $playCount times", Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class MusicService(var appPath: String = ""): Service() {
|
|||||||
try {
|
try {
|
||||||
trackPlayer!!.reset()
|
trackPlayer!!.reset()
|
||||||
trackPlayer!!.setDataSource(this, uri, hddr)
|
trackPlayer!!.setDataSource(this, uri, hddr)
|
||||||
trackPlayer!!.prepareAsync()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.start()
|
||||||
}
|
}
|
||||||
catch (ex: Exception) {
|
catch (ex: Exception) {
|
||||||
@@ -102,14 +102,13 @@ class MusicService(var appPath: String = ""): Service() {
|
|||||||
currentSong = song
|
currentSong = song
|
||||||
currentSongIndex = songQueue.indexOfFirst { it.id == currentSong.id }
|
currentSongIndex = songQueue.indexOfFirst { it.id == currentSong.id }
|
||||||
songQueue[currentSongIndex!!] = currentSong
|
songQueue[currentSongIndex!!] = currentSong
|
||||||
/**
|
|
||||||
val curPosition = currentPositionOfTrack()
|
val curPosition = currentPositionOfTrack()
|
||||||
trackPlayer!!.reset()
|
trackPlayer!!.reset()
|
||||||
trackPlayer!!.setDataSource(currentSong.path)
|
trackPlayer!!.setDataSource(currentSong.path)
|
||||||
trackPlayer!!.prepareAsync()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.seekTo(curPosition)
|
trackPlayer!!.seekTo(curPosition)
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.start()
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeSongDownloadStatus(song: Song) {
|
fun removeSongDownloadStatus(song: Song) {
|
||||||
@@ -179,7 +178,7 @@ class MusicService(var appPath: String = ""): Service() {
|
|||||||
uri, hddr)
|
uri, hddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
trackPlayer!!.prepareAsync()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +215,7 @@ class MusicService(var appPath: String = ""): Service() {
|
|||||||
APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
|
APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
|
||||||
APIRepository.retrieveSongStreamHeader(token))
|
APIRepository.retrieveSongStreamHeader(token))
|
||||||
}
|
}
|
||||||
trackPlayer!!.prepareAsync()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.start()
|
||||||
}
|
}
|
||||||
catch (ex: Exception) {
|
catch (ex: Exception) {
|
||||||
@@ -266,7 +265,7 @@ class MusicService(var appPath: String = ""): Service() {
|
|||||||
APIRepository.retrieveSongStreamHeader(token))
|
APIRepository.retrieveSongStreamHeader(token))
|
||||||
}
|
}
|
||||||
|
|
||||||
trackPlayer!!.prepareAsync()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.setOnCompletionListener {
|
trackPlayer!!.setOnCompletionListener {
|
||||||
playNextTrack()
|
playNextTrack()
|
||||||
}
|
}
|
||||||
@@ -302,7 +301,7 @@ class MusicService(var appPath: String = ""): Service() {
|
|||||||
|
|
||||||
trackPlayer!!.reset()
|
trackPlayer!!.reset()
|
||||||
trackPlayer!!.setDataSource(song.path)
|
trackPlayer!!.setDataSource(song.path)
|
||||||
trackPlayer!!.prepareAsync()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.start()
|
||||||
}
|
}
|
||||||
catch (ex: Exception) {
|
catch (ex: Exception) {
|
||||||
|
|||||||
@@ -1,21 +1,46 @@
|
|||||||
package com.example.mear.workers
|
package com.example.mear.workers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.work.Data
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
|
||||||
|
import com.example.mear.models.Song
|
||||||
|
import com.example.mear.repositories.TokenRepository
|
||||||
|
import com.example.mear.repositories.TrackRepository
|
||||||
|
|
||||||
class IcarusSyncManager(context: Context, workerParams: WorkerParameters) :
|
class IcarusSyncManager(context: Context, workerParams: WorkerParameters) :
|
||||||
Worker(context, workerParams) {
|
Worker(context, workerParams) {
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
//TODO perform your async operational task here
|
val appPath: String = inputData.getString("appPath")!!
|
||||||
/**
|
val songId = inputData.getInt("songId", 0)
|
||||||
* We have performed download task here on above example
|
if (songId == 0) {
|
||||||
*/
|
return Result.failure()
|
||||||
val accessToken = inputData.getString("accessToken")
|
}
|
||||||
val appPath = inputData.getString("appPath")
|
|
||||||
//val songId = inputData.getInt("songId")
|
|
||||||
|
|
||||||
return Result.success()
|
val tokenRepo = TokenRepository()
|
||||||
|
val trackRepo = TrackRepository()
|
||||||
|
val tok = tokenRepo.retrieveToken(appPath)
|
||||||
|
val song = Song()
|
||||||
|
song.id = songId
|
||||||
|
song.title = inputData.getString("songTitle")!!
|
||||||
|
song.artist = inputData.getString("songArtist")!!
|
||||||
|
song.album = inputData.getString("songAlbum")!!
|
||||||
|
song.albumArtist = inputData.getString("songAlbumArtist")!!
|
||||||
|
song.genre = inputData.getString("songGenre")!!
|
||||||
|
song.year = inputData.getInt("songYear", 0)
|
||||||
|
song.duration = inputData.getInt("songDuration", 0)
|
||||||
|
song.coverArtId = inputData.getInt("songCoverArtId", 0)
|
||||||
|
song.disc = inputData.getInt("songDisc", 0)
|
||||||
|
song.track = inputData.getInt("songTrack", 0)
|
||||||
|
|
||||||
|
val downloadedSong = trackRepo.download(tok, song, appPath)
|
||||||
|
|
||||||
|
val output: Data = workDataOf("songPath" to downloadedSong.path,
|
||||||
|
"songFilename" to downloadedSong.filename,
|
||||||
|
"songDownloaded" to true)
|
||||||
|
|
||||||
|
return Result.success(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user