Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mms Send Stuck on "Sending" #197

Open
IbrahimEzzatSaad opened this issue Jun 25, 2024 · 2 comments
Open

Mms Send Stuck on "Sending" #197

IbrahimEzzatSaad opened this issue Jun 25, 2024 · 2 comments

Comments

@IbrahimEzzatSaad
Copy link

IbrahimEzzatSaad commented Jun 25, 2024

I have noticed this problem on the following devices:
realme 9i android 13 network - vi
samesung m53 android 13 network - jio
redmi note10s android 13 network - jio

Some of those devices give "error code: 5" and some devices is just stuck on "Sending" without sending anything
https://drive.google.com/file/d/1sSI_niLAFBP4gWOlsVRzM1MSjxOYZiJK/view?usp=sharing
https://drive.google.com/file/d/1A2tZZ1Zz07bERa1WiBBMpHfYsClKL53f/view?usp=sharing
https://drive.google.com/file/d/12rEq8JP0L5mKnP0nxwxjSkVqiNKa5Qh-/view?usp=sharing

Here's my code

fun Context.getSendMessageSettings(): Settings {
    val settings = Settings()
    settings.useSystemSending = true
    settings.deliveryReports = config.enableDeliveryReports
    settings.sendLongAsMms = config.sendLongMessageMMS
    settings.sendLongAsMmsAfter = 1
    settings.group = config.sendGroupMessageMMS
    return settings
}
/** 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>, messageId: Long? = null) {
    val settings = getSendMessageSettings()
    if (subId != null) {
        settings.subscriptionId = subId
    }
    Log.i("subId", subId.toString())

    val messagingUtils = messagingUtils
    val isMms = attachments.isNotEmpty() || isLongMmsMessage(text, settings) || addresses.size > 1 && settings.group
    if (isMms) {
        // we send all MMS attachments separately to reduces the chances of hitting provider MMS limit.
        if (attachments.isNotEmpty()) {
            val lastIndex = attachments.lastIndex
            if (attachments.size > 1) {
                for (i in 0 until lastIndex) {
                    val attachment = attachments[i]
                    messagingUtils.sendMmsMessage("", addresses, attachment, settings, messageId)
                }
            }

            val lastAttachment = attachments[lastIndex]
            messagingUtils.sendMmsMessage(text, addresses, lastAttachment, settings, messageId)
        } else {
            messagingUtils.sendMmsMessage(text, addresses, null, settings, messageId)
        }
    } else {
        try {
            messagingUtils.sendSmsMessage(text, addresses.toSet(), settings.subscriptionId, settings.deliveryReports, messageId)
        } catch (e: SmsException) {
            when (e.errorCode) {
                EMPTY_DESTINATION_ADDRESS -> toast(id = R.string.empty_destination_address, length = LENGTH_LONG)
                ERROR_PERSISTING_MESSAGE -> toast(id = R.string.unable_to_save_message, length = LENGTH_LONG)
                ERROR_SENDING_MESSAGE -> toast(
                    msg = getString(R.string.unknown_error_occurred_sending_message, e.errorCode),
                    length = LENGTH_LONG
                )
            }
        } catch (e: Exception) {
            showErrorToast(e)
        }
    }
}
fun sendMmsMessage(text: String, addresses: List<String>, attachment: Attachment?, settings: Settings, messageId: Long? = null) {
        val transaction = Transaction(context, settings)
        val message = Message(text, addresses.toTypedArray())

        if (attachment != null) {
            try {
                val uri = attachment.getUri()
                context.contentResolver.openInputStream(uri)?.use {
                    val bytes = it.readBytes()
                    val mimeType = if (attachment.mimetype.isPlainTextMimeType()) {
                        "application/txt"
                    } else {
                        attachment.mimetype
                    }
                    val name = attachment.filename
                    message.addMedia(bytes, mimeType, name)
                }
            } catch (e: Exception) {
                context.showErrorToast(e)
            } catch (e: Error) {
                context.showErrorToast(e.localizedMessage ?: context.getString(com.simplemobiletools.commons.R.string.unknown_error_occurred))
            }
        }

        val mmsSentIntent = Intent(context, MmsSentReceiver::class.java)
        mmsSentIntent.putExtra(MmsSentReceiver.EXTRA_ORIGINAL_RESENT_MESSAGE_ID, messageId)
        transaction.setExplicitBroadcastForSentMms(mmsSentIntent)


        try {
            transaction.sendNewMessage(message)
        } catch (e: Exception) {
            context.showErrorToast(e)
        }
    }
@AndroidEntryPoint
class MmsSentReceiver : SendStatusReceiver() {
    @Inject
    lateinit var cache: Cache
    private val myCoroutineScope = CoroutineScope(Dispatchers.IO)

    override fun updateAndroidDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
        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) {
            Telephony.Mms.MESSAGE_BOX_SENT
        } else {
            val msg = context.getString(R.string.unknown_error_occurred_sending_message, receiverResultCode)
            context.toast(msg = msg, length = Toast.LENGTH_LONG)

            Telephony.Mms.MESSAGE_BOX_FAILED
        }

        val values = ContentValues(1).apply {
            put(Telephony.Mms.MESSAGE_BOX, messageBox)
        }

        try {
            context.contentResolver.update(uri, values, null, null)
        } catch (e: SQLiteException) {
            context.showErrorToast(e)
        }

        // In case of resent message, delete original to prevent duplication
        if (originalResentMessageId != -1L) {
            myCoroutineScope.launch {
                context.deleteMessage(originalResentMessageId, true)
                cache.deleteMessage(originalResentMessageId)
            }
        }

        val filePath = intent.getStringExtra(EXTRA_FILE_PATH)
        if (filePath != null) {
            File(filePath).delete()
        }
    }

    override fun updateAppDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
        val messageUri: Uri? = intent.data
        if (messageUri != null) {
            val messageId = messageUri.lastPathSegment?.toLong() ?: 0L
            myCoroutineScope.launch {
                if (resultCode != Telephony.Sms.Sent.STATUS_NONE) {
                    cache.updateMessageStatus(messageId, receiverResultCode)
                }
            }
        }
    }

    companion object {
        private const val EXTRA_CONTENT_URI = "content_uri"
        private const val EXTRA_FILE_PATH = "file_path"
        const val EXTRA_ORIGINAL_RESENT_MESSAGE_ID = "original_message_id"
    }
}
@Barkerww
Copy link

Your code looks normal. Maybe you need to check the APN/proxy/port setting

@IbrahimEzzatSaad
Copy link
Author

Your code looks normal. Maybe you need to check the APN/proxy/port setting

Can you give me an example of that? Are there specifics for each SIM proxy and port? I thought just data connection was the only thing that was required

The problem also exists in this app which uses the same library
https://play.google.com/store/apps/details?id=com.simplemobiletools.smsmessenger&hl=en

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants