Skip to content

Commit 1e3f5e5

Browse files
authored
fix: improve sms receiver handling (#642)
* fix: improve sms receiver handling * docs: add comment regarding multiple messages * fix: catch errors when inserting conversation Refs: #159
1 parent ed2aedd commit 1e3f5e5

File tree

4 files changed

+139
-120
lines changed

4 files changed

+139
-120
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Fixed
9+
- Fixed missing notifications in some cases ([#159])
810

911
## [1.7.0] - 2025-12-16
1012
### Added
@@ -188,6 +190,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
188190
[#115]: https://github.com/FossifyOrg/Messages/issues/115
189191
[#135]: https://github.com/FossifyOrg/Messages/issues/135
190192
[#153]: https://github.com/FossifyOrg/Messages/issues/153
193+
[#159]: https://github.com/FossifyOrg/Messages/issues/159
191194
[#165]: https://github.com/FossifyOrg/Messages/issues/165
192195
[#177]: https://github.com/FossifyOrg/Messages/issues/177
193196
[#180]: https://github.com/FossifyOrg/Messages/issues/180

app/src/main/kotlin/org/fossify/messages/extensions/Context.kt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,24 +1050,20 @@ fun Context.getThreadId(addresses: Set<String>): Long {
10501050
fun Context.showReceivedMessageNotification(
10511051
messageId: Long,
10521052
address: String,
1053+
senderName: String,
10531054
body: String,
10541055
threadId: Long,
10551056
bitmap: Bitmap?,
10561057
) {
1057-
val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
1058-
ensureBackgroundThread {
1059-
val senderName = getNameFromAddress(address, privateCursor)
1060-
1061-
Handler(Looper.getMainLooper()).post {
1062-
notificationHelper.showMessageNotification(
1063-
messageId = messageId,
1064-
address = address,
1065-
body = body,
1066-
threadId = threadId,
1067-
bitmap = bitmap,
1068-
sender = senderName
1069-
)
1070-
}
1058+
Handler(Looper.getMainLooper()).post {
1059+
notificationHelper.showMessageNotification(
1060+
messageId = messageId,
1061+
address = address,
1062+
body = body,
1063+
threadId = threadId,
1064+
bitmap = bitmap,
1065+
sender = senderName
1066+
)
10711067
}
10721068
}
10731069

app/src/main/kotlin/org/fossify/messages/receivers/MmsReceiver.kt

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package org.fossify.messages.receivers
22

33
import android.content.Context
44
import android.net.Uri
5-
import android.os.Handler
6-
import android.os.Looper
75
import com.bumptech.glide.Glide
86
import com.klinker.android.send_message.MmsReceivedReceiver
97
import org.fossify.commons.extensions.baseConfig
@@ -16,6 +14,7 @@ import org.fossify.commons.helpers.ensureBackgroundThread
1614
import org.fossify.messages.R
1715
import org.fossify.messages.extensions.getConversations
1816
import org.fossify.messages.extensions.getLatestMMS
17+
import org.fossify.messages.extensions.getNameFromAddress
1918
import org.fossify.messages.extensions.insertOrUpdateConversation
2019
import org.fossify.messages.extensions.shouldUnarchive
2120
import org.fossify.messages.extensions.showReceivedMessageNotification
@@ -31,12 +30,10 @@ class MmsReceiver : MmsReceivedReceiver() {
3130
val normalizedAddress = address.normalizePhoneNumber()
3231
if (context.isNumberBlocked(normalizedAddress)) return true
3332
if (context.baseConfig.blockUnknownNumbers) {
34-
val privateCursor = context.getMyContactsCursor(
35-
favoritesOnly = false,
36-
withPhoneNumbersOnly = true
37-
)
38-
val isKnownContact = SimpleContactsHelper(context).existsSync(address, privateCursor)
39-
return !isKnownContact
33+
context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true).use {
34+
val isKnownContact = SimpleContactsHelper(context).existsSync(address, it)
35+
return !isKnownContact
36+
}
4037
}
4138

4239
return false
@@ -76,25 +73,26 @@ class MmsReceiver : MmsReceivedReceiver() {
7673
null
7774
}
7875

79-
Handler(Looper.getMainLooper()).post {
80-
context.showReceivedMessageNotification(
81-
messageId = mms.id,
82-
address = address,
83-
body = mms.body,
84-
threadId = mms.threadId,
85-
bitmap = glideBitmap
86-
)
8776

88-
ensureBackgroundThread {
89-
val conversation = context.getConversations(mms.threadId).firstOrNull()
90-
?: return@ensureBackgroundThread
91-
context.insertOrUpdateConversation(conversation)
92-
if (context.shouldUnarchive()) {
93-
context.updateConversationArchivedStatus(mms.threadId, false)
94-
}
95-
refreshMessages()
96-
refreshConversations()
97-
}
77+
val senderName = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true).use {
78+
context.getNameFromAddress(address, it)
79+
}
80+
81+
context.showReceivedMessageNotification(
82+
messageId = mms.id,
83+
address = address,
84+
senderName = senderName,
85+
body = mms.body,
86+
threadId = mms.threadId,
87+
bitmap = glideBitmap
88+
)
89+
90+
val conversation = context.getConversations(mms.threadId).firstOrNull() ?: return
91+
runCatching { context.insertOrUpdateConversation(conversation) }
92+
if (context.shouldUnarchive()) {
93+
context.updateConversationArchivedStatus(mms.threadId, false)
9894
}
95+
refreshMessages()
96+
refreshConversations()
9997
}
10098
}

app/src/main/kotlin/org/fossify/messages/receivers/SmsReceiver.kt

Lines changed: 102 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package org.fossify.messages.receivers
33
import android.content.BroadcastReceiver
44
import android.content.Context
55
import android.content.Intent
6-
import android.os.Handler
7-
import android.os.Looper
86
import android.provider.Telephony
97
import org.fossify.commons.extensions.baseConfig
108
import org.fossify.commons.extensions.getMyContactsCursor
@@ -29,104 +27,128 @@ import org.fossify.messages.helpers.refreshMessages
2927
import org.fossify.messages.models.Message
3028

3129
class SmsReceiver : BroadcastReceiver() {
30+
3231
override fun onReceive(context: Context, intent: Intent) {
33-
val messages = Telephony.Sms.Intents.getMessagesFromIntent(intent)
34-
var address = ""
35-
var body = ""
36-
var subject = ""
37-
var date = 0L
38-
var threadId = 0L
39-
var status = Telephony.Sms.STATUS_NONE
40-
val type = Telephony.Sms.MESSAGE_TYPE_INBOX
41-
val read = 0
42-
val subscriptionId = intent.getIntExtra("subscription", -1)
43-
44-
val privateCursor = context.getMyContactsCursor(false, true)
32+
val pending = goAsync()
33+
val appContext = context.applicationContext
34+
4535
ensureBackgroundThread {
46-
messages.forEach {
47-
address = it.originatingAddress ?: ""
48-
subject = it.pseudoSubject
49-
status = it.status
50-
body += it.messageBody
51-
date = System.currentTimeMillis()
52-
threadId = context.getThreadId(address)
53-
}
54-
if (context.baseConfig.blockUnknownNumbers) {
55-
val simpleContactsHelper = SimpleContactsHelper(context)
56-
// Maybe switch to existsSync()? No?
57-
simpleContactsHelper.exists(address, privateCursor) { exists ->
58-
if (exists) {
59-
handleMessage(context, address, subject, body, date, read, threadId, type, subscriptionId, status)
36+
try {
37+
val parts = Telephony.Sms.Intents.getMessagesFromIntent(intent)
38+
if (parts.isEmpty()) return@ensureBackgroundThread
39+
40+
// this is how it has always worked, but need to revisit this.
41+
val address = parts.last().originatingAddress.orEmpty()
42+
if (address.isBlank()) return@ensureBackgroundThread
43+
val subject = parts.last().pseudoSubject.orEmpty()
44+
val status = parts.last().status
45+
val body = buildString { parts.forEach { append(it.messageBody.orEmpty()) } }
46+
47+
if (isMessageFilteredOut(appContext, body)) return@ensureBackgroundThread
48+
if (appContext.isNumberBlocked(address)) return@ensureBackgroundThread
49+
if (appContext.baseConfig.blockUnknownNumbers) {
50+
appContext.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true).use {
51+
val isKnownContact = SimpleContactsHelper(appContext).existsSync(address, it)
52+
if (!isKnownContact) return@ensureBackgroundThread
6053
}
6154
}
62-
} else {
63-
handleMessage(context, address, subject, body, date, read, threadId, type, subscriptionId, status)
55+
56+
val date = System.currentTimeMillis()
57+
val threadId = appContext.getThreadId(address)
58+
val subscriptionId = intent.getIntExtra("subscription", -1)
59+
60+
handleMessageSync(
61+
context = appContext,
62+
address = address,
63+
subject = subject,
64+
body = body,
65+
date = date,
66+
threadId = threadId,
67+
subscriptionId = subscriptionId,
68+
status = status
69+
)
70+
} finally {
71+
pending.finish()
6472
}
6573
}
6674
}
6775

68-
private fun handleMessage(
76+
private fun handleMessageSync(
6977
context: Context,
7078
address: String,
7179
subject: String,
7280
body: String,
7381
date: Long,
74-
read: Int,
82+
read: Int = 0,
7583
threadId: Long,
76-
type: Int,
84+
type: Int = Telephony.Sms.MESSAGE_TYPE_INBOX,
7785
subscriptionId: Int,
7886
status: Int
7987
) {
80-
if (isMessageFilteredOut(context, body)) {
81-
return
82-
}
83-
8488
val photoUri = SimpleContactsHelper(context).getPhotoUriFromPhoneNumber(address)
8589
val bitmap = context.getNotificationBitmap(photoUri)
86-
Handler(Looper.getMainLooper()).post {
87-
if (!context.isNumberBlocked(address)) {
88-
val privateCursor = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
89-
ensureBackgroundThread {
90-
val newMessageId = context.insertNewSMS(address, subject, body, date, read, threadId, type, subscriptionId)
91-
92-
val conversation = context.getConversations(threadId).firstOrNull() ?: return@ensureBackgroundThread
93-
try {
94-
context.insertOrUpdateConversation(conversation)
95-
} catch (ignored: Exception) {
96-
}
9790

98-
val senderName = context.getNameFromAddress(address, privateCursor)
99-
val phoneNumber = PhoneNumber(address, 0, "", address)
100-
val participant = SimpleContact(0, 0, senderName, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
101-
val participants = arrayListOf(participant)
102-
val messageDate = (date / 1000).toInt()
103-
104-
val message =
105-
Message(
106-
newMessageId,
107-
body,
108-
type,
109-
status,
110-
participants,
111-
messageDate,
112-
false,
113-
threadId,
114-
false,
115-
null,
116-
address,
117-
senderName,
118-
photoUri,
119-
subscriptionId
120-
)
121-
context.messagesDB.insertOrUpdate(message)
122-
if (context.shouldUnarchive()) {
123-
context.updateConversationArchivedStatus(threadId, false)
124-
}
125-
refreshMessages()
126-
refreshConversations()
127-
context.showReceivedMessageNotification(newMessageId, address, body, threadId, bitmap)
128-
}
129-
}
91+
val newMessageId = context.insertNewSMS(
92+
address = address,
93+
subject = subject,
94+
body = body,
95+
date = date,
96+
read = read,
97+
threadId = threadId,
98+
type = type,
99+
subscriptionId = subscriptionId
100+
)
101+
102+
context.getConversations(threadId).firstOrNull()?.let { conv ->
103+
runCatching { context.insertOrUpdateConversation(conv) }
130104
}
105+
106+
val senderName = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true).use {
107+
context.getNameFromAddress(address, it)
108+
}
109+
110+
val participant = SimpleContact(
111+
rawId = 0,
112+
contactId = 0,
113+
name = senderName,
114+
photoUri = photoUri,
115+
phoneNumbers = arrayListOf(PhoneNumber(value = address, type = 0, label = "", normalizedNumber = address)),
116+
birthdays = ArrayList(),
117+
anniversaries = ArrayList()
118+
)
119+
120+
val message = Message(
121+
id = newMessageId,
122+
body = body,
123+
type = type,
124+
status = status,
125+
participants = arrayListOf(participant),
126+
date = (date / 1000).toInt(),
127+
read = false,
128+
threadId = threadId,
129+
isMMS = false,
130+
attachment = null,
131+
senderPhoneNumber = address,
132+
senderName = senderName,
133+
senderPhotoUri = photoUri,
134+
subscriptionId = subscriptionId
135+
)
136+
137+
context.messagesDB.insertOrUpdate(message)
138+
139+
if (context.shouldUnarchive()) {
140+
context.updateConversationArchivedStatus(threadId, false)
141+
}
142+
143+
refreshMessages()
144+
refreshConversations()
145+
context.showReceivedMessageNotification(
146+
messageId = newMessageId,
147+
address = address,
148+
senderName = senderName,
149+
body = body,
150+
threadId = threadId,
151+
bitmap = bitmap
152+
)
131153
}
132154
}

0 commit comments

Comments
 (0)