added error handling

.use {} for automatic resource management with snapshots
This commit is contained in:
David Kaspar
2025-05-12 17:35:06 +02:00
parent 0192a4eb20
commit 8c1888b4d5
@@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.ui.components
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.util.Log
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.Amethyst
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@@ -37,55 +38,60 @@ object ShareHelper {
context: Context, context: Context,
imageUrl: String, imageUrl: String,
) { ) {
// get snapshot try {
val snapShot = Amethyst.instance.diskCache.openSnapshot(imageUrl) // Safely get snapshot and file
val snapshot =
Amethyst.instance.diskCache.openSnapshot(imageUrl)
?: throw IOException("Unable to open snapshot for: $imageUrl")
// get file from snapshot snapshot.use { snapshot ->
val file = snapShot?.data?.toFile() val file =
snapshot.data.toFile()
if (file != null) { // Determine file extension and prepare sharable file
// get file extension
val fileExtension = getImageExtension(file) val fileExtension = getImageExtension(file)
// copy to local file with correct extension
val fileCopy = prepareSharableImageFile(context, file, fileExtension) val fileCopy = prepareSharableImageFile(context, file, fileExtension)
// share with intent // Share the file
shareMediaFile(context, getSharableUri(context, fileCopy), "image/*") shareMediaFile(context, getSharableUri(context, fileCopy), "image/*")
} else { }
throw IOException("Image file does not exist at path: $imageUrl") } catch (e: IOException) {
Log.e("ShareHelper", "Error sharing image", e)
throw e
}
} }
// close snapshot private fun getImageExtension(file: File): String =
snapShot.close() try {
} FileInputStream(file).use { inputStream ->
private fun getImageExtension(file: File): String {
val header = ByteArray(12) val header = ByteArray(12)
FileInputStream(file).use { inputStream.read(header)
it.read(header)
}
return when { when {
// JPEG magic number: FF D8 FF // JPEG magic number: FF D8 FF
header[0] == 0xFF.toByte() && header[1] == 0xD8.toByte() -> "jpg" header.sliceArray(0..1).contentEquals(byteArrayOf(0xFF.toByte(), 0xD8.toByte())) -> "jpg"
// PNG magic number: 89 50 4E 47 // PNG magic number: 89 50 4E 47
header[0] == 0x89.toByte() && header.sliceArray(0..3).contentEquals(
header[1] == 0x50.toByte() && byteArrayOf(
header[2] == 0x4E.toByte() && 0x89.toByte(),
header[3] == 0x47.toByte() -> "png" 0x50.toByte(),
0x4E.toByte(),
0x47.toByte(),
),
) -> "png"
// WEBP magic number: "RIFF....WEBP" // WEBP magic number: "RIFF....WEBP"
header[0] == 'R'.code.toByte() && header.sliceArray(0..3).contentEquals("RIFF".toByteArray()) &&
header[1] == 'I'.code.toByte() &&
header[2] == 'F'.code.toByte() &&
header[3] == 'F'.code.toByte() &&
header.sliceArray(8..11).contentEquals("WEBP".toByteArray()) -> "webp" header.sliceArray(8..11).contentEquals("WEBP".toByteArray()) -> "webp"
else -> "jpg" // default fallback else -> "jpg" // default fallback
} }
} }
} catch (e: IOException) {
Log.w("ShareHelper", "Could not determine image type, defaulting to jpg", e)
"jpg"
}
private fun prepareSharableImageFile( private fun prepareSharableImageFile(
context: Context, context: Context,