For only with Files now

This commit is contained in:
Benoit Marty 2020-09-04 11:07:06 +02:00
parent b31178683c
commit 544bff9f4f
2 changed files with 26 additions and 48 deletions

View File

@ -21,56 +21,46 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.net.Uri
import androidx.core.content.FileProvider
import androidx.exifinterface.media.ExifInterface
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.matrix.android.sdk.internal.di.SessionDownloadsDirectory
import timber.log.Timber
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.UUID
import javax.inject.Inject
internal class ImageCompressor @Inject constructor(
@SessionDownloadsDirectory
private val sessionCacheDirectory: File
) {
private val cacheFolder = File(sessionCacheDirectory, "MF")
internal class ImageCompressor @Inject constructor() {
suspend fun compress(
context: Context,
imageUri: Uri,
imageFile: File,
desiredWidth: Int,
desiredHeight: Int,
desiredQuality: Int = 80): Uri {
desiredQuality: Int = 80): File {
return withContext(Dispatchers.IO) {
val compressedBitmap = BitmapFactory.Options().run {
inJustDecodeBounds = true
decodeBitmap(context, imageUri, this)
decodeBitmap(imageFile, this)
inSampleSize = calculateInSampleSize(outWidth, outHeight, desiredWidth, desiredHeight)
inJustDecodeBounds = false
decodeBitmap(context, imageUri, this)?.let {
rotateBitmap(context, imageUri, it)
decodeBitmap(imageFile, this)?.let {
rotateBitmap(imageFile, it)
}
} ?: return@withContext imageUri
} ?: return@withContext imageFile
val destinationUri = createDestinationUri(context)
val destinationFile = createDestinationFile(context)
runCatching {
context.contentResolver.openOutputStream(destinationUri).use {
destinationFile.outputStream().use {
compressedBitmap.compress(Bitmap.CompressFormat.JPEG, desiredQuality, it)
}
}
return@withContext destinationUri
return@withContext destinationFile
}
}
private fun rotateBitmap(context: Context, uri: Uri, bitmap: Bitmap): Bitmap {
context.contentResolver.openInputStream(uri)?.use { inputStream ->
private fun rotateBitmap(file: File, bitmap: Bitmap): Bitmap {
file.inputStream().use { inputStream ->
try {
ExifInterface(inputStream).let { exifInfo ->
val orientation = exifInfo.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
@ -94,7 +84,7 @@ internal class ImageCompressor @Inject constructor(
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
} catch (e: Exception) {
Timber.e(e, "Cannot read orientation: %s", uri.toString())
Timber.e(e, "Cannot read orientation")
}
}
return bitmap
@ -118,9 +108,9 @@ internal class ImageCompressor @Inject constructor(
return inSampleSize
}
private fun decodeBitmap(context: Context, uri: Uri, options: BitmapFactory.Options = BitmapFactory.Options()): Bitmap? {
private fun decodeBitmap(file: File, options: BitmapFactory.Options = BitmapFactory.Options()): Bitmap? {
return try {
context.contentResolver.openInputStream(uri)?.use { inputStream ->
file.inputStream().use { inputStream ->
BitmapFactory.decodeStream(inputStream, null, options)
}
} catch (e: Exception) {
@ -129,19 +119,7 @@ internal class ImageCompressor @Inject constructor(
}
}
private fun createDestinationUri(context: Context): Uri {
val file = createTempFile()
val authority = "${context.packageName}.mx-sdk.fileprovider"
return FileProvider.getUriForFile(context, authority, file)
}
private fun createTempFile(): File {
if (!cacheFolder.exists()) cacheFolder.mkdirs()
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
return File.createTempFile(
"${timeStamp}_", /* prefix */
".jpg", /* suffix */
cacheFolder /* directory */
)
private fun createDestinationFile(context: Context): File {
return File.createTempFile(UUID.randomUUID().toString(), null, context.cacheDir)
}
}

View File

@ -19,8 +19,6 @@ package org.matrix.android.sdk.internal.session.content
import android.content.Context
import android.graphics.BitmapFactory
import androidx.core.net.toFile
import androidx.core.net.toUri
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.squareup.moshi.JsonClass
@ -129,7 +127,6 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
inputStream.copyTo(it)
}
// inputStream.use {
var uploadedThumbnailUrl: String? = null
var uploadedThumbnailEncryptedFileInfo: EncryptedFileInfo? = null
@ -181,9 +178,10 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
val fileToUpload: File
if (attachment.type == ContentAttachmentData.Type.IMAGE && params.compressBeforeSending) {
fileToUpload = imageCompressor.compress(context, workingFile.toUri(), MAX_IMAGE_SIZE, MAX_IMAGE_SIZE)
.also { compressedUri ->
context.contentResolver.openInputStream(compressedUri)?.use {
fileToUpload = imageCompressor.compress(context, workingFile, MAX_IMAGE_SIZE, MAX_IMAGE_SIZE)
.also { compressedFile ->
// Get new Bitmap size
compressedFile.inputStream().use {
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
val bitmap = BitmapFactory.decodeStream(it, null, options)
val fileSize = bitmap?.byteCount ?: 0
@ -194,7 +192,9 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
)
}
}
.toFile()
// we can delete workingFile
tryThis { workingFile.delete() }
} else {
fileToUpload = workingFile
}
@ -232,7 +232,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
}
Timber.v("## FileService: cache storage updated")
} catch (failure: Throwable) {
Timber.e(failure, "## FileService: Failed to update fileservice cache")
Timber.e(failure, "## FileService: Failed to update file cache")
}
handleSuccess(params,