Merge pull request #707 from esensar/fix/554-duplicate-resent-messages

Prevent duplication of messages on resend
This commit is contained in:
Tibor Kaputa 2023-07-24 23:32:25 +02:00 committed by GitHub
commit 96c8b4b1ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 13 deletions

View File

@ -107,6 +107,7 @@ class ThreadActivity : SimpleActivity() {
private var wasProtectionHandled = false private var wasProtectionHandled = false
private var isScheduledMessage: Boolean = false private var isScheduledMessage: Boolean = false
private var messageToResend: Long? = null
private var scheduledMessage: Message? = null private var scheduledMessage: Message? = null
private lateinit var scheduledDateTime: DateTime private lateinit var scheduledDateTime: DateTime
@ -291,6 +292,7 @@ class ThreadActivity : SimpleActivity() {
super.onActivityResult(requestCode, resultCode, resultData) super.onActivityResult(requestCode, resultCode, resultData)
if (resultCode != Activity.RESULT_OK) return if (resultCode != Activity.RESULT_OK) return
val data = resultData?.data val data = resultData?.data
messageToResend = null
if (requestCode == CAPTURE_PHOTO_INTENT && capturedImageUri != null) { if (requestCode == CAPTURE_PHOTO_INTENT && capturedImageUri != null) {
addAttachment(capturedImageUri!!) addAttachment(capturedImageUri!!)
@ -492,7 +494,10 @@ class ThreadActivity : SimpleActivity() {
private fun handleItemClick(any: Any) { private fun handleItemClick(any: Any) {
when { when {
any is Message && any.isScheduled -> showScheduledMessageInfo(any) any is Message && any.isScheduled -> showScheduledMessageInfo(any)
any is ThreadError -> thread_type_message.setText(any.messageText) any is ThreadError -> {
thread_type_message.setText(any.messageText)
messageToResend = any.messageId
}
} }
} }
@ -635,6 +640,7 @@ class ThreadActivity : SimpleActivity() {
thread_send_message.isClickable = false thread_send_message.isClickable = false
thread_type_message.onTextChangeListener { thread_type_message.onTextChangeListener {
messageToResend = null
checkSendMessageAvailability() checkSendMessageAvailability()
val messageString = if (config.useSimpleCharacters) { val messageString = if (config.useSimpleCharacters) {
it.normalizeString() it.normalizeString()
@ -1334,7 +1340,7 @@ class ThreadActivity : SimpleActivity() {
try { try {
refreshedSinceSent = false refreshedSinceSent = false
sendMessageCompat(text, addresses, subscriptionId, attachments) sendMessageCompat(text, addresses, subscriptionId, attachments, messageToResend)
ensureBackgroundThread { ensureBackgroundThread {
val messageIds = messages.map { it.id } val messageIds = messages.map { it.id }
val messages = getMessages(threadId, getImageResolutions = true, limit = maxOf(1, attachments.size)) val messages = getMessages(threadId, getImageResolutions = true, limit = maxOf(1, attachments.size))

View File

@ -32,7 +32,7 @@ fun Context.isLongMmsMessage(text: String, settings: Settings = getSendMessageSe
} }
/** Sends the message using the in-app SmsManager API wrappers if it's an SMS or using android-smsmms for MMS. */ /** Sends the message using the in-app SmsManager API wrappers if it's an SMS or using android-smsmms for MMS. */
fun Context.sendMessageCompat(text: String, addresses: List<String>, subId: Int?, attachments: List<Attachment>) { fun Context.sendMessageCompat(text: String, addresses: List<String>, subId: Int?, attachments: List<Attachment>, messageId: Long? = null) {
val settings = getSendMessageSettings() val settings = getSendMessageSettings()
if (subId != null) { if (subId != null) {
settings.subscriptionId = subId settings.subscriptionId = subId
@ -47,18 +47,18 @@ fun Context.sendMessageCompat(text: String, addresses: List<String>, subId: Int?
if (attachments.size > 1) { if (attachments.size > 1) {
for (i in 0 until lastIndex) { for (i in 0 until lastIndex) {
val attachment = attachments[i] val attachment = attachments[i]
messagingUtils.sendMmsMessage("", addresses, attachment, settings) messagingUtils.sendMmsMessage("", addresses, attachment, settings, messageId)
} }
} }
val lastAttachment = attachments[lastIndex] val lastAttachment = attachments[lastIndex]
messagingUtils.sendMmsMessage(text, addresses, lastAttachment, settings) messagingUtils.sendMmsMessage(text, addresses, lastAttachment, settings, messageId)
} else { } else {
messagingUtils.sendMmsMessage(text, addresses, null, settings) messagingUtils.sendMmsMessage(text, addresses, null, settings, messageId)
} }
} else { } else {
try { try {
messagingUtils.sendSmsMessage(text, addresses.toSet(), settings.subscriptionId, settings.deliveryReports) messagingUtils.sendSmsMessage(text, addresses.toSet(), settings.subscriptionId, settings.deliveryReports, messageId)
} catch (e: SmsException) { } catch (e: SmsException) {
when (e.errorCode) { when (e.errorCode) {
EMPTY_DESTINATION_ADDRESS -> toast(id = R.string.empty_destination_address, length = LENGTH_LONG) EMPTY_DESTINATION_ADDRESS -> toast(id = R.string.empty_destination_address, length = LENGTH_LONG)

View File

@ -31,7 +31,7 @@ class MessagingUtils(val context: Context) {
*/ */
private fun insertSmsMessage( private fun insertSmsMessage(
subId: Int, dest: String, text: String, timestamp: Long, threadId: Long, subId: Int, dest: String, text: String, timestamp: Long, threadId: Long,
status: Int = Sms.STATUS_NONE, type: Int = Sms.MESSAGE_TYPE_OUTBOX status: Int = Sms.STATUS_NONE, type: Int = Sms.MESSAGE_TYPE_OUTBOX, messageId: Long? = null
): Uri { ): Uri {
val response: Uri? val response: Uri?
val values = ContentValues().apply { val values = ContentValues().apply {
@ -58,7 +58,18 @@ class MessagingUtils(val context: Context) {
} }
try { try {
response = context.contentResolver.insert(Sms.CONTENT_URI, values) if (messageId != null) {
val selection = "${Sms._ID} = ?"
val selectionArgs = arrayOf(messageId.toString())
val count = context.contentResolver.update(Sms.CONTENT_URI, values, selection, selectionArgs)
if (count > 0) {
response = Uri.parse("${Sms.CONTENT_URI}/${messageId}")
} else {
response = null
}
} else {
response = context.contentResolver.insert(Sms.CONTENT_URI, values)
}
} catch (e: Exception) { } catch (e: Exception) {
throw SmsException(ERROR_PERSISTING_MESSAGE, e) throw SmsException(ERROR_PERSISTING_MESSAGE, e)
} }
@ -67,7 +78,7 @@ class MessagingUtils(val context: Context) {
/** Send an SMS message given [text] and [addresses]. A [SmsException] is thrown in case any errors occur. */ /** Send an SMS message given [text] and [addresses]. A [SmsException] is thrown in case any errors occur. */
fun sendSmsMessage( fun sendSmsMessage(
text: String, addresses: Set<String>, subId: Int, requireDeliveryReport: Boolean text: String, addresses: Set<String>, subId: Int, requireDeliveryReport: Boolean, messageId: Long? = null
) { ) {
if (addresses.size > 1) { if (addresses.size > 1) {
// insert a dummy message for this thread if it is a group message // insert a dummy message for this thread if it is a group message
@ -76,7 +87,8 @@ class MessagingUtils(val context: Context) {
insertSmsMessage( insertSmsMessage(
subId = subId, dest = mergedAddresses, text = text, subId = subId, dest = mergedAddresses, text = text,
timestamp = System.currentTimeMillis(), threadId = broadCastThreadId, timestamp = System.currentTimeMillis(), threadId = broadCastThreadId,
status = Sms.Sent.STATUS_COMPLETE, type = Sms.Sent.MESSAGE_TYPE_SENT status = Sms.Sent.STATUS_COMPLETE, type = Sms.Sent.MESSAGE_TYPE_SENT,
messageId = messageId
) )
} }
@ -84,7 +96,8 @@ class MessagingUtils(val context: Context) {
val threadId = context.getThreadId(address) val threadId = context.getThreadId(address)
val messageUri = insertSmsMessage( val messageUri = insertSmsMessage(
subId = subId, dest = address, text = text, subId = subId, dest = address, text = text,
timestamp = System.currentTimeMillis(), threadId = threadId timestamp = System.currentTimeMillis(), threadId = threadId,
messageId = messageId
) )
try { try {
context.smsSender.sendMessage( context.smsSender.sendMessage(
@ -133,7 +146,7 @@ class MessagingUtils(val context: Context) {
} }
@Deprecated("TODO: Move/rewrite MMS code into the app.") @Deprecated("TODO: Move/rewrite MMS code into the app.")
fun sendMmsMessage(text: String, addresses: List<String>, attachment: Attachment?, settings: Settings) { fun sendMmsMessage(text: String, addresses: List<String>, attachment: Attachment?, settings: Settings, messageId: Long? = null) {
val transaction = Transaction(context, settings) val transaction = Transaction(context, settings)
val message = Message(text, addresses.toTypedArray()) val message = Message(text, addresses.toTypedArray())
@ -158,6 +171,7 @@ class MessagingUtils(val context: Context) {
} }
val mmsSentIntent = Intent(context, MmsSentReceiver::class.java) val mmsSentIntent = Intent(context, MmsSentReceiver::class.java)
mmsSentIntent.putExtra(MmsSentReceiver.EXTRA_ORIGINAL_RESENT_MESSAGE_ID, messageId)
transaction.setExplicitBroadcastForSentMms(mmsSentIntent) transaction.setExplicitBroadcastForSentMms(mmsSentIntent)
try { try {

View File

@ -11,6 +11,7 @@ import android.widget.Toast
import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.extensions.deleteMessage
import com.simplemobiletools.smsmessenger.helpers.refreshMessages import com.simplemobiletools.smsmessenger.helpers.refreshMessages
import java.io.File import java.io.File
@ -19,6 +20,7 @@ class MmsSentReceiver : SendStatusReceiver() {
override fun updateAndroidDatabase(context: Context, intent: Intent, receiverResultCode: Int) { override fun updateAndroidDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
val uri = Uri.parse(intent.getStringExtra(EXTRA_CONTENT_URI)) val uri = Uri.parse(intent.getStringExtra(EXTRA_CONTENT_URI))
val originalResentMessageId = intent.getLongExtra(EXTRA_ORIGINAL_RESENT_MESSAGE_ID, -1L)
val messageBox = if (receiverResultCode == Activity.RESULT_OK) { val messageBox = if (receiverResultCode == Activity.RESULT_OK) {
Telephony.Mms.MESSAGE_BOX_SENT Telephony.Mms.MESSAGE_BOX_SENT
} else { } else {
@ -37,6 +39,11 @@ class MmsSentReceiver : SendStatusReceiver() {
context.showErrorToast(e) context.showErrorToast(e)
} }
// In case of resent message, delete original to prevent duplication
if (originalResentMessageId != -1L) {
context.deleteMessage(originalResentMessageId, true)
}
val filePath = intent.getStringExtra(EXTRA_FILE_PATH) val filePath = intent.getStringExtra(EXTRA_FILE_PATH)
if (filePath != null) { if (filePath != null) {
File(filePath).delete() File(filePath).delete()
@ -50,5 +57,6 @@ class MmsSentReceiver : SendStatusReceiver() {
companion object { companion object {
private const val EXTRA_CONTENT_URI = "content_uri" private const val EXTRA_CONTENT_URI = "content_uri"
private const val EXTRA_FILE_PATH = "file_path" private const val EXTRA_FILE_PATH = "file_path"
const val EXTRA_ORIGINAL_RESENT_MESSAGE_ID = "original_message_id"
} }
} }