fixed some bugs caused by new download update
This commit is contained in:
parent
35e1b8b4dc
commit
e20e3dcfd3
|
@ -52,7 +52,7 @@ android {
|
||||||
targetSdk = 33
|
targetSdk = 33
|
||||||
|
|
||||||
versionCode = 59
|
versionCode = 59
|
||||||
versionName = "4.1.4"
|
versionName = "4.1.5"
|
||||||
|
|
||||||
resValue("string", "app_version", "${defaultConfig.versionName}${versionNameSuffix ?: ""}")
|
resValue("string", "app_version", "${defaultConfig.versionName}${versionNameSuffix ?: ""}")
|
||||||
resValue("string", "commit_hash", "git rev-parse --short HEAD".execute() ?: "")
|
resValue("string", "commit_hash", "git rev-parse --short HEAD".execute() ?: "")
|
||||||
|
|
|
@ -7,6 +7,7 @@ import androidx.work.ForegroundInfo
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
||||||
import com.lagradost.cloudstream3.utils.VideoDownloadManager.WORK_KEY_INFO
|
import com.lagradost.cloudstream3.utils.VideoDownloadManager.WORK_KEY_INFO
|
||||||
|
@ -25,15 +26,16 @@ class DownloadFileWorkManager(val context: Context, private val workerParams: Wo
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
val key = workerParams.inputData.getString("key")
|
val key = workerParams.inputData.getString("key")
|
||||||
try {
|
try {
|
||||||
println("KEY $key")
|
|
||||||
if (key == DOWNLOAD_CHECK) {
|
if (key == DOWNLOAD_CHECK) {
|
||||||
downloadCheck(applicationContext, ::handleNotification)?.let {
|
downloadCheck(applicationContext, ::handleNotification)
|
||||||
awaitDownload(it)
|
|
||||||
}
|
|
||||||
} else if (key != null) {
|
} else if (key != null) {
|
||||||
val info = applicationContext.getKey<VideoDownloadManager.DownloadInfo>(WORK_KEY_INFO, key)
|
val info =
|
||||||
|
applicationContext.getKey<VideoDownloadManager.DownloadInfo>(WORK_KEY_INFO, key)
|
||||||
val pkg =
|
val pkg =
|
||||||
applicationContext.getKey<VideoDownloadManager.DownloadResumePackage>(WORK_KEY_PACKAGE, key)
|
applicationContext.getKey<VideoDownloadManager.DownloadResumePackage>(
|
||||||
|
WORK_KEY_PACKAGE,
|
||||||
|
key
|
||||||
|
)
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
downloadEpisode(
|
downloadEpisode(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
|
@ -43,10 +45,8 @@ class DownloadFileWorkManager(val context: Context, private val workerParams: Wo
|
||||||
info.links,
|
info.links,
|
||||||
::handleNotification
|
::handleNotification
|
||||||
)
|
)
|
||||||
awaitDownload(info.ep.id)
|
|
||||||
} else if (pkg != null) {
|
} else if (pkg != null) {
|
||||||
downloadFromResume(applicationContext, pkg, ::handleNotification)
|
downloadFromResume(applicationContext, pkg, ::handleNotification)
|
||||||
awaitDownload(pkg.item.ep.id)
|
|
||||||
}
|
}
|
||||||
removeKeys(key)
|
removeKeys(key)
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ class DownloadFileWorkManager(val context: Context, private val workerParams: Wo
|
||||||
VideoDownloadManager.DownloadType.IsDone, VideoDownloadManager.DownloadType.IsFailed, VideoDownloadManager.DownloadType.IsStopped -> {
|
VideoDownloadManager.DownloadType.IsDone, VideoDownloadManager.DownloadType.IsFailed, VideoDownloadManager.DownloadType.IsStopped -> {
|
||||||
isDone = true
|
isDone = true
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.hippo.unifile.UniFile
|
||||||
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||||
|
import com.lagradost.cloudstream3.BuildConfig
|
||||||
import com.lagradost.cloudstream3.MainActivity
|
import com.lagradost.cloudstream3.MainActivity
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.TvType
|
import com.lagradost.cloudstream3.TvType
|
||||||
|
@ -723,7 +724,7 @@ object VideoDownloadManager {
|
||||||
var hlsTotal: Int? = null,
|
var hlsTotal: Int? = null,
|
||||||
// this is how many segments that has been written to the file
|
// this is how many segments that has been written to the file
|
||||||
// will always be <= hlsProgress as we may keep some in a buffer
|
// will always be <= hlsProgress as we may keep some in a buffer
|
||||||
var hlsWrittenProgress: Long = 0,
|
var hlsWrittenProgress: Int = 0,
|
||||||
|
|
||||||
// this is used for copy with metadata on how much we have downloaded for setKey
|
// this is used for copy with metadata on how much we have downloaded for setKey
|
||||||
private var downloadFileInfoTemplate: DownloadedFileInfo? = null
|
private var downloadFileInfoTemplate: DownloadedFileInfo? = null
|
||||||
|
@ -798,6 +799,15 @@ object VideoDownloadManager {
|
||||||
notify()
|
notify()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onDelete() {
|
||||||
|
bytesDownloaded = 0
|
||||||
|
hlsWrittenProgress = 0
|
||||||
|
hlsProgress = 0
|
||||||
|
|
||||||
|
//internalType = DownloadType.IsStopped
|
||||||
|
notify()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val UPDATE_RATE_MS: Long = 1000L
|
const val UPDATE_RATE_MS: Long = 1000L
|
||||||
}
|
}
|
||||||
|
@ -842,6 +852,9 @@ object VideoDownloadManager {
|
||||||
}
|
}
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
logError(t)
|
logError(t)
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
throw t
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +879,7 @@ object VideoDownloadManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setWrittenSegment(segmentIndex: Int) {
|
fun setWrittenSegment(segmentIndex: Int) {
|
||||||
hlsWrittenProgress = segmentIndex.toLong() + 1L
|
hlsWrittenProgress = segmentIndex + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,16 +929,18 @@ object VideoDownloadManager {
|
||||||
// set up a connection
|
// set up a connection
|
||||||
val request = app.get(
|
val request = app.get(
|
||||||
link.url.replace(" ", "%20"),
|
link.url.replace(" ", "%20"),
|
||||||
headers = link.headers + mapOf(
|
headers = link.headers.appendAndDontOverride(
|
||||||
"Accept-Encoding" to "identity",
|
mapOf(
|
||||||
"accept" to "*/*",
|
"Accept-Encoding" to "identity",
|
||||||
"user-agent" to USER_AGENT,
|
"accept" to "*/*",
|
||||||
"sec-ch-ua" to "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"",
|
"user-agent" to USER_AGENT,
|
||||||
"sec-fetch-mode" to "navigate",
|
"sec-ch-ua" to "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"",
|
||||||
"sec-fetch-dest" to "video",
|
"sec-fetch-mode" to "navigate",
|
||||||
"sec-fetch-user" to "?1",
|
"sec-fetch-dest" to "video",
|
||||||
"sec-ch-ua-mobile" to "?0",
|
"sec-fetch-user" to "?1",
|
||||||
) + if (resumeAt > 0) mapOf("Range" to "bytes=${resumeAt}-") else emptyMap(),
|
"sec-ch-ua-mobile" to "?0",
|
||||||
|
) + if (resumeAt > 0) mapOf("Range" to "bytes=${resumeAt}-") else emptyMap()
|
||||||
|
),
|
||||||
referer = link.referer,
|
referer = link.referer,
|
||||||
verify = false
|
verify = false
|
||||||
)
|
)
|
||||||
|
@ -964,14 +979,14 @@ object VideoDownloadManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata.type == DownloadType.IsStopped) {
|
if (metadata.type == DownloadType.IsStopped) {
|
||||||
return@withContext delete(
|
// we need to close before delete
|
||||||
context,
|
fileStream.closeQuietly()
|
||||||
name,
|
metadata.onDelete()
|
||||||
relativePath,
|
if (deleteFile(context, baseFile, relativePath ?: "", displayName)) {
|
||||||
extension,
|
return@withContext SUCCESS_STOPPED
|
||||||
parentId,
|
} else {
|
||||||
baseFile
|
return@withContext ERROR_DELETING_FILE
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.type = DownloadType.IsDone
|
metadata.type = DownloadType.IsDone
|
||||||
|
@ -995,6 +1010,18 @@ object VideoDownloadManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Helper function to make sure duplicate attributes don't get overriden or inserted without lowercase cmp
|
||||||
|
* example: map("a" to 1) appendAndDontOverride map("A" to 2, "a" to 3, "c" to 4) = map("a" to 1, "c" to 4)
|
||||||
|
* */
|
||||||
|
private fun <V> Map<String, V>.appendAndDontOverride(rhs: Map<String, V>): Map<String, V> {
|
||||||
|
val out = this.toMutableMap()
|
||||||
|
val current = this.keys.map { it.lowercase() }
|
||||||
|
for ((key, value) in rhs) {
|
||||||
|
if (current.contains(key.lowercase())) continue
|
||||||
|
out[key] = value
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
private suspend fun downloadHLS(
|
private suspend fun downloadHLS(
|
||||||
|
@ -1047,11 +1074,13 @@ object VideoDownloadManager {
|
||||||
|
|
||||||
// do the initial get request to fetch the segments
|
// do the initial get request to fetch the segments
|
||||||
val m3u8 = M3u8Helper.M3u8Stream(
|
val m3u8 = M3u8Helper.M3u8Stream(
|
||||||
link.url, link.quality, mapOf(
|
link.url, link.quality, link.headers.appendAndDontOverride(
|
||||||
"Accept-Encoding" to "identity",
|
mapOf(
|
||||||
"accept" to "*/*",
|
"Accept-Encoding" to "identity",
|
||||||
"user-agent" to USER_AGENT,
|
"accept" to "*/*",
|
||||||
) + if (link.referer.isNotBlank()) mapOf("referer" to link.referer) else emptyMap()
|
"user-agent" to USER_AGENT,
|
||||||
|
) + if (link.referer.isNotBlank()) mapOf("referer" to link.referer) else emptyMap()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
val items = M3u8Helper2.hslLazy(listOf(m3u8))
|
val items = M3u8Helper2.hslLazy(listOf(m3u8))
|
||||||
|
|
||||||
|
@ -1081,14 +1110,14 @@ object VideoDownloadManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata.type == DownloadType.IsStopped) {
|
if (metadata.type == DownloadType.IsStopped) {
|
||||||
return@withContext delete(
|
// we need to close before delete
|
||||||
context,
|
fileStream.closeQuietly()
|
||||||
name,
|
metadata.onDelete()
|
||||||
relativePath,
|
if (deleteFile(context, baseFile, relativePath ?: "", displayName)) {
|
||||||
extension,
|
return@withContext SUCCESS_STOPPED
|
||||||
parentId,
|
} else {
|
||||||
baseFile
|
return@withContext ERROR_DELETING_FILE
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.type = DownloadType.IsDone
|
metadata.type = DownloadType.IsDone
|
||||||
|
@ -1194,7 +1223,7 @@ object VideoDownloadManager {
|
||||||
return (Environment.DIRECTORY_DOWNLOADS + '/' + folder + '/').replace(
|
return (Environment.DIRECTORY_DOWNLOADS + '/' + folder + '/').replace(
|
||||||
'/',
|
'/',
|
||||||
File.separatorChar
|
File.separatorChar
|
||||||
)
|
).replace("${File.separatorChar}${File.separatorChar}", File.separatorChar.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1224,7 +1253,7 @@ object VideoDownloadManager {
|
||||||
return this != null && this.filePath == getDownloadDir()?.filePath
|
return this != null && this.filePath == getDownloadDir()?.filePath
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun delete(
|
/*private fun delete(
|
||||||
context: Context,
|
context: Context,
|
||||||
name: String,
|
name: String,
|
||||||
folder: String?,
|
folder: String?,
|
||||||
|
@ -1235,7 +1264,7 @@ object VideoDownloadManager {
|
||||||
val displayName = getDisplayName(name, extension)
|
val displayName = getDisplayName(name, extension)
|
||||||
|
|
||||||
// delete all subtitle files
|
// delete all subtitle files
|
||||||
if (extension == "mp4") {
|
if (extension != "vtt" && extension != "srt") {
|
||||||
try {
|
try {
|
||||||
delete(context, name, folder, "vtt", parentId, basePath)
|
delete(context, name, folder, "vtt", parentId, basePath)
|
||||||
delete(context, name, folder, "srt", parentId, basePath)
|
delete(context, name, folder, "srt", parentId, basePath)
|
||||||
|
@ -1248,9 +1277,9 @@ object VideoDownloadManager {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && basePath.isDownloadDir()) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && basePath.isDownloadDir()) {
|
||||||
val relativePath = getRelativePath(folder)
|
val relativePath = getRelativePath(folder)
|
||||||
val lastContent =
|
val lastContent =
|
||||||
context.contentResolver.getExistingDownloadUriOrNullQ(relativePath, displayName)
|
context.contentResolver.getExistingDownloadUriOrNullQ(relativePath, displayName) ?: return ERROR_DELETING_FILE
|
||||||
if (lastContent != null) {
|
if(context.contentResolver.delete(lastContent, null, null) <= 0) {
|
||||||
context.contentResolver.delete(lastContent, null, null)
|
return ERROR_DELETING_FILE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val dir = basePath?.gotoDir(folder)
|
val dir = basePath?.gotoDir(folder)
|
||||||
|
@ -1260,13 +1289,12 @@ object VideoDownloadManager {
|
||||||
// Cleans up empty directory
|
// Cleans up empty directory
|
||||||
if (dir.listFiles()?.isEmpty() == true) dir.delete()
|
if (dir.listFiles()?.isEmpty() == true) dir.delete()
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
parentId?.let {
|
parentId?.let {
|
||||||
downloadDeleteEvent.invoke(parentId)
|
downloadDeleteEvent.invoke(parentId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SUCCESS_STOPPED
|
return SUCCESS_STOPPED
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
fun getFileName(context: Context, metadata: DownloadEpisodeMetadata): String {
|
fun getFileName(context: Context, metadata: DownloadEpisodeMetadata): String {
|
||||||
|
@ -1377,71 +1405,71 @@ object VideoDownloadManager {
|
||||||
|
|
||||||
suspend fun downloadCheck(
|
suspend fun downloadCheck(
|
||||||
context: Context, notificationCallback: (Int, Notification) -> Unit,
|
context: Context, notificationCallback: (Int, Notification) -> Unit,
|
||||||
): Int? {
|
) {
|
||||||
if (currentDownloads.size < maxConcurrentDownloads && downloadQueue.size > 0) {
|
if (!(currentDownloads.size < maxConcurrentDownloads && downloadQueue.size > 0)) return
|
||||||
val pkg = downloadQueue.removeFirst()
|
|
||||||
val item = pkg.item
|
|
||||||
val id = item.ep.id
|
|
||||||
if (currentDownloads.contains(id)) { // IF IT IS ALREADY DOWNLOADING, RESUME IT
|
|
||||||
downloadEvent.invoke(Pair(id, DownloadActionType.Resume))
|
|
||||||
/** ID needs to be returned to the work-manager to properly await notification */
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
currentDownloads.add(id)
|
val pkg = downloadQueue.removeFirst()
|
||||||
|
val item = pkg.item
|
||||||
try {
|
val id = item.ep.id
|
||||||
for (index in (pkg.linkIndex ?: 0) until item.links.size) {
|
if (currentDownloads.contains(id)) { // IF IT IS ALREADY DOWNLOADING, RESUME IT
|
||||||
val link = item.links[index]
|
downloadEvent.invoke(Pair(id, DownloadActionType.Resume))
|
||||||
val resume = pkg.linkIndex == index
|
/** ID needs to be returned to the work-manager to properly await notification */
|
||||||
|
// return id
|
||||||
setKey(
|
|
||||||
KEY_RESUME_PACKAGES,
|
|
||||||
id.toString(),
|
|
||||||
DownloadResumePackage(item, index)
|
|
||||||
)
|
|
||||||
|
|
||||||
var connectionResult =
|
|
||||||
downloadSingleEpisode(
|
|
||||||
context,
|
|
||||||
item.source,
|
|
||||||
item.folder,
|
|
||||||
item.ep,
|
|
||||||
link,
|
|
||||||
notificationCallback,
|
|
||||||
resume
|
|
||||||
)
|
|
||||||
//.also { println("Single episode finished with return code: $it") }
|
|
||||||
|
|
||||||
// retry every link at least once
|
|
||||||
if (connectionResult <= 0) {
|
|
||||||
connectionResult = downloadSingleEpisode(
|
|
||||||
context,
|
|
||||||
item.source,
|
|
||||||
item.folder,
|
|
||||||
item.ep,
|
|
||||||
link,
|
|
||||||
notificationCallback,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionResult > 0) { // SUCCESS
|
|
||||||
removeKey(KEY_RESUME_PACKAGES, id.toString())
|
|
||||||
break
|
|
||||||
} else if (index == item.links.lastIndex) {
|
|
||||||
downloadStatusEvent.invoke(Pair(id, DownloadType.IsFailed))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logError(e)
|
|
||||||
} finally {
|
|
||||||
currentDownloads.remove(id)
|
|
||||||
// Because otherwise notifications will not get caught by the work manager
|
|
||||||
downloadCheckUsingWorker(context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
|
currentDownloads.add(id)
|
||||||
|
try {
|
||||||
|
for (index in (pkg.linkIndex ?: 0) until item.links.size) {
|
||||||
|
val link = item.links[index]
|
||||||
|
val resume = pkg.linkIndex == index
|
||||||
|
|
||||||
|
setKey(
|
||||||
|
KEY_RESUME_PACKAGES,
|
||||||
|
id.toString(),
|
||||||
|
DownloadResumePackage(item, index)
|
||||||
|
)
|
||||||
|
|
||||||
|
var connectionResult =
|
||||||
|
downloadSingleEpisode(
|
||||||
|
context,
|
||||||
|
item.source,
|
||||||
|
item.folder,
|
||||||
|
item.ep,
|
||||||
|
link,
|
||||||
|
notificationCallback,
|
||||||
|
resume
|
||||||
|
)
|
||||||
|
//.also { println("Single episode finished with return code: $it") }
|
||||||
|
|
||||||
|
// retry every link at least once
|
||||||
|
if (connectionResult <= 0) {
|
||||||
|
connectionResult = downloadSingleEpisode(
|
||||||
|
context,
|
||||||
|
item.source,
|
||||||
|
item.folder,
|
||||||
|
item.ep,
|
||||||
|
link,
|
||||||
|
notificationCallback,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectionResult > 0) { // SUCCESS
|
||||||
|
removeKey(KEY_RESUME_PACKAGES, id.toString())
|
||||||
|
break
|
||||||
|
} else if (index == item.links.lastIndex) {
|
||||||
|
downloadStatusEvent.invoke(Pair(id, DownloadType.IsFailed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logError(e)
|
||||||
|
} finally {
|
||||||
|
currentDownloads.remove(id)
|
||||||
|
// Because otherwise notifications will not get caught by the work manager
|
||||||
|
downloadCheckUsingWorker(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return id
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDownloadFileInfoAndUpdateSettings(context: Context, id: Int): DownloadedFileInfoResult? {
|
fun getDownloadFileInfoAndUpdateSettings(context: Context, id: Int): DownloadedFileInfoResult? {
|
||||||
|
@ -1500,23 +1528,21 @@ object VideoDownloadManager {
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteFile(context: Context, id: Int): Boolean {
|
private fun deleteFile(
|
||||||
val info =
|
context: Context,
|
||||||
context.getKey<DownloadedFileInfo>(KEY_DOWNLOAD_INFO, id.toString()) ?: return false
|
folder: UniFile?,
|
||||||
downloadEvent.invoke(Pair(id, DownloadActionType.Stop))
|
relativePath: String,
|
||||||
downloadProgressEvent.invoke(Triple(id, 0, 0))
|
displayName: String
|
||||||
downloadStatusEvent.invoke(Pair(id, DownloadType.IsStopped))
|
): Boolean {
|
||||||
downloadDeleteEvent.invoke(id)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && folder.isDownloadDir()) {
|
||||||
val base = basePathToFile(context, info.basePath)
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && base.isDownloadDir()) {
|
|
||||||
val cr = context.contentResolver ?: return false
|
val cr = context.contentResolver ?: return false
|
||||||
val fileUri =
|
val fileUri =
|
||||||
cr.getExistingDownloadUriOrNullQ(info.relativePath, info.displayName)
|
cr.getExistingDownloadUriOrNullQ(relativePath, displayName)
|
||||||
?: return true // FILE NOT FOUND, ALREADY DELETED
|
?: return true // FILE NOT FOUND, ALREADY DELETED
|
||||||
|
|
||||||
return cr.delete(fileUri, null, null) > 0 // IF DELETED ROWS IS OVER 0
|
return cr.delete(fileUri, null, null) > 0 // IF DELETED ROWS IS OVER 0
|
||||||
} else {
|
} else {
|
||||||
val file = base?.gotoDir(info.relativePath)?.findFile(info.displayName)
|
val file = folder?.gotoDir(relativePath)?.findFile(displayName)
|
||||||
// val normalPath = context.getNormalPath(getFile(info.relativePath), info.displayName)
|
// val normalPath = context.getNormalPath(getFile(info.relativePath), info.displayName)
|
||||||
// val dFile = File(normalPath)
|
// val dFile = File(normalPath)
|
||||||
if (file?.exists() != true) return true
|
if (file?.exists() != true) return true
|
||||||
|
@ -1530,6 +1556,17 @@ object VideoDownloadManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun deleteFile(context: Context, id: Int): Boolean {
|
||||||
|
val info =
|
||||||
|
context.getKey<DownloadedFileInfo>(KEY_DOWNLOAD_INFO, id.toString()) ?: return false
|
||||||
|
downloadEvent.invoke(Pair(id, DownloadActionType.Stop))
|
||||||
|
downloadProgressEvent.invoke(Triple(id, 0, 0))
|
||||||
|
downloadStatusEvent.invoke(id to DownloadType.IsStopped)
|
||||||
|
downloadDeleteEvent.invoke(id)
|
||||||
|
val base = basePathToFile(context, info.basePath)
|
||||||
|
return deleteFile(context, base, info.relativePath, info.displayName)
|
||||||
|
}
|
||||||
|
|
||||||
fun getDownloadResumePackage(context: Context, id: Int): DownloadResumePackage? {
|
fun getDownloadResumePackage(context: Context, id: Int): DownloadResumePackage? {
|
||||||
return context.getKey(KEY_RESUME_PACKAGES, id.toString())
|
return context.getKey(KEY_RESUME_PACKAGES, id.toString())
|
||||||
}
|
}
|
||||||
|
@ -1544,10 +1581,12 @@ object VideoDownloadManager {
|
||||||
downloadQueue.addLast(pkg)
|
downloadQueue.addLast(pkg)
|
||||||
downloadCheck(context, notificationCallback)
|
downloadCheck(context, notificationCallback)
|
||||||
if (setKey) saveQueue()
|
if (setKey) saveQueue()
|
||||||
|
//ret
|
||||||
} else {
|
} else {
|
||||||
downloadEvent.invoke(
|
downloadEvent(
|
||||||
Pair(pkg.item.ep.id, DownloadActionType.Resume)
|
Pair(pkg.item.ep.id, DownloadActionType.Resume)
|
||||||
)
|
)
|
||||||
|
//null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue