Merge pull request #1252 from Bnyro/master

fix and cleanup downloads
This commit is contained in:
Bnyro 2022-09-10 12:23:36 +02:00 committed by GitHub
commit 34bd2a8173
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 142 additions and 49 deletions

View File

@ -13,6 +13,7 @@ import com.github.libretube.constants.IntentData
import com.github.libretube.databinding.ActivityOfflinePlayerBinding
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.extensions.BaseActivity
import com.github.libretube.util.DownloadHelper
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.source.MergingMediaSource
@ -69,20 +70,13 @@ class OfflinePlayerActivity : BaseActivity() {
}
private fun playVideo() {
val videoDownloadDir = File(
getExternalFilesDir(null),
"video"
)
val videoDownloadDir = DownloadHelper.getVideoDir(this)
val videoFile = File(
videoDownloadDir,
fileName
)
val audioDownloadDir = File(
getExternalFilesDir(null),
"audio"
)
val audioDownloadDir = DownloadHelper.getAudioDir(this)
val audioFile = File(
audioDownloadDir,
fileName
@ -129,6 +123,7 @@ class OfflinePlayerActivity : BaseActivity() {
}
}
@Suppress("DEPRECATION")
private fun hideSystemBars() {
window?.decorView?.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE

View File

@ -9,11 +9,12 @@ import com.github.libretube.R
import com.github.libretube.activities.OfflinePlayerActivity
import com.github.libretube.constants.IntentData
import com.github.libretube.databinding.DownloadedMediaRowBinding
import com.github.libretube.obj.DownloadedFile
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.File
class DownloadsAdapter(
private val files: MutableList<File>
private val files: MutableList<DownloadedFile>
) : RecyclerView.Adapter<DownloadsViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DownloadsViewHolder {
val binding = DownloadedMediaRowBinding.inflate(
@ -29,7 +30,7 @@ class DownloadsAdapter(
val file = files[position]
holder.binding.apply {
fileName.text = file.name
fileSize.text = "${file.length() / (1024 * 1024)} MiB"
fileSize.text = "${file.size / (1024 * 1024)} MiB"
root.setOnClickListener {
val intent = Intent(root.context, OfflinePlayerActivity::class.java).also {

View File

@ -4,11 +4,13 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.size
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.adapters.DownloadsAdapter
import com.github.libretube.databinding.FragmentDownloadsBinding
import com.github.libretube.extensions.BaseFragment
import java.io.File
import com.github.libretube.util.DownloadHelper
class DownloadsFragment : BaseFragment() {
private lateinit var binding: FragmentDownloadsBinding
@ -25,14 +27,26 @@ class DownloadsFragment : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val downloadDir = File(
context?.getExternalFilesDir(null),
"video"
)
val files = DownloadHelper.getDownloadedFiles(requireContext())
if (files.isEmpty()) return
binding.downloadsEmpty.visibility = View.GONE
binding.downloads.visibility = View.VISIBLE
binding.downloads.layoutManager = LinearLayoutManager(context)
binding.downloads.adapter = DownloadsAdapter(
downloadDir.listFiles()?.toMutableList() ?: mutableListOf()
binding.downloads.adapter = DownloadsAdapter(files)
binding.downloads.adapter?.registerAdapterDataObserver(
object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
if (binding.downloads.size == 0) {
binding.downloads.visibility = View.GONE
binding.downloadsEmpty.visibility = View.VISIBLE
}
super.onChanged()
}
}
)
}
}

View File

@ -0,0 +1,7 @@
package com.github.libretube.obj
data class DownloadedFile(
val name: String,
val size: Long,
val type: Int
)

View File

@ -7,7 +7,6 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
@ -19,6 +18,7 @@ import com.github.libretube.constants.DOWNLOAD_FAILURE_NOTIFICATION_ID
import com.github.libretube.constants.DOWNLOAD_SUCCESS_NOTIFICATION_ID
import com.github.libretube.constants.DownloadType
import com.github.libretube.extensions.TAG
import com.github.libretube.util.DownloadHelper
import java.io.File
class DownloadService : Service() {
@ -28,8 +28,6 @@ class DownloadService : Service() {
private lateinit var audioUrl: String
private var downloadType: Int = 3
private lateinit var videoDownloadDir: File
private lateinit var audioDownloadDir: File
private var videoDownloadId: Long? = null
private var audioDownloadId: Long? = null
@ -64,19 +62,14 @@ class DownloadService : Service() {
}
private fun downloadManager() {
videoDownloadDir = File(
this.getExternalFilesDir(null),
"video"
)
// initialize and create the directories to download into
if (!videoDownloadDir.exists()) videoDownloadDir.mkdirs()
val videoDownloadDir = DownloadHelper.getVideoDir(this)
val audioDownloadDir = DownloadHelper.getAudioDir(this)
audioDownloadDir = File(
this.getExternalFilesDir(null),
"audio"
)
if (!audioDownloadDir.exists()) audioDownloadDir.mkdirs()
listOf(videoDownloadDir, audioDownloadDir).forEach {
if (!it.exists()) it.mkdir()
}
// start download
try {
@ -113,9 +106,13 @@ class DownloadService : Service() {
private val onDownloadComplete: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// Fetching the download id received with the broadcast
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
// Checking if the received broadcast is for our enqueued download by matching download id
when (id) {
when (
intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID,
-1
)
) {
videoDownloadId -> videoDownloadId = null
audioDownloadId -> audioDownloadId = null
}
@ -147,13 +144,13 @@ class DownloadService : Service() {
}
private fun downloadFailedNotification() {
val builder = NotificationCompat.Builder(this@DownloadService, DOWNLOAD_CHANNEL_ID)
val builder = NotificationCompat.Builder(this, DOWNLOAD_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_download)
.setContentTitle(resources.getString(R.string.downloadfailed))
.setContentText(getString(R.string.fail))
.setPriority(NotificationCompat.PRIORITY_HIGH)
with(NotificationManagerCompat.from(this@DownloadService)) {
with(NotificationManagerCompat.from(this)) {
// notificationId is a unique int for each notification that you must define
notify(DOWNLOAD_FAILURE_NOTIFICATION_ID, builder.build())
}
@ -161,13 +158,13 @@ class DownloadService : Service() {
private fun downloadSucceededNotification() {
Log.i(TAG(), "Download succeeded")
val builder = NotificationCompat.Builder(this@DownloadService, DOWNLOAD_CHANNEL_ID)
val builder = NotificationCompat.Builder(this, DOWNLOAD_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_download)
.setContentTitle(resources.getString(R.string.success))
.setContentText(getString(R.string.downloadsucceeded))
.setPriority(NotificationCompat.PRIORITY_HIGH)
with(NotificationManagerCompat.from(this@DownloadService)) {
with(NotificationManagerCompat.from(this)) {
// notificationId is a unique int for each notification that you must define
notify(DOWNLOAD_SUCCESS_NOTIFICATION_ID, builder.build())
}
@ -181,14 +178,7 @@ class DownloadService : Service() {
Globals.IS_DOWNLOAD_RUNNING = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
stopForeground(STOP_FOREGROUND_REMOVE)
} else {
@Suppress("DEPRECATION")
stopForeground(true)
}
stopService(Intent(this@DownloadService, DownloadService::class.java))
stopService(Intent(this, DownloadService::class.java))
super.onDestroy()
}
}

View File

@ -0,0 +1,62 @@
package com.github.libretube.util
import android.content.Context
import com.github.libretube.constants.DownloadType
import com.github.libretube.obj.DownloadedFile
import java.io.File
object DownloadHelper {
private fun getOfflineStorageDir(context: Context): File {
return context.getExternalFilesDir(null)!!
}
fun getVideoDir(context: Context): File {
return File(
getOfflineStorageDir(context),
"video"
)
}
fun getAudioDir(context: Context): File {
return File(
getOfflineStorageDir(context),
"audio"
)
}
fun getDownloadedFiles(context: Context): MutableList<DownloadedFile> {
val videoFiles = getVideoDir(context).listFiles()
val audioFiles = getAudioDir(context).listFiles()?.toMutableList()
val files = mutableListOf<DownloadedFile>()
videoFiles?.forEach {
var type = DownloadType.VIDEO
audioFiles?.forEach { audioFile ->
if (audioFile.name == it.name) {
type = DownloadType.AUDIO_VIDEO
audioFiles.remove(audioFile)
}
}
files.add(
DownloadedFile(
name = it.name,
size = it.length(),
type = type
)
)
}
audioFiles?.forEach {
files.add(
DownloadedFile(
name = it.name,
size = it.length(),
type = DownloadType.AUDIO
)
)
}
return files
}
}

View File

@ -1,12 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="?android:attr/colorBackground">
<LinearLayout
android:id="@+id/downloads_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginBottom="16dp"
android:src="@drawable/ic_download" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:gravity="center"
android:text="@string/emptyList"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/downloads"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:visibility="gone" />
</LinearLayout>
</FrameLayout>