Overwrite saved images instead of creating new ones (#8162)

* Implementing overwrite instead of saving duplicated images

* Using filename instead of hardcoding image type

* Refactoring method to accept lambda for default value

* Removing extra parenthesis
This commit is contained in:
Platiplus 2022-10-11 09:20:30 -03:00 committed by GitHub
parent fba244423f
commit a3afb35539
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,12 +1,14 @@
package eu.kanade.tachiyomi.data.saver package eu.kanade.tachiyomi.data.saver
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Environment import android.os.Environment
import android.provider.MediaStore import android.provider.MediaStore
import androidx.annotation.RequiresApi
import androidx.core.content.contentValuesOf import androidx.core.content.contentValuesOf
import androidx.core.net.toUri import androidx.core.net.toUri
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -40,18 +42,21 @@ class ImageSaver(
val pictureDir = val pictureDir =
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY) MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val folderRelativePath = "${Environment.DIRECTORY_PICTURES}/${context.getString(R.string.app_name)}/"
val imageLocation = (image.location as Location.Pictures).relativePath
val contentValues = contentValuesOf( val contentValues = contentValuesOf(
MediaStore.Images.Media.DISPLAY_NAME to image.name, MediaStore.Images.Media.DISPLAY_NAME to image.name,
MediaStore.Images.Media.MIME_TYPE to type.mime, MediaStore.Images.Media.MIME_TYPE to type.mime,
MediaStore.Images.Media.RELATIVE_PATH to MediaStore.Images.Media.RELATIVE_PATH to folderRelativePath + imageLocation,
"${Environment.DIRECTORY_PICTURES}/${context.getString(R.string.app_name)}/" +
(image.location as Location.Pictures).relativePath,
) )
val picture = context.contentResolver.insert( val picture = findUriOrDefault(folderRelativePath, "$imageLocation$filename") {
context.contentResolver.insert(
pictureDir, pictureDir,
contentValues, contentValues,
) ?: throw IOException(context.getString(R.string.error_saving_picture)) ) ?: throw IOException(context.getString(R.string.error_saving_picture))
}
try { try {
data().use { input -> data().use { input ->
@ -85,6 +90,37 @@ class ImageSaver(
return destFile.getUriCompat(context) return destFile.getUriCompat(context)
} }
@RequiresApi(Build.VERSION_CODES.Q)
private fun findUriOrDefault(relativePath: String, imagePath: String, default: () -> Uri): Uri {
val projection = arrayOf(
MediaStore.MediaColumns._ID,
MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.Images.Media.MIME_TYPE,
MediaStore.MediaColumns.RELATIVE_PATH,
MediaStore.MediaColumns.DATE_MODIFIED,
)
val selection = "${MediaStore.MediaColumns.RELATIVE_PATH}='$relativePath' AND " +
"${MediaStore.MediaColumns.DISPLAY_NAME}='$imagePath'"
context.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
null,
null,
).use { cursor ->
if (cursor != null && cursor.count >= 1) {
cursor.moveToFirst().let {
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
return ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
}
}
}
return default()
}
} }
sealed class Image( sealed class Image(