Fix storage getting full while moving multiple items to the recycle bin at once
This commit is contained in:
parent
07fb21a775
commit
9f152ea01d
|
@ -656,9 +656,10 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
|
|||
val pathsToDelete = ArrayList<String>()
|
||||
itemsToDelete.mapTo(pathsToDelete) { it.path }
|
||||
|
||||
movePathsInRecycleBin(pathsToDelete) {
|
||||
if (it) {
|
||||
deleteFilteredFileDirItems(itemsToDelete, folders)
|
||||
movePathsInRecycleBin(pathsToDelete) { wasSuccess, range ->
|
||||
if (wasSuccess) {
|
||||
val itemsInRange = itemsToDelete.subList(range.first, range.second)
|
||||
deleteFilteredFileDirItems(ArrayList(itemsInRange), ArrayList())
|
||||
} else {
|
||||
toast(R.string.unknown_error_occurred)
|
||||
}
|
||||
|
|
|
@ -887,9 +887,10 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
|
|||
val movingItems = resources.getQuantityString(R.plurals.moving_items_into_bin, filtered.size, filtered.size)
|
||||
toast(movingItems)
|
||||
|
||||
movePathsInRecycleBin(filtered.map { it.path } as ArrayList<String>) {
|
||||
if (it) {
|
||||
deleteFilteredFiles(filtered)
|
||||
movePathsInRecycleBin(filtered.map { it.path } as ArrayList<String>) { wasSuccess, range ->
|
||||
if (wasSuccess) {
|
||||
val itemsInRange = filtered.subList(range.first, range.second)
|
||||
deleteFilteredFiles(ArrayList(itemsInRange))
|
||||
} else {
|
||||
toast(R.string.unknown_error_occurred)
|
||||
}
|
||||
|
|
|
@ -267,9 +267,10 @@ class SearchActivity : SimpleActivity(), MediaOperationsListener {
|
|||
val movingItems = resources.getQuantityString(R.plurals.moving_items_into_bin, filtered.size, filtered.size)
|
||||
toast(movingItems)
|
||||
|
||||
movePathsInRecycleBin(filtered.map { it.path } as ArrayList<String>) {
|
||||
if (it) {
|
||||
deleteFilteredFiles(filtered)
|
||||
movePathsInRecycleBin(filtered.map { it.path } as ArrayList<String>) { wasSuccess, range ->
|
||||
if (wasSuccess) {
|
||||
val itemsInRange = filtered.subList(range.first, range.second)
|
||||
deleteFilteredFiles(ArrayList(itemsInRange))
|
||||
} else {
|
||||
toast(R.string.unknown_error_occurred)
|
||||
}
|
||||
|
|
|
@ -1161,8 +1161,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
|||
onPageSelected(0)
|
||||
}
|
||||
|
||||
movePathsInRecycleBin(arrayListOf(path)) {
|
||||
if (it) {
|
||||
movePathsInRecycleBin(arrayListOf(path)) { wasSuccess, _ ->
|
||||
if (wasSuccess) {
|
||||
tryDeleteFileDirItem(fileDirItem, false, false) {
|
||||
mIgnoredPaths.remove(fileDirItem.path)
|
||||
if (media.isEmpty()) {
|
||||
|
|
|
@ -44,6 +44,7 @@ import com.squareup.picasso.Picasso
|
|||
import java.io.*
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
fun Activity.sharePath(path: String) {
|
||||
sharePathIntent(path, BuildConfig.APPLICATION_ID)
|
||||
|
@ -313,18 +314,45 @@ fun BaseSimpleActivity.tryDeleteFileDirItem(
|
|||
}
|
||||
}
|
||||
|
||||
fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, callback: ((wasSuccess: Boolean) -> Unit)?) {
|
||||
fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, callback: ((wasSuccess: Boolean, movedRange: Pair<Int, Int>) -> Unit)?) {
|
||||
ensureBackgroundThread {
|
||||
var pathsCnt = paths.size
|
||||
val OTGPath = config.OTGPath
|
||||
|
||||
for (source in paths) {
|
||||
var availableSize = getAvailableInternalMemorySize().toLong()
|
||||
|
||||
// If available size is more than 200MB, keep a safe distance from
|
||||
// exceeding the remaining size
|
||||
if (availableSize > 1024 * 1024 * 200)
|
||||
availableSize -= 1024 * 1024 * 50
|
||||
var totalCopiedSize = 0L
|
||||
|
||||
var lastDeletedIndex = -1
|
||||
val ensureSizeIsAvailable = { index: Int, size: Long ->
|
||||
// Try to delete already moved files if space if not sufficient
|
||||
if (size <= availableSize && totalCopiedSize > 0 && totalCopiedSize + size > availableSize) {
|
||||
// Return true in wasSuccess for now, callback will be called
|
||||
// at the end of the function with the correct parameter
|
||||
callback?.invoke(true, Pair(lastDeletedIndex + 1, index + 1))
|
||||
availableSize = getAvailableInternalMemorySize()
|
||||
totalCopiedSize = 0L
|
||||
lastDeletedIndex = index
|
||||
}
|
||||
|
||||
size <= availableSize
|
||||
}
|
||||
|
||||
for ((index, source) in paths.withIndex()) {
|
||||
if (OTGPath.isNotEmpty() && source.startsWith(OTGPath)) {
|
||||
var inputStream: InputStream? = null
|
||||
var out: OutputStream? = null
|
||||
try {
|
||||
val destination = "$recycleBinPath/$source"
|
||||
val fileDocument = getSomeDocumentFile(source)
|
||||
val originalSize = fileDocument?.getItemSize(true)!!
|
||||
if (!ensureSizeIsAvailable(index, originalSize))
|
||||
continue
|
||||
|
||||
inputStream = applicationContext.contentResolver.openInputStream(fileDocument?.uri!!)
|
||||
out = getFileOutputStreamSync(destination, source.getMimeType())
|
||||
|
||||
|
@ -339,9 +367,11 @@ fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, callback:
|
|||
|
||||
out?.flush()
|
||||
|
||||
if (fileDocument.getItemSize(true) == copiedSize && getDoesFilePathExist(destination)) {
|
||||
if (originalSize == copiedSize && getDoesFilePathExist(destination)) {
|
||||
mediaDB.updateDeleted("$RECYCLE_BIN$source", System.currentTimeMillis(), source)
|
||||
pathsCnt--
|
||||
|
||||
totalCopiedSize += copiedSize
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
|
@ -352,6 +382,10 @@ fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, callback:
|
|||
}
|
||||
} else {
|
||||
val file = File(source)
|
||||
val originalSize = file.length()
|
||||
if (!ensureSizeIsAvailable(index, originalSize))
|
||||
continue
|
||||
|
||||
val internalFile = File(recycleBinPath, source)
|
||||
val lastModified = file.lastModified()
|
||||
try {
|
||||
|
@ -362,6 +396,8 @@ fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, callback:
|
|||
if (config.keepLastModified && lastModified != 0L) {
|
||||
internalFile.setLastModified(lastModified)
|
||||
}
|
||||
|
||||
totalCopiedSize += originalSize
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
|
@ -369,7 +405,7 @@ fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, callback:
|
|||
}
|
||||
}
|
||||
}
|
||||
callback?.invoke(pathsCnt == 0)
|
||||
callback?.invoke(pathsCnt == 0, Pair(lastDeletedIndex + 1, paths.size))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@ import android.database.Cursor
|
|||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.PictureDrawable
|
||||
import android.media.AudioManager
|
||||
import android.os.Environment
|
||||
import android.os.Process
|
||||
import android.os.StatFs
|
||||
import android.provider.MediaStore.Files
|
||||
import android.provider.MediaStore.Images
|
||||
import android.widget.ImageView
|
||||
|
@ -43,6 +45,7 @@ import java.nio.ByteBuffer
|
|||
import java.nio.channels.FileChannel
|
||||
import kotlin.collections.set
|
||||
|
||||
|
||||
val Context.audioManager get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
|
||||
fun Context.getHumanizedFilename(path: String): String {
|
||||
|
@ -1103,3 +1106,12 @@ fun Context.getFileDateTaken(path: String): Long {
|
|||
|
||||
return 0L
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/8133417/android-get-free-size-of-internal-external-memory
|
||||
fun Context.getAvailableInternalMemorySize(): Long {
|
||||
val path: File = filesDir
|
||||
val stat = StatFs(path.path)
|
||||
val blockSize = stat.blockSizeLong
|
||||
val availableBlocks = stat.availableBlocksLong
|
||||
return availableBlocks * blockSize
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue