diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt index 08db3a06..143b48d7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt @@ -5,6 +5,7 @@ import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent +import android.content.ContentResolver import android.content.ContentValues import android.content.Context import android.content.Intent @@ -17,6 +18,7 @@ import android.net.Uri import android.os.Handler import android.os.Looper import android.provider.ContactsContract.PhoneLookup +import android.provider.OpenableColumns import android.provider.Telephony.* import android.text.TextUtils import androidx.core.app.NotificationCompat @@ -35,6 +37,7 @@ import com.simplemobiletools.smsmessenger.interfaces.MessagesDao import com.simplemobiletools.smsmessenger.models.* import com.simplemobiletools.smsmessenger.receivers.DirectReplyReceiver import com.simplemobiletools.smsmessenger.receivers.MarkAsReadReceiver +import java.io.FileNotFoundException import java.util.* import kotlin.collections.ArrayList import me.leolin.shortcutbadger.ShortcutBadger @@ -788,3 +791,38 @@ fun Context.updateLastConversationMessage(threadId: Long) { } catch (e: Exception) { } } + +fun Context.getFileSizeFromUri(uri:Uri): Long { + val assetFileDescriptor = try { + contentResolver.openAssetFileDescriptor(uri, "r") + } catch (e: FileNotFoundException) { + null + } + + // uses ParcelFileDescriptor#getStatSize underneath if failed + val length = assetFileDescriptor?.use { it.length } ?: FILE_SIZE_NONE + if (length != -1L) { + return length + } + + // if "content://" uri scheme, try contentResolver table + if (uri.scheme.equals(ContentResolver.SCHEME_CONTENT)) { + return contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null) + ?.use { cursor -> + // maybe shouldn't trust ContentResolver for size: + // https://stackoverflow.com/questions/48302972/content-resolver-returns-wrong-size + val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE) + if (sizeIndex == -1) { + return@use FILE_SIZE_NONE + } + cursor.moveToFirst() + return try { + cursor.getLong(sizeIndex) + } catch (_: Throwable) { + FILE_SIZE_NONE + } + } ?: FILE_SIZE_NONE + } else { + return FILE_SIZE_NONE + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt index 50523678..aa58387e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt @@ -11,6 +11,7 @@ import com.simplemobiletools.commons.extensions.getMyFileUri import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.smsmessenger.extensions.extension import com.simplemobiletools.smsmessenger.extensions.getExtensionFromMimeType +import com.simplemobiletools.smsmessenger.extensions.getFileSizeFromUri import com.simplemobiletools.smsmessenger.extensions.isImageMimeType import java.io.File import java.io.FileOutputStream @@ -20,7 +21,6 @@ import java.io.FileOutputStream * [Compressor](https://github.com/zetbaitsu/Compressor/) * */ class ImageCompressor(private val context: Context) { - private val contentResolver = context.contentResolver private val outputDirectory = File(context.cacheDir, "compressed").apply { if (!exists()) { @@ -31,18 +31,24 @@ class ImageCompressor(private val context: Context) { fun compressImage(uri: Uri, compressSize: Long, callback: (compressedFileUri: Uri?) -> Unit) { ensureBackgroundThread { try { - val mimeType = contentResolver.getType(uri)!! - if (mimeType.isImageMimeType()) { - val byteArray = contentResolver.openInputStream(uri)?.readBytes()!! - var destinationFile = File(outputDirectory, System.currentTimeMillis().toString().plus(mimeType.getExtensionFromMimeType())) - destinationFile.writeBytes(byteArray) - val constraint = SizeConstraint(compressSize) - while (constraint.isSatisfied(destinationFile).not()) { - destinationFile = constraint.satisfy(destinationFile) + val fileSize = context.getFileSizeFromUri(uri) + if (fileSize > compressSize) { + val mimeType = contentResolver.getType(uri)!! + if (mimeType.isImageMimeType()) { + val byteArray = contentResolver.openInputStream(uri)?.readBytes()!! + var destinationFile = File(outputDirectory, System.currentTimeMillis().toString().plus(mimeType.getExtensionFromMimeType())) + destinationFile.writeBytes(byteArray) + val constraint = SizeConstraint(compressSize) + while (constraint.isSatisfied(destinationFile).not()) { + destinationFile = constraint.satisfy(destinationFile) + } + callback.invoke(context.getMyFileUri(destinationFile)) + } else { + callback.invoke(null) } - callback.invoke(context.getMyFileUri(destinationFile)) } else { - callback.invoke(null) + //no need to compress since the file is less than the compress size + callback.invoke(uri) } } catch (e: Exception) { callback.invoke(null)