fix: improve sms receiver handling (#642)
* fix: improve sms receiver handling * docs: add comment regarding multiple messages * fix: catch errors when inserting conversation Refs: https://github.com/FossifyOrg/Messages/issues/159
This commit is contained in:
parent
ed2aedd915
commit
1e3f5e5933
4 changed files with 138 additions and 119 deletions
|
|
@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
### Fixed
|
||||
- Fixed missing notifications in some cases ([#159])
|
||||
|
||||
## [1.7.0] - 2025-12-16
|
||||
### Added
|
||||
|
|
@ -188,6 +190,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
[#115]: https://github.com/FossifyOrg/Messages/issues/115
|
||||
[#135]: https://github.com/FossifyOrg/Messages/issues/135
|
||||
[#153]: https://github.com/FossifyOrg/Messages/issues/153
|
||||
[#159]: https://github.com/FossifyOrg/Messages/issues/159
|
||||
[#165]: https://github.com/FossifyOrg/Messages/issues/165
|
||||
[#177]: https://github.com/FossifyOrg/Messages/issues/177
|
||||
[#180]: https://github.com/FossifyOrg/Messages/issues/180
|
||||
|
|
|
|||
|
|
@ -1050,14 +1050,11 @@ fun Context.getThreadId(addresses: Set<String>): Long {
|
|||
fun Context.showReceivedMessageNotification(
|
||||
messageId: Long,
|
||||
address: String,
|
||||
senderName: String,
|
||||
body: String,
|
||||
threadId: Long,
|
||||
bitmap: Bitmap?,
|
||||
) {
|
||||
val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
|
||||
ensureBackgroundThread {
|
||||
val senderName = getNameFromAddress(address, privateCursor)
|
||||
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
notificationHelper.showMessageNotification(
|
||||
messageId = messageId,
|
||||
|
|
@ -1069,7 +1066,6 @@ fun Context.showReceivedMessageNotification(
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.getNameFromAddress(address: String, privateCursor: Cursor?): String {
|
||||
var sender = getNameAndPhotoFromPhoneNumber(address).name
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package org.fossify.messages.receivers
|
|||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.bumptech.glide.Glide
|
||||
import com.klinker.android.send_message.MmsReceivedReceiver
|
||||
import org.fossify.commons.extensions.baseConfig
|
||||
|
|
@ -16,6 +14,7 @@ import org.fossify.commons.helpers.ensureBackgroundThread
|
|||
import org.fossify.messages.R
|
||||
import org.fossify.messages.extensions.getConversations
|
||||
import org.fossify.messages.extensions.getLatestMMS
|
||||
import org.fossify.messages.extensions.getNameFromAddress
|
||||
import org.fossify.messages.extensions.insertOrUpdateConversation
|
||||
import org.fossify.messages.extensions.shouldUnarchive
|
||||
import org.fossify.messages.extensions.showReceivedMessageNotification
|
||||
|
|
@ -31,13 +30,11 @@ class MmsReceiver : MmsReceivedReceiver() {
|
|||
val normalizedAddress = address.normalizePhoneNumber()
|
||||
if (context.isNumberBlocked(normalizedAddress)) return true
|
||||
if (context.baseConfig.blockUnknownNumbers) {
|
||||
val privateCursor = context.getMyContactsCursor(
|
||||
favoritesOnly = false,
|
||||
withPhoneNumbersOnly = true
|
||||
)
|
||||
val isKnownContact = SimpleContactsHelper(context).existsSync(address, privateCursor)
|
||||
context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true).use {
|
||||
val isKnownContact = SimpleContactsHelper(context).existsSync(address, it)
|
||||
return !isKnownContact
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
@ -76,19 +73,22 @@ class MmsReceiver : MmsReceivedReceiver() {
|
|||
null
|
||||
}
|
||||
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
|
||||
val senderName = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true).use {
|
||||
context.getNameFromAddress(address, it)
|
||||
}
|
||||
|
||||
context.showReceivedMessageNotification(
|
||||
messageId = mms.id,
|
||||
address = address,
|
||||
senderName = senderName,
|
||||
body = mms.body,
|
||||
threadId = mms.threadId,
|
||||
bitmap = glideBitmap
|
||||
)
|
||||
|
||||
ensureBackgroundThread {
|
||||
val conversation = context.getConversations(mms.threadId).firstOrNull()
|
||||
?: return@ensureBackgroundThread
|
||||
context.insertOrUpdateConversation(conversation)
|
||||
val conversation = context.getConversations(mms.threadId).firstOrNull() ?: return
|
||||
runCatching { context.insertOrUpdateConversation(conversation) }
|
||||
if (context.shouldUnarchive()) {
|
||||
context.updateConversationArchivedStatus(mms.threadId, false)
|
||||
}
|
||||
|
|
@ -96,5 +96,3 @@ class MmsReceiver : MmsReceivedReceiver() {
|
|||
refreshConversations()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ package org.fossify.messages.receivers
|
|||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.provider.Telephony
|
||||
import org.fossify.commons.extensions.baseConfig
|
||||
import org.fossify.commons.extensions.getMyContactsCursor
|
||||
|
|
@ -29,104 +27,128 @@ import org.fossify.messages.helpers.refreshMessages
|
|||
import org.fossify.messages.models.Message
|
||||
|
||||
class SmsReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val messages = Telephony.Sms.Intents.getMessagesFromIntent(intent)
|
||||
var address = ""
|
||||
var body = ""
|
||||
var subject = ""
|
||||
var date = 0L
|
||||
var threadId = 0L
|
||||
var status = Telephony.Sms.STATUS_NONE
|
||||
val type = Telephony.Sms.MESSAGE_TYPE_INBOX
|
||||
val read = 0
|
||||
val pending = goAsync()
|
||||
val appContext = context.applicationContext
|
||||
|
||||
ensureBackgroundThread {
|
||||
try {
|
||||
val parts = Telephony.Sms.Intents.getMessagesFromIntent(intent)
|
||||
if (parts.isEmpty()) return@ensureBackgroundThread
|
||||
|
||||
// this is how it has always worked, but need to revisit this.
|
||||
val address = parts.last().originatingAddress.orEmpty()
|
||||
if (address.isBlank()) return@ensureBackgroundThread
|
||||
val subject = parts.last().pseudoSubject.orEmpty()
|
||||
val status = parts.last().status
|
||||
val body = buildString { parts.forEach { append(it.messageBody.orEmpty()) } }
|
||||
|
||||
if (isMessageFilteredOut(appContext, body)) return@ensureBackgroundThread
|
||||
if (appContext.isNumberBlocked(address)) return@ensureBackgroundThread
|
||||
if (appContext.baseConfig.blockUnknownNumbers) {
|
||||
appContext.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true).use {
|
||||
val isKnownContact = SimpleContactsHelper(appContext).existsSync(address, it)
|
||||
if (!isKnownContact) return@ensureBackgroundThread
|
||||
}
|
||||
}
|
||||
|
||||
val date = System.currentTimeMillis()
|
||||
val threadId = appContext.getThreadId(address)
|
||||
val subscriptionId = intent.getIntExtra("subscription", -1)
|
||||
|
||||
val privateCursor = context.getMyContactsCursor(false, true)
|
||||
ensureBackgroundThread {
|
||||
messages.forEach {
|
||||
address = it.originatingAddress ?: ""
|
||||
subject = it.pseudoSubject
|
||||
status = it.status
|
||||
body += it.messageBody
|
||||
date = System.currentTimeMillis()
|
||||
threadId = context.getThreadId(address)
|
||||
}
|
||||
if (context.baseConfig.blockUnknownNumbers) {
|
||||
val simpleContactsHelper = SimpleContactsHelper(context)
|
||||
// Maybe switch to existsSync()? No?
|
||||
simpleContactsHelper.exists(address, privateCursor) { exists ->
|
||||
if (exists) {
|
||||
handleMessage(context, address, subject, body, date, read, threadId, type, subscriptionId, status)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handleMessage(context, address, subject, body, date, read, threadId, type, subscriptionId, status)
|
||||
handleMessageSync(
|
||||
context = appContext,
|
||||
address = address,
|
||||
subject = subject,
|
||||
body = body,
|
||||
date = date,
|
||||
threadId = threadId,
|
||||
subscriptionId = subscriptionId,
|
||||
status = status
|
||||
)
|
||||
} finally {
|
||||
pending.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMessage(
|
||||
private fun handleMessageSync(
|
||||
context: Context,
|
||||
address: String,
|
||||
subject: String,
|
||||
body: String,
|
||||
date: Long,
|
||||
read: Int,
|
||||
read: Int = 0,
|
||||
threadId: Long,
|
||||
type: Int,
|
||||
type: Int = Telephony.Sms.MESSAGE_TYPE_INBOX,
|
||||
subscriptionId: Int,
|
||||
status: Int
|
||||
) {
|
||||
if (isMessageFilteredOut(context, body)) {
|
||||
return
|
||||
}
|
||||
|
||||
val photoUri = SimpleContactsHelper(context).getPhotoUriFromPhoneNumber(address)
|
||||
val bitmap = context.getNotificationBitmap(photoUri)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
if (!context.isNumberBlocked(address)) {
|
||||
val privateCursor = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
|
||||
ensureBackgroundThread {
|
||||
val newMessageId = context.insertNewSMS(address, subject, body, date, read, threadId, type, subscriptionId)
|
||||
|
||||
val conversation = context.getConversations(threadId).firstOrNull() ?: return@ensureBackgroundThread
|
||||
try {
|
||||
context.insertOrUpdateConversation(conversation)
|
||||
} catch (ignored: Exception) {
|
||||
val newMessageId = context.insertNewSMS(
|
||||
address = address,
|
||||
subject = subject,
|
||||
body = body,
|
||||
date = date,
|
||||
read = read,
|
||||
threadId = threadId,
|
||||
type = type,
|
||||
subscriptionId = subscriptionId
|
||||
)
|
||||
|
||||
context.getConversations(threadId).firstOrNull()?.let { conv ->
|
||||
runCatching { context.insertOrUpdateConversation(conv) }
|
||||
}
|
||||
|
||||
val senderName = context.getNameFromAddress(address, privateCursor)
|
||||
val phoneNumber = PhoneNumber(address, 0, "", address)
|
||||
val participant = SimpleContact(0, 0, senderName, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
|
||||
val participants = arrayListOf(participant)
|
||||
val messageDate = (date / 1000).toInt()
|
||||
val senderName = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true).use {
|
||||
context.getNameFromAddress(address, it)
|
||||
}
|
||||
|
||||
val message =
|
||||
Message(
|
||||
newMessageId,
|
||||
body,
|
||||
type,
|
||||
status,
|
||||
participants,
|
||||
messageDate,
|
||||
false,
|
||||
threadId,
|
||||
false,
|
||||
null,
|
||||
address,
|
||||
senderName,
|
||||
photoUri,
|
||||
subscriptionId
|
||||
val participant = SimpleContact(
|
||||
rawId = 0,
|
||||
contactId = 0,
|
||||
name = senderName,
|
||||
photoUri = photoUri,
|
||||
phoneNumbers = arrayListOf(PhoneNumber(value = address, type = 0, label = "", normalizedNumber = address)),
|
||||
birthdays = ArrayList(),
|
||||
anniversaries = ArrayList()
|
||||
)
|
||||
|
||||
val message = Message(
|
||||
id = newMessageId,
|
||||
body = body,
|
||||
type = type,
|
||||
status = status,
|
||||
participants = arrayListOf(participant),
|
||||
date = (date / 1000).toInt(),
|
||||
read = false,
|
||||
threadId = threadId,
|
||||
isMMS = false,
|
||||
attachment = null,
|
||||
senderPhoneNumber = address,
|
||||
senderName = senderName,
|
||||
senderPhotoUri = photoUri,
|
||||
subscriptionId = subscriptionId
|
||||
)
|
||||
|
||||
context.messagesDB.insertOrUpdate(message)
|
||||
|
||||
if (context.shouldUnarchive()) {
|
||||
context.updateConversationArchivedStatus(threadId, false)
|
||||
}
|
||||
|
||||
refreshMessages()
|
||||
refreshConversations()
|
||||
context.showReceivedMessageNotification(newMessageId, address, body, threadId, bitmap)
|
||||
}
|
||||
}
|
||||
}
|
||||
context.showReceivedMessageNotification(
|
||||
messageId = newMessageId,
|
||||
address = address,
|
||||
senderName = senderName,
|
||||
body = body,
|
||||
threadId = threadId,
|
||||
bitmap = bitmap
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue