diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58ab976f..3193a1ca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,14 @@
Changelog
==========
+Version 5.10.1 *(2021-09-16)*
+----------------------------
+
+ * Automatically resize sent MMS image attachments by default, allow customizing the limit
+ * Added Draft support
+ * Allow marking conversations un/read from the main screen
+ * Some other stability, UX and translation improvements
+
Version 5.10.0 *(2021-08-27)*
----------------------------
diff --git a/app/build.gradle b/app/build.gradle
index 0844aa10..ab02e588 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -16,8 +16,8 @@ android {
applicationId "com.simplemobiletools.smsmessenger"
minSdkVersion 22
targetSdkVersion 30
- versionCode 35
- versionName "5.10.0"
+ versionCode 36
+ versionName "5.10.1"
setProperty("archivesBaseName", "sms-messenger")
}
@@ -56,7 +56,7 @@ android {
}
dependencies {
- implementation 'com.github.SimpleMobileTools:Simple-Commons:8979ca8187'
+ implementation 'com.github.SimpleMobileTools:Simple-Commons:f49f7b5f89'
implementation 'org.greenrobot:eventbus:3.2.0'
implementation 'com.klinkerapps:android-smsmms:5.2.6'
implementation 'com.github.tibbi:IndicatorFastScroll:c3de1d040a'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a40d3d85..ea66d25e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -195,6 +195,16 @@
+
+
+
+
()
private var messages = ArrayList()
private val availableSIMCards = ArrayList()
- private var attachmentUris = LinkedHashSet()
+ private var attachmentSelections = mutableMapOf()
+ private val imageCompressor by lazy { ImageCompressor(this) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -119,7 +122,7 @@ class ThreadActivity : SimpleActivity() {
override fun onPause() {
super.onPause()
- if (thread_type_message.value != "" && attachmentUris.isEmpty()) {
+ if (thread_type_message.value != "" && attachmentSelections.isEmpty()) {
saveSmsDraft(thread_type_message.value, threadId)
} else {
deleteSmsDraft(threadId)
@@ -390,7 +393,10 @@ class ThreadActivity : SimpleActivity() {
private fun setupParticipants() {
if (participants.isEmpty()) {
participants = if (messages.isEmpty()) {
- getThreadParticipants(threadId, null)
+ val intentNumbers = getPhoneNumbersFromIntent()
+ val participants = getThreadParticipants(threadId, null)
+
+ fixParticipantNumbers(participants, intentNumbers)
} else {
messages.first().participants
}
@@ -583,7 +589,7 @@ class ThreadActivity : SimpleActivity() {
conversationsDB.markRead(threadId)
}
- if (i == cnt - 1 && (message.type == Telephony.Sms.MESSAGE_TYPE_SENT )) {
+ if (i == cnt - 1 && (message.type == Telephony.Sms.MESSAGE_TYPE_SENT)) {
items.add(ThreadSent(message.id, delivered = message.status == Telephony.Sms.STATUS_COMPLETE))
}
}
@@ -606,29 +612,57 @@ class ThreadActivity : SimpleActivity() {
}
private fun addAttachment(uri: Uri) {
- if (attachmentUris.contains(uri)) {
+ val originalUriString = uri.toString()
+ if (attachmentSelections.containsKey(originalUriString)) {
return
}
- attachmentUris.add(uri)
+ attachmentSelections[originalUriString] = AttachmentSelection(uri, false)
+ val attachmentView = addAttachmentView(originalUriString, uri)
+ val mimeType = contentResolver.getType(uri) ?: return
+
+ if (mimeType.isImageMimeType() && config.mmsFileSizeLimit != FILE_SIZE_NONE) {
+ val selection = attachmentSelections[originalUriString]
+ attachmentSelections[originalUriString] = selection!!.copy(isPending = true)
+ checkSendMessageAvailability()
+ attachmentView.thread_attachment_progress.beVisible()
+ imageCompressor.compressImage(uri, config.mmsFileSizeLimit) { compressedUri ->
+ runOnUiThread {
+ if (compressedUri != null) {
+ attachmentSelections[originalUriString] = AttachmentSelection(compressedUri, false)
+ loadAttachmentPreview(attachmentView, compressedUri)
+ }
+ checkSendMessageAvailability()
+ attachmentView.thread_attachment_progress.beGone()
+ }
+ }
+ }
+ }
+
+ private fun addAttachmentView(originalUri: String, uri: Uri): View {
thread_attachments_holder.beVisible()
val attachmentView = layoutInflater.inflate(R.layout.item_attachment, null).apply {
thread_attachments_wrapper.addView(this)
thread_remove_attachment.setOnClickListener {
thread_attachments_wrapper.removeView(this)
- attachmentUris.remove(uri)
- if (attachmentUris.isEmpty()) {
+ attachmentSelections.remove(originalUri)
+ if (attachmentSelections.isEmpty()) {
thread_attachments_holder.beGone()
}
}
}
+ loadAttachmentPreview(attachmentView, uri)
+ return attachmentView
+ }
+
+ private fun loadAttachmentPreview(attachmentView: View, uri: Uri) {
val roundedCornersRadius = resources.getDimension(R.dimen.medium_margin).toInt()
val options = RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.transform(CenterCrop(), RoundedCorners(roundedCornersRadius))
- Glide.with(this)
+ Glide.with(attachmentView.thread_attachment_preview)
.load(uri)
.transition(DrawableTransitionOptions.withCrossFade())
.apply(options)
@@ -650,7 +684,7 @@ class ThreadActivity : SimpleActivity() {
}
private fun checkSendMessageAvailability() {
- if (thread_type_message.text.isNotEmpty() || attachmentUris.isNotEmpty()) {
+ if (thread_type_message.text.isNotEmpty() || (attachmentSelections.isNotEmpty() && !attachmentSelections.values.any { it.isPending })) {
thread_send_message.isClickable = true
thread_send_message.alpha = 0.9f
} else {
@@ -660,11 +694,13 @@ class ThreadActivity : SimpleActivity() {
}
private fun sendMessage() {
- val msg = thread_type_message.value
- if (msg.isEmpty() && attachmentUris.isEmpty()) {
+ var msg = thread_type_message.value
+ if (msg.isEmpty() && attachmentSelections.isEmpty()) {
return
}
+ msg = removeDiacriticsIfNeeded(msg)
+
val numbers = ArrayList()
participants.forEach {
it.phoneNumbers.forEach {
@@ -687,11 +723,11 @@ class ThreadActivity : SimpleActivity() {
val transaction = Transaction(this, settings)
val message = com.klinker.android.send_message.Message(msg, numbers.toTypedArray())
- if (attachmentUris.isNotEmpty()) {
- for (uri in attachmentUris) {
+ if (attachmentSelections.isNotEmpty()) {
+ for (selection in attachmentSelections.values) {
try {
- val byteArray = contentResolver.openInputStream(uri)?.readBytes() ?: continue
- val mimeType = contentResolver.getType(uri) ?: continue
+ val byteArray = contentResolver.openInputStream(selection.uri)?.readBytes() ?: continue
+ val mimeType = contentResolver.getType(selection.uri) ?: continue
message.addMedia(byteArray, mimeType)
} catch (e: Exception) {
showErrorToast(e)
@@ -711,7 +747,7 @@ class ThreadActivity : SimpleActivity() {
refreshedSinceSent = false
transaction.sendNewMessage(message, threadId)
thread_type_message.setText("")
- attachmentUris.clear()
+ attachmentSelections.clear()
thread_attachments_holder.beGone()
thread_attachments_wrapper.removeAllViews()
@@ -781,6 +817,41 @@ class ThreadActivity : SimpleActivity() {
showSelectedContacts()
}
+ private fun getPhoneNumbersFromIntent(): ArrayList {
+ val numberFromIntent = intent.getStringExtra(THREAD_NUMBER)
+ val numbers = ArrayList()
+
+ if (numberFromIntent != null) {
+ if (numberFromIntent.startsWith('[') && numberFromIntent.endsWith(']')) {
+ val type = object : TypeToken>() {}.type
+ numbers.addAll(Gson().fromJson(numberFromIntent, type))
+ } else {
+ numbers.add(numberFromIntent)
+ }
+ }
+ return numbers
+ }
+
+ private fun fixParticipantNumbers(participants: ArrayList, properNumbers: ArrayList): ArrayList {
+ for (number in properNumbers) {
+ for (participant in participants) {
+ participant.phoneNumbers = participant.phoneNumbers.map {
+ val numberWithoutPlus = number.replace("+", "")
+ if (numberWithoutPlus == it.trim()) {
+ if (participant.name == it) {
+ participant.name = number
+ }
+ number
+ } else {
+ it
+ }
+ } as ArrayList
+ }
+ }
+
+ return participants
+ }
+
@SuppressLint("MissingPermission")
@Subscribe(threadMode = ThreadMode.ASYNC)
fun refreshMessages(event: Events.RefreshMessages) {
diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt
index 2990622a..cbccb4b1 100644
--- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt
@@ -217,6 +217,11 @@ class ConversationsAdapter(
conversationsMarkedAsUnread.filter { conversation -> conversation.read }.forEach {
activity.markThreadMessagesUnread(it.threadId)
}
+
+ activity.runOnUiThread {
+ refreshMessages()
+ finishActMode()
+ }
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Bitmap.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Bitmap.kt
new file mode 100644
index 00000000..c55bbe7b
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Bitmap.kt
@@ -0,0 +1,9 @@
+package com.simplemobiletools.smsmessenger.extensions
+
+import android.graphics.Bitmap
+
+fun Bitmap.CompressFormat.extension() = when (this) {
+ Bitmap.CompressFormat.PNG -> "png"
+ Bitmap.CompressFormat.WEBP -> "webp"
+ else -> "jpg"
+}
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 1e2479d0..a4c845db 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,8 +37,10 @@ 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 java.text.Normalizer
import me.leolin.shortcutbadger.ShortcutBadger
val Context.config: Config get() = Config.newInstance(applicationContext)
@@ -73,11 +77,7 @@ fun Context.getMessages(threadId: Long): ArrayList {
val blockedNumbers = getBlockedNumbers()
var messages = ArrayList()
queryCursor(uri, projection, selection, selectionArgs, sortOrder, showErrors = true) { cursor ->
- val senderNumber = cursor.getStringValue(Sms.ADDRESS)
-
- if(senderNumber == null){
- return@queryCursor
- }
+ val senderNumber = cursor.getStringValue(Sms.ADDRESS) ?: return@queryCursor
val isNumberBlocked = if (blockStatus.containsKey(senderNumber)) {
blockStatus[senderNumber]!!
@@ -783,6 +783,10 @@ fun Context.getLockScreenVisibilityText(type: Int) = getString(
}
)
+fun Context.removeDiacriticsIfNeeded(text: String): String {
+ return if (config.useSimpleCharacters) text.normalizeString() else text
+}
+
fun Context.getSmsDraft(threadId: Long): String? {
val uri = Sms.Draft.CONTENT_URI
val projection = arrayOf(Sms.BODY)
@@ -835,6 +839,18 @@ fun Context.deleteSmsDraft(threadId: Long) {
}
}
+fun Context.getMMSFileLimitText(size: Long) = getString(
+ when (size) {
+ FILE_SIZE_100_KB -> R.string.mms_file_size_limit_100kb
+ FILE_SIZE_200_KB -> R.string.mms_file_size_limit_200kb
+ FILE_SIZE_300_KB -> R.string.mms_file_size_limit_300kb
+ FILE_SIZE_600_KB -> R.string.mms_file_size_limit_600kb
+ FILE_SIZE_1_MB -> R.string.mms_file_size_limit_1mb
+ FILE_SIZE_2_MB -> R.string.mms_file_size_limit_2mb
+ else -> R.string.mms_file_size_limit_none
+ }
+)
+
fun Context.updateLastConversationMessage(threadId: Long) {
val uri = Threads.CONTENT_URI
val selection = "${Threads._ID} = ?"
@@ -846,3 +862,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/extensions/String.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/String.kt
new file mode 100644
index 00000000..acdf0bb9
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/String.kt
@@ -0,0 +1,16 @@
+package com.simplemobiletools.smsmessenger.extensions
+
+fun String.getExtensionFromMimeType(): String {
+ return when (lowercase()) {
+ "image/png" -> ".png"
+ "image/apng" -> ".apng"
+ "image/webp" -> ".webp"
+ "image/svg+xml" -> ".svg"
+ "image/gif" -> ".gif"
+ else -> ".jpg"
+ }
+}
+
+fun String.isImageMimeType(): Boolean {
+ return lowercase().startsWith("image")
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt
index 8b590b0e..c6e5c601 100644
--- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt
@@ -18,6 +18,10 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getBoolean(SHOW_CHARACTER_COUNTER, false)
set(showCharacterCounter) = prefs.edit().putBoolean(SHOW_CHARACTER_COUNTER, showCharacterCounter).apply()
+ var useSimpleCharacters: Boolean
+ get() = prefs.getBoolean(USE_SIMPLE_CHARACTERS, false)
+ set(useSimpleCharacters) = prefs.edit().putBoolean(USE_SIMPLE_CHARACTERS, useSimpleCharacters).apply()
+
var enableDeliveryReports: Boolean
get() = prefs.getBoolean(ENABLE_DELIVERY_REPORTS, true)
set(enableDeliveryReports) = prefs.edit().putBoolean(ENABLE_DELIVERY_REPORTS, enableDeliveryReports).apply()
@@ -26,6 +30,10 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getInt(LOCK_SCREEN_VISIBILITY, LOCK_SCREEN_SENDER_MESSAGE)
set(lockScreenVisibilitySetting) = prefs.edit().putInt(LOCK_SCREEN_VISIBILITY, lockScreenVisibilitySetting).apply()
+ var mmsFileSizeLimit: Long
+ get() = prefs.getLong(MMS_FILE_SIZE_LIMIT, FILE_SIZE_1_MB)
+ set(mmsFileSizeLimit) = prefs.edit().putLong(MMS_FILE_SIZE_LIMIT, mmsFileSizeLimit).apply()
+
var lastExportPath: String
get() = prefs.getString(LAST_EXPORT_PATH, "")!!
set(lastExportPath) = prefs.edit().putString(LAST_EXPORT_PATH, lastExportPath).apply()
diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt
index 7e99610e..9e74d87c 100644
--- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt
@@ -13,8 +13,10 @@ const val SEARCHED_MESSAGE_ID = "searched_message_id"
const val USE_SIM_ID_PREFIX = "use_sim_id_"
const val NOTIFICATION_CHANNEL = "simple_sms_messenger"
const val SHOW_CHARACTER_COUNTER = "show_character_counter"
+const val USE_SIMPLE_CHARACTERS = "use_simple_characters"
const val LOCK_SCREEN_VISIBILITY = "lock_screen_visibility"
const val ENABLE_DELIVERY_REPORTS = "enable_delivery_reports"
+const val MMS_FILE_SIZE_LIMIT = "mms_file_size_limit"
const val LAST_EXPORT_PATH = "last_export_path"
const val EXPORT_SMS = "export_sms"
const val EXPORT_MMS = "export_mms"
@@ -40,6 +42,14 @@ const val LOCK_SCREEN_SENDER_MESSAGE = 1
const val LOCK_SCREEN_SENDER = 2
const val LOCK_SCREEN_NOTHING = 3
+const val FILE_SIZE_NONE = -1L
+const val FILE_SIZE_100_KB = 102_400L
+const val FILE_SIZE_200_KB = 204_800L
+const val FILE_SIZE_300_KB = 307_200L
+const val FILE_SIZE_600_KB = 614_400L
+const val FILE_SIZE_1_MB = 1_048_576L
+const val FILE_SIZE_2_MB = 2_097_152L
+
fun refreshMessages() {
EventBus.getDefault().post(Events.RefreshMessages())
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt
new file mode 100644
index 00000000..aa58387e
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt
@@ -0,0 +1,119 @@
+package com.simplemobiletools.smsmessenger.helpers
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.Matrix
+import android.media.ExifInterface
+import android.net.Uri
+import com.simplemobiletools.commons.extensions.getCompressionFormat
+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
+
+/**
+ * Compress image to a given size based on
+ * [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()) {
+ mkdirs()
+ }
+ }
+
+ fun compressImage(uri: Uri, compressSize: Long, callback: (compressedFileUri: Uri?) -> Unit) {
+ ensureBackgroundThread {
+ try {
+ 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)
+ }
+ } else {
+ //no need to compress since the file is less than the compress size
+ callback.invoke(uri)
+ }
+ } catch (e: Exception) {
+ callback.invoke(null)
+ }
+ }
+ }
+
+ private fun overWrite(imageFile: File, bitmap: Bitmap, format: Bitmap.CompressFormat = imageFile.path.getCompressionFormat(), quality: Int = 100): File {
+ val result = if (format == imageFile.path.getCompressionFormat()) {
+ imageFile
+ } else {
+ File("${imageFile.absolutePath.substringBeforeLast(".")}.${format.extension()}")
+ }
+ imageFile.delete()
+ saveBitmap(bitmap, result, format, quality)
+ return result
+ }
+
+ private fun saveBitmap(bitmap: Bitmap, destination: File, format: Bitmap.CompressFormat = destination.path.getCompressionFormat(), quality: Int = 100) {
+ destination.parentFile?.mkdirs()
+ var fileOutputStream: FileOutputStream? = null
+ try {
+ fileOutputStream = FileOutputStream(destination.absolutePath)
+ bitmap.compress(format, quality, fileOutputStream)
+ } finally {
+ fileOutputStream?.run {
+ flush()
+ close()
+ }
+ }
+ }
+
+ private fun loadBitmap(imageFile: File) = BitmapFactory.decodeFile(imageFile.absolutePath).run {
+ determineImageRotation(imageFile, this)
+ }
+
+ private fun determineImageRotation(imageFile: File, bitmap: Bitmap): Bitmap {
+ val exif = ExifInterface(imageFile.absolutePath)
+ val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)
+ val matrix = Matrix()
+ when (orientation) {
+ 6 -> matrix.postRotate(90f)
+ 3 -> matrix.postRotate(180f)
+ 8 -> matrix.postRotate(270f)
+ }
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
+ }
+
+ private inner class SizeConstraint(
+ private val maxFileSize: Long,
+ private val stepSize: Int = 10,
+ private val maxIteration: Int = 10,
+ private val minQuality: Int = 10
+ ) {
+ private var iteration: Int = 0
+
+ fun isSatisfied(imageFile: File): Boolean {
+ return imageFile.length() <= maxFileSize || iteration >= maxIteration
+ }
+
+ fun satisfy(imageFile: File): File {
+ iteration++
+ val quality = (100 - iteration * stepSize).takeIf { it >= minQuality } ?: minQuality
+ return overWrite(imageFile, loadBitmap(imageFile), quality = quality)
+ }
+ }
+
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/AttachmentSelection.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/AttachmentSelection.kt
new file mode 100644
index 00000000..e56835d2
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/AttachmentSelection.kt
@@ -0,0 +1,8 @@
+package com.simplemobiletools.smsmessenger.models
+
+import android.net.Uri
+
+data class AttachmentSelection(
+ val uri: Uri,
+ val isPending: Boolean,
+)
diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt
index 8a4ee30c..79e333b8 100644
--- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt
@@ -11,6 +11,7 @@ import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.smsmessenger.extensions.conversationsDB
import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead
+import com.simplemobiletools.smsmessenger.extensions.removeDiacriticsIfNeeded
import com.simplemobiletools.smsmessenger.helpers.REPLY
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
import com.simplemobiletools.smsmessenger.helpers.THREAD_NUMBER
@@ -19,7 +20,9 @@ class DirectReplyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val address = intent.getStringExtra(THREAD_NUMBER)
val threadId = intent.getLongExtra(THREAD_ID, 0L)
- val msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY)?.toString() ?: return
+ var msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY)?.toString() ?: return
+
+ msg = context.removeDiacriticsIfNeeded(msg)
val settings = Settings()
settings.useSystemSending = true
diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MarkAsReadReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MarkAsReadReceiver.kt
index 4525f30d..5488c3aa 100644
--- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MarkAsReadReceiver.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MarkAsReadReceiver.kt
@@ -10,6 +10,7 @@ import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead
import com.simplemobiletools.smsmessenger.extensions.updateUnreadCountBadge
import com.simplemobiletools.smsmessenger.helpers.MARK_AS_READ
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
+import com.simplemobiletools.smsmessenger.helpers.refreshMessages
class MarkAsReadReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -21,6 +22,7 @@ class MarkAsReadReceiver : BroadcastReceiver() {
context.markThreadMessagesRead(threadId)
context.conversationsDB.markRead(threadId)
context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations())
+ refreshMessages()
}
}
}
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
index 859fdf00..77283b63 100644
--- a/app/src/main/res/layout/activity_settings.xml
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -195,6 +195,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_attachment.xml b/app/src/main/res/layout/item_attachment.xml
index ee25d173..be794651 100644
--- a/app/src/main/res/layout/item_attachment.xml
+++ b/app/src/main/res/layout/item_attachment.xml
@@ -1,14 +1,24 @@
+ android:layout_width="@dimen/attachment_preview_size"
+ android:layout_height="@dimen/attachment_preview_size">
+ android:visibility="gone"
+ tools:visibility="visible" />
+
+
+ android:visibility="gone"
+ tools:visibility="visible" />
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 37651ec0..af8271c5 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Proč aplikace vyžaduje přístup k internetu?
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index d9067fb0..16102277 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Hvorfor kræver appen adgang til internettet?
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index d7e5e614..40f69e22 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Warum benötigt diese App Internetzugriff?
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 73901649..ec01e170 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -49,6 +49,9 @@
Αποστολέας και μήνυμα
Αποστολέας μόνο
Ενεργοποίηση αναφορών παράδοσης
+ Αφαίρεση τονισμών και διακριτικών κατά την αποστολή μηνυμάτων
+ Αλλαγή μεγέθους απεσταλμένων εικόνων MMS
+ Χωρίς όριο
Γιατί η εφαρμογή απαιτεί πρόσβαση στο Internet;
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 0f2ec0f6..a267726e 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
¿Por qué la aplicación requiere acceso a internet?
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 3f6b221f..ab3a4416 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Miksi sovellus vaatii Internet-yhteyden?
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index acf8de23..1625d4fd 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -2,21 +2,21 @@
Simple SMS Messenger
SMS Messenger
Écrivez un message…
- Message not sent
- Not sent. Touch to retry.
- Your message to \'%s\' has not been sent
+ Message non envoyé
+ Pas envoyé. Appuyez pour réessayer.
+ Votre message à \'%s\' n\'a pas été envoyé
Ajouter une personne
Pièce jointe
Aucune conversation enregistrée n\'a été trouvée
Commencer une conversation
Répondre
- Show a character counter at writing messages
- Loading messages…
- Sender doesn\'t support replies
- Draft
- Sending…
- Export messages
- Import messages
+ Afficher le nombre de caractères lors de l\'écriture de messages
+ Chargement des messages…
+ L\'expéditeur n\'accepte pas les réponses
+ Brouillon
+ Envoi en cours…
+ Export de messages
+ Import de messages
Nouvelle conversation
@@ -45,15 +45,18 @@
- Lock screen notification visibility
- Sender and message
- Sender only
- Enable delivery reports
+ Visibilité des notifications sur l\'écran de verrouillage
+ Expéditeur et message
+ Expéditeur uniquement
+ Activer les rapports d\'envoi
+ Supprimer les accents et caractères spéciaux lors de l\'envoi de messages
+ Redimensionner les images MMS envoyées
+ Pas de limite
Pourquoi cette application a besoin d\'un accès à internet ?
Malheureusement, cela est nécessaire pour envoyer des pièces jointes dans les MMS. Ne pas pouvoir envoyer de MMS serait un énorme désavantage comparé à d\'autres applications, nous avons donc décidé de faire ainsi.
- Cependant, comme toujours, il n\'y a aucune publicité, traqueur ou analyseur de quelque sorte, internet n\'est utilisé que pour envoyer des MMS.
+ Cependant, comme toujours, il n\'y a aucune publicité, traqueur ou analyseur de quelque sorte, internet n\'est utilisé que pour envoyer des MMS.
diff --git a/app/src/main/res/values-gl b/app/src/main/res/values-gl/strings.xml
similarity index 75%
rename from app/src/main/res/values-gl
rename to app/src/main/res/values-gl/strings.xml
index ef3cabd1..d566febf 100644
--- a/app/src/main/res/values-gl
+++ b/app/src/main/res/values-gl/strings.xml
@@ -2,12 +2,21 @@
Simple SMS Messenger
Mensaxe SMS
Escribir unha mensaxe…
- Mensaxe non enviada
+ Mensaxe non enviada
+ Not sent. Touch to retry.
+ Your message to \'%s\' has not been sent
Engadir persoa
Anexo
Non se atoparon conversas
Iniciar unha conversa
Responder
+ Show a character counter at writing messages
+ Loading messages…
+ Sender doesn\'t support replies
+ Draft
+ Sending…
+ Export messages
+ Import messages
Nova conversa
@@ -35,6 +44,15 @@
- %d mensaxes
+
+ Lock screen notification visibility
+ Sender and message
+ Sender only
+ Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
+
Por que o aplicativo necesita acceder a Internet?
Infelizmente é a única forma para poder enviar anexos MMS. A incapacidade de non conseguir enviar MMS sería unha enorme desvantaxe comparativamente a outros aplicativos e, por iso, tomamos esta decisión. Pero, como habitualmente, o aplicativo non ten anuncios, non rastrea os utilizadores nin recolle datos persoais. Este permiso só é necesario para enviar as MMS.
diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml
index 0db16d26..e4217469 100644
--- a/app/src/main/res/values-id/strings.xml
+++ b/app/src/main/res/values-id/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Mengapa aplikasi membutuhkan akses ke internet?
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index b6201852..b1477e50 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -49,6 +49,9 @@
Mittente e messaggio
Solo mittente
Abilita conferma di consegna
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Perché l\'applicazione richiede l\'accesso ad internet?
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 8c5071ec..b281ca3d 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
なぜアプリ使用にインターネットへのアクセスが必要なのですか?
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index ea039ad8..714051b0 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Why does the app require access to the internet?
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index 366149ef..50c2029f 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
അപ്ലിക്കേഷന് ഇന്റർനെറ്റിലേക്ക് ആവശ്യമായി വരുന്നത് എന്തുകൊണ്ട്?
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 0f9e313a..759d3c56 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -49,6 +49,9 @@
Afzender en bericht
Alleen afzender
Bezorgingsrapporten inschakelen
+ Accenten en diakritische tekens verwijderen bij het verzenden van berichten
+ Afbeelding verkleinen voor MMS
+ Geen limiet
Waarom heeft deze app toegang nodig tot het internet?
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 7bc60f8a..bd91ca19 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -51,6 +51,9 @@
Nadawca i treść
Tylko nadawca
Włącz raporty doręczeń
+ Usuwaj akcenty i znaki diakrytyczne podczas wysyłania wiadomości
+ Rozmiar wysyłanych obrazków w MMS-ach
+ Bez limitu
Dlaczego aplikacja wymaga dostępu do Internetu?
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index f6cf255b..4f08f40e 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Porque é que a aplicação necessita de aceder à Internet?
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index f6944577..c4ae0a0b 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -51,6 +51,9 @@
Отправитель и сообщение
Только отправитель
Использовать отчёты о доставке
+ Удалять ударения и диакритические знаки при отправке сообщений
+ Изменять размер отправляемых в MMS изображений
+ Нет ограничения
Почему приложение требует доступ к интернету?
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index f1092bb8..5c922a60 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -12,7 +12,7 @@
Odpovedať
Zobraziť počítadlo znakov pri písaní správ
Načítanie správ…
- Sender doesn\'t support replies
+ Odosielateľ nepodporuje odpovede
Koncept
Odosiela sa…
Exportovať správy
@@ -51,6 +51,9 @@
Odosielateľ a správa
Iba odosielateľ
Povoliť správy o doručení
+ Odstrániť diakritiku pri odosielaní správ
+ Zmenšiť MMS obrázky pri odosielaní
+ Žiadny limit
Prečo vyžaduje apka prístup na internet?
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index f7a3224e..575b3c20 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Uygulama neden internete erişim gerektiriyor?
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index b0a239d0..8a5a6b46 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Чому додаток потрубує доступу до інтернету?
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index b6542e07..c2622ff6 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -49,6 +49,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
为什么该应用需要访问互联网?
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index 24f6140e..244c41e4 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -2,4 +2,11 @@
com.simplemobiletools.smsmessenger
+ 100KB
+ 200KB
+ 300KB
+ 600KB
+ 1MB
+ 2MB
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 527171ed..a4ac6ad8 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -47,6 +47,9 @@
Sender and message
Sender only
Enable delivery reports
+ Remove accents and diacritics at sending messages
+ Resize sent MMS images
+ No limit
Messages
diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml
new file mode 100644
index 00000000..d2c19fcd
--- /dev/null
+++ b/app/src/main/res/xml/provider_paths.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/build.gradle b/build.gradle
index 22e54ea7..b2370fda 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.5.21'
+ ext.kotlin_version = '1.5.30'
repositories {
google()
jcenter()
diff --git a/fastlane/metadata/android/en-US/changelogs/36.txt b/fastlane/metadata/android/en-US/changelogs/36.txt
new file mode 100644
index 00000000..a60f0002
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/36.txt
@@ -0,0 +1,4 @@
+ * Automatically resize sent MMS image attachments by default, allow customizing the limit
+ * Added Draft support
+ * Allow marking conversations un/read from the main screen
+ * Some other stability, UX and translation improvements