From d97a6f6a5f96ced833462b21185edf7ae7476117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Wed, 12 Jul 2023 17:45:24 +0200 Subject: [PATCH] Ensure that MMS reception ACK is sent to prevent duplicate MMS This implements the getMmscInfoForReceptionAck method in MmsReceiver which is according to android-smsmms library required for some carriers, since otherwise MMS would be duplicated. Unfortunately, accessing MMSC information is more restricted with each version of Android and this implementation relies on system database on older versions and uses APN database included with android-smsmms for newer versions, which will work only on the default SIM card. --- .../com/simplemobiletools/smsmessenger/App.kt | 6 ++ .../smsmessenger/receivers/MmsReceiver.kt | 67 ++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/App.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/App.kt index 5f76354e..c5f624f6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/App.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/App.kt @@ -1,11 +1,17 @@ package com.simplemobiletools.smsmessenger import android.app.Application +import com.klinker.android.send_message.ApnUtils import com.simplemobiletools.commons.extensions.checkUseEnglish +import com.simplemobiletools.commons.helpers.isRPlus class App : Application() { override fun onCreate() { super.onCreate() checkUseEnglish() + + if (isRPlus()) { + ApnUtils.initDefaultApns(this) {} + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MmsReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MmsReceiver.kt index 57f35872..13911e4c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MmsReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MmsReceiver.kt @@ -1,19 +1,84 @@ package com.simplemobiletools.smsmessenger.receivers +import android.content.BroadcastReceiver import android.content.Context +import android.content.Intent import android.net.Uri import android.os.Handler import android.os.Looper +import android.preference.PreferenceManager +import android.provider.Telephony import com.bumptech.glide.Glide +import com.klinker.android.send_message.MmsReceivedReceiver +import com.klinker.android.send_message.MmsReceivedReceiver.MmscInformation +import com.klinker.android.send_message.MmsReceivedReceiver.SUBSCRIPTION_ID +import com.klinker.android.send_message.Utils +import com.simplemobiletools.commons.extensions.getStringValue import com.simplemobiletools.commons.extensions.isNumberBlocked import com.simplemobiletools.commons.extensions.normalizePhoneNumber +import com.simplemobiletools.commons.extensions.queryCursor import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.commons.helpers.isQPlus +import com.simplemobiletools.commons.helpers.isRPlus import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.extensions.* import com.simplemobiletools.smsmessenger.helpers.refreshMessages // more info at https://github.com/klinker41/android-smsmms -class MmsReceiver : com.klinker.android.send_message.MmsReceivedReceiver() { +class MmsReceiver : BroadcastReceiver() { + + private var carriers = mutableMapOf() + + override fun onReceive(context: Context?, intent: Intent?) { + if (isRPlus() && carriers.isNotEmpty()) { + // This information is stored by ApnUtils from android-smsmms + PreferenceManager.getDefaultSharedPreferences(context).apply { + carriers[0] = MmscInformation( + getString("mmsc_url", ""), + getString("mms_proxy", ""), + getString("mms_port", "0")?.toInt() ?: 0 + ) + } + } else { + val subscriptionId = intent?.getIntExtra(SUBSCRIPTION_ID, Utils.getDefaultSubscriptionId()) ?: Utils.getDefaultSubscriptionId() + if (carriers.containsKey(subscriptionId).not()) { + val baseUri = if (isQPlus()) { + Telephony.Carriers.SIM_APN_URI + } else { + Telephony.Carriers.CONTENT_URI + } + val uri = Uri.withAppendedPath(baseUri, subscriptionId.toString()) + val projection = arrayOf( + Telephony.Carriers.MMSC, + Telephony.Carriers.MMSPROXY, + Telephony.Carriers.MMSPORT, + ) + val selection = "${Telephony.Carriers.TYPE} LIKE ?" + val selectionArgs = arrayOf("%mms%") + + context?.queryCursor(uri, projection = projection, selection = selection, selectionArgs = selectionArgs) { cursor -> + carriers[subscriptionId] = MmscInformation( + cursor.getStringValue(Telephony.Carriers.MMSC), + cursor.getStringValue(Telephony.Carriers.MMSPROXY), + cursor.getStringValue(Telephony.Carriers.MMSPORT).toIntOrNull() ?: 0, + ) + } + } + } + val mmscInformation = if (isRPlus()) { + carriers[0] + } else { + val subscriptionId = intent?.getIntExtra(SUBSCRIPTION_ID, Utils.getDefaultSubscriptionId()) ?: Utils.getDefaultSubscriptionId() + carriers[subscriptionId] + } + MmsReceivedReceiverImplementation(mmscInformation).onReceive(context, intent) + } +} + +private class MmsReceivedReceiverImplementation(private val mmscInformation: MmscInformation?) : MmsReceivedReceiver() { + override fun getMmscInfoForReceptionAck(): MmscInformation? { + return mmscInformation + } override fun isAddressBlocked(context: Context, address: String): Boolean { val normalizedAddress = address.normalizePhoneNumber()