Don't include empty dirs in media backup
Otherwise, the directories would be treated as small files and we would try to backup their content which would fail.
diff --git a/storage/lib/src/main/java/org/calyxos/backup/storage/backup/Backup.kt b/storage/lib/src/main/java/org/calyxos/backup/storage/backup/Backup.kt
index e08d538..d1451f2 100644
--- a/storage/lib/src/main/java/org/calyxos/backup/storage/backup/Backup.kt
+++ b/storage/lib/src/main/java/org/calyxos/backup/storage/backup/Backup.kt
@@ -22,7 +22,6 @@
import java.io.IOException
import java.security.GeneralSecurityException
import kotlin.time.Duration
-import kotlin.time.ExperimentalTime
internal class BackupResult(
val chunkIds: Set<String>,
@@ -86,7 +85,6 @@
)
@Throws(IOException::class, GeneralSecurityException::class)
- @OptIn(ExperimentalTime::class)
suspend fun runBackup(backupObserver: BackupObserver?) {
backupObserver?.onStartScanning()
var duration: Duration? = null
@@ -121,7 +119,6 @@
}
@Throws(IOException::class, GeneralSecurityException::class)
- @OptIn(ExperimentalTime::class)
private suspend fun backupFiles(
filesResult: FileScannerResult,
availableChunkIds: HashSet<String>,
diff --git a/storage/lib/src/main/java/org/calyxos/backup/storage/scanner/MediaScanner.kt b/storage/lib/src/main/java/org/calyxos/backup/storage/scanner/MediaScanner.kt
index 0e0c352..c2ece36 100644
--- a/storage/lib/src/main/java/org/calyxos/backup/storage/scanner/MediaScanner.kt
+++ b/storage/lib/src/main/java/org/calyxos/backup/storage/scanner/MediaScanner.kt
@@ -12,6 +12,7 @@
import android.net.Uri
import android.os.Bundle
import android.os.Environment
+import android.provider.DocumentsContract.Document.MIME_TYPE_DIR
import android.provider.MediaStore
import android.provider.MediaStore.MediaColumns.IS_DOWNLOAD
import android.util.Log
@@ -57,15 +58,18 @@
internal fun scanMediaUri(uri: Uri, extraQuery: String? = null): List<MediaFile> {
val extras = Bundle().apply {
- val query = StringBuilder()
+ val query = StringBuilder().apply {
+ // don't include directories (if they are non-empty they will be in implicitly)
+ append("${MediaStore.MediaColumns.MIME_TYPE}!='$MIME_TYPE_DIR'")
+ }
if (uri != MediaType.Downloads.contentUri) {
- query.append("$IS_DOWNLOAD=0")
+ query.append(" AND $IS_DOWNLOAD=0")
}
extraQuery?.let {
- if (query.isNotEmpty()) query.append(" AND ")
+ query.append(" AND ")
query.append(it)
}
- if (query.isNotEmpty()) putString(QUERY_ARG_SQL_SELECTION, query.toString())
+ putString(QUERY_ARG_SQL_SELECTION, query.toString())
}
val cursor = contentResolver.query(uri, PROJECTION, extras, null)
return ArrayList<MediaFile>(cursor?.count ?: 0).apply {
@@ -106,7 +110,6 @@
}
private fun getRealSize(mediaFile: MediaFile): Long {
- @Suppress("DEPRECATION")
val extDir = Environment.getExternalStorageDirectory()
val path = "$extDir/${mediaFile.dirPath}/${mediaFile.fileName}"
return try {