mirror of
https://github.com/clangen/musikcube.git
synced 2024-11-19 11:10:52 +00:00
Added a progress bar to TrackDownloadActivity.
This commit is contained in:
parent
058fd842b3
commit
4453935b9d
@ -3,6 +3,7 @@
|
||||
musikcube:
|
||||
* added lyrics support (powered by audd.io)! access lyrics for the currently
|
||||
playing song by pressing ^L.
|
||||
* removed vcredist runtime requirement on windows
|
||||
|
||||
musikdroid:
|
||||
* added a new "offline" tab to the browse screen
|
||||
@ -10,6 +11,8 @@ musikdroid:
|
||||
screen's toolbar.
|
||||
* added settings > advanced > diagnostics screen to show app runtime, wakelock
|
||||
acquisition time and status, and service status.
|
||||
* added a "download" option for song rows -- this can be used to download songs
|
||||
for ringtones, or for playback in offline players.
|
||||
* added the ability to seek playback on secondary screens
|
||||
* removed some old settings that are no longer useful
|
||||
* updated to AndroidX
|
||||
|
2
src/3rdparty/bin
vendored
2
src/3rdparty/bin
vendored
@ -1 +1 @@
|
||||
Subproject commit 31cd7109785075fc18ddb6319440c5cbb305e702
|
||||
Subproject commit f77857c24dec5e4d6d900995ed3d140088657eb6
|
@ -46,7 +46,7 @@
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:theme="@style/AppThemeNoActionBar" />
|
||||
|
||||
<activity android:name=".ui.download.activity.RingtoneActivity"
|
||||
<activity android:name=".ui.download.activity.TrackDownloadActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:theme="@style/AppThemeNoActionBar" />
|
||||
|
@ -8,6 +8,9 @@ import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@ -20,6 +23,7 @@ import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
||||
import io.casey.musikcube.remote.ui.shared.extension.*
|
||||
import me.zhanghai.android.materialprogressbar.MaterialProgressBar
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
import okhttp3.Request
|
||||
@ -27,19 +31,24 @@ import okhttp3.Response
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
class RingtoneActivity: BaseActivity() {
|
||||
class TrackDownloadActivity: BaseActivity() {
|
||||
private val httpClient = createHttpClient(Application.instance)
|
||||
private val mutex = Object()
|
||||
private var pendingCall: Call? = null
|
||||
private lateinit var spinner: MaterialProgressBar
|
||||
private lateinit var progress: MaterialProgressBar
|
||||
private val handler = Handler()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.download_ringtone_activity)
|
||||
setContentView(R.layout.track_download_activity)
|
||||
|
||||
findViewById<TextView>(R.id.title).text = getString(
|
||||
R.string.downloading_please_wait,
|
||||
intent.getStringExtra(EXTRA_TRACK_TITLE))
|
||||
progress = findViewById(R.id.progress)
|
||||
spinner = findViewById(R.id.spinner)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
findDialog<RetryDialog>(RetryDialog.TAG)?.onRetry = this::download
|
||||
@ -99,6 +108,68 @@ class RingtoneActivity: BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateProgress(percent: Int) {
|
||||
handler.post {
|
||||
if (percent > 0) {
|
||||
spinner.visibility = View.GONE
|
||||
progress.visibility = View.VISIBLE
|
||||
progress.progress = percent
|
||||
}
|
||||
else {
|
||||
spinner.visibility = View.VISIBLE
|
||||
progress.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processResponse(response: Response) {
|
||||
var success = false
|
||||
|
||||
try {
|
||||
response.body()?.let {
|
||||
val total = it.contentLength()
|
||||
var lastPercent = 0
|
||||
|
||||
updateProgress(0)
|
||||
|
||||
val onBytesReceived = { bytes: Long ->
|
||||
if (total > 0) {
|
||||
val updatedPercent = ((bytes * 100) / total).toInt()
|
||||
if (updatedPercent != lastPercent) {
|
||||
updateProgress(updatedPercent)
|
||||
lastPercent = updatedPercent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (it.byteStream().toFile(outputFilename, onBytesReceived)) {
|
||||
MediaScannerConnection.scanFile(
|
||||
this@TrackDownloadActivity,
|
||||
arrayOf(outputFilename),
|
||||
null)
|
||||
{ _, _ ->
|
||||
finish()
|
||||
}
|
||||
|
||||
success = true
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
/* move on... */
|
||||
}
|
||||
finally {
|
||||
synchronized (mutex) {
|
||||
pendingCall = null
|
||||
}
|
||||
response.close()
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
showRetryDialog()
|
||||
}
|
||||
}
|
||||
|
||||
private fun download() {
|
||||
synchronized (mutex) {
|
||||
if (pendingCall == null) {
|
||||
@ -111,34 +182,7 @@ class RingtoneActivity: BaseActivity() {
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
var success = false
|
||||
|
||||
try {
|
||||
if (response.body()?.byteStream()?.toFile(outputFilename) == true) {
|
||||
MediaScannerConnection.scanFile(
|
||||
this@RingtoneActivity,
|
||||
arrayOf(outputFilename),
|
||||
null)
|
||||
{ _, _ ->
|
||||
finish()
|
||||
}
|
||||
|
||||
success = true
|
||||
}
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
/* move on... */
|
||||
}
|
||||
finally {
|
||||
synchronized (mutex) {
|
||||
pendingCall = null
|
||||
}
|
||||
response.close()
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
showRetryDialog()
|
||||
}
|
||||
processResponse(response)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -154,7 +198,7 @@ class RingtoneActivity: BaseActivity() {
|
||||
private fun showRetryDialog() {
|
||||
if (!dialogVisible(RetryDialog.TAG)) {
|
||||
showDialog(RetryDialog.create().apply {
|
||||
onRetry = this@RingtoneActivity::download
|
||||
onRetry = this@TrackDownloadActivity::download
|
||||
}, RetryDialog.TAG)
|
||||
}
|
||||
}
|
||||
@ -233,7 +277,7 @@ class RingtoneActivity: BaseActivity() {
|
||||
private const val EXTRA_EXTENSION = "extra_extension"
|
||||
|
||||
fun getStartIntent(activity: AppCompatActivity, track: ITrack): Intent {
|
||||
return Intent(activity, RingtoneActivity::class.java).apply {
|
||||
return Intent(activity, TrackDownloadActivity::class.java).apply {
|
||||
putExtra(EXTRA_EXTERNAL_ID, track.externalId)
|
||||
putExtra(EXTRA_EXTENSION, track.uri.split(".").lastOrNull())
|
||||
putExtra(EXTRA_TRACK_TITLE, track.title)
|
@ -17,7 +17,7 @@ import io.casey.musikcube.remote.ui.category.activity.AllCategoriesActivity
|
||||
import io.casey.musikcube.remote.ui.category.activity.CategoryBrowseActivity
|
||||
import io.casey.musikcube.remote.ui.category.constant.NavigationType
|
||||
import io.casey.musikcube.remote.ui.category.fragment.CategoryBrowseFragment
|
||||
import io.casey.musikcube.remote.ui.download.activity.RingtoneActivity
|
||||
import io.casey.musikcube.remote.ui.download.activity.TrackDownloadActivity
|
||||
import io.casey.musikcube.remote.ui.home.activity.MainActivity
|
||||
import io.casey.musikcube.remote.ui.playqueue.activity.PlayQueueActivity
|
||||
import io.casey.musikcube.remote.ui.playqueue.fragment.PlayQueueFragment
|
||||
@ -240,7 +240,7 @@ object Navigate {
|
||||
*/
|
||||
|
||||
fun toDownloadRingtone(track: ITrack, activity: AppCompatActivity) =
|
||||
activity.startActivity(RingtoneActivity.getStartIntent(activity, track))
|
||||
activity.startActivity(TrackDownloadActivity.getStartIntent(activity, track))
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -505,19 +505,27 @@ fun createHttpClient(context: Context): OkHttpClient {
|
||||
*
|
||||
*/
|
||||
|
||||
fun InputStream.toFile(path: String): Boolean {
|
||||
fun InputStream.toFile(path: String, progress: ((Long) -> Unit)? = null): Boolean {
|
||||
try {
|
||||
File(path).parentFile.mkdirs()
|
||||
File(path).delete()
|
||||
FileOutputStream(path, false).use { out ->
|
||||
val reader = BufferedInputStream(this)
|
||||
val buffer = ByteArray(4096)
|
||||
var iterations = 0
|
||||
var count: Int
|
||||
var total = 0L
|
||||
do {
|
||||
count = reader.read(buffer)
|
||||
total += count
|
||||
if (count > 0) {
|
||||
out.write(buffer)
|
||||
}
|
||||
++iterations
|
||||
/* post progress every ~(4096 * 25 = 102400) bytes */
|
||||
if (iterations % 25 == 0) {
|
||||
progress?.invoke(total)
|
||||
}
|
||||
} while (count > 0)
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@ -20,9 +20,23 @@
|
||||
android:text="@string/downloading_please_wait"/>
|
||||
|
||||
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
|
||||
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
|
||||
android:id="@+id/progress"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="12dp"
|
||||
android:indeterminate="false"
|
||||
android:progress="25"
|
||||
android:max="100"
|
||||
app:mpb_progressStyle="horizontal"
|
||||
app:mpb_useIntrinsicPadding="false" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
Loading…
Reference in New Issue
Block a user