Rewrite, move SMS related code into the app

This commit is contained in:
Naveen 2023-01-03 15:43:14 +05:30
parent 7bce8ab31b
commit 1f36738be0
16 changed files with 647 additions and 162 deletions

View file

@ -14,7 +14,7 @@ import com.simplemobiletools.smsmessenger.extensions.*
import com.simplemobiletools.smsmessenger.helpers.REPLY
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
import com.simplemobiletools.smsmessenger.helpers.THREAD_NUMBER
import com.simplemobiletools.smsmessenger.helpers.sendMessage
import com.simplemobiletools.smsmessenger.messaging.sendMessageCompat
class DirectReplyReceiver : BroadcastReceiver() {
@SuppressLint("MissingPermission")
@ -38,7 +38,7 @@ class DirectReplyReceiver : BroadcastReceiver() {
ensureBackgroundThread {
try {
context.sendMessage(body, listOf(address), subscriptionId, emptyList())
context.sendMessageCompat(body, listOf(address), subscriptionId, emptyList())
val message = context.getMessages(threadId, getImageResolutions = false, includeScheduledMessages = false, limit = 1).lastOrNull()
if (message != null) {
context.messagesDB.insertOrUpdate(message)

View file

@ -1,15 +1,44 @@
package com.simplemobiletools.smsmessenger.receivers
import android.app.Activity
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.database.sqlite.SQLiteException
import android.net.Uri
import android.provider.Telephony
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
import com.simplemobiletools.smsmessenger.messaging.SendStatusReceiver
import java.io.File
class MmsSentReceiver : com.klinker.android.send_message.MmsSentReceiver() {
override fun onMessageStatusUpdated(context: Context?, intent: Intent?, resultCode: Int) {
super.onMessageStatusUpdated(context, intent, resultCode)
/** Handles updating databases and states when a MMS message is sent. */
class MmsSentReceiver : SendStatusReceiver() {
override fun updateAndroidDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
val uri = Uri.parse(intent.getStringExtra(EXTRA_CONTENT_URI))
val values = ContentValues(1)
values.put(Telephony.Mms.MESSAGE_BOX, Telephony.Mms.MESSAGE_BOX_SENT)
try {
context.contentResolver.update(uri, values, null, null)
} catch (e: SQLiteException) {
context.showErrorToast(e)
}
val filePath = intent.getStringExtra(EXTRA_FILE_PATH)
if (filePath != null) {
File(filePath).delete()
}
}
override fun updateAppDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
if (resultCode == Activity.RESULT_OK) {
refreshMessages()
}
}
companion object {
private const val EXTRA_CONTENT_URI = "content_uri"
private const val EXTRA_FILE_PATH = "file_path"
}
}

View file

@ -16,7 +16,7 @@ import com.simplemobiletools.smsmessenger.extensions.messagesDB
import com.simplemobiletools.smsmessenger.helpers.SCHEDULED_MESSAGE_ID
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
import com.simplemobiletools.smsmessenger.helpers.sendMessage
import com.simplemobiletools.smsmessenger.messaging.sendMessageCompat
class ScheduledMessageReceiver : BroadcastReceiver() {
@ -46,7 +46,7 @@ class ScheduledMessageReceiver : BroadcastReceiver() {
try {
Handler(Looper.getMainLooper()).post {
context.sendMessage(message.body, addresses, message.subscriptionId, attachments)
context.sendMessageCompat(message.body, addresses, message.subscriptionId, attachments)
}
// delete temporary conversation and message as it's already persisted to the telephony db now

View file

@ -1,26 +1,90 @@
package com.simplemobiletools.smsmessenger.receivers
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import com.klinker.android.send_message.DeliveredReceiver
import android.provider.Telephony.Sms
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.smsmessenger.extensions.messagesDB
import com.simplemobiletools.smsmessenger.extensions.updateMessageStatus
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
import com.simplemobiletools.smsmessenger.messaging.SendStatusReceiver
class SmsStatusDeliveredReceiver : DeliveredReceiver() {
/** Handles updating databases and states when a sent SMS message is delivered. */
class SmsStatusDeliveredReceiver : SendStatusReceiver() {
override fun onMessageStatusUpdated(context: Context, intent: Intent, receiverResultCode: Int) {
if (intent.extras?.containsKey("message_uri") == true) {
val uri = Uri.parse(intent.getStringExtra("message_uri"))
val messageId = uri?.lastPathSegment?.toLong() ?: 0L
override fun updateAndroidDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
val uri: Uri? = intent.data
val resultCode = resultCode
try {
when (resultCode) {
Activity.RESULT_OK -> {
if (uri != null) {
val values = ContentValues().apply {
put(Sms.Sent.STATUS, Sms.Sent.STATUS_COMPLETE)
put(Sms.Sent.DATE_SENT, System.currentTimeMillis())
put(Sms.Sent.READ, true)
}
context.contentResolver.update(uri, values, null, null)
} else {
updateLatestSmsStatus(context, status = Sms.Sent.STATUS_COMPLETE, read = true, date = System.currentTimeMillis())
}
}
Activity.RESULT_CANCELED -> {
if (uri != null) {
val values = ContentValues().apply {
put(Sms.Sent.STATUS, Sms.Sent.STATUS_FAILED)
put(Sms.Sent.DATE_SENT, System.currentTimeMillis())
put(Sms.Sent.READ, true)
put(Sms.Sent.ERROR_CODE, resultCode)
}
context.contentResolver.update(uri, values, null, null)
} else {
updateLatestSmsStatus(context, status = Sms.Sent.STATUS_FAILED, read = true, errorCode = resultCode)
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
@SuppressLint("Range")
private fun updateLatestSmsStatus(context: Context, status: Int, read: Boolean, date: Long = -1L, errorCode: Int = -1) {
val query = context.contentResolver.query(Sms.Sent.CONTENT_URI, null, null, null, "date desc")
// mark message as delivered in database
if (query!!.moveToFirst()) {
val id = query.getString(query.getColumnIndex(Sms.Sent._ID))
val values = ContentValues().apply {
put(Sms.Sent.STATUS, status)
put(Sms.Sent.READ, read)
if (date != -1L) {
put(Sms.Sent.DATE_SENT, date)
}
if (errorCode != -1) {
put(Sms.Sent.ERROR_CODE, errorCode)
}
}
context.contentResolver.update(Sms.Sent.CONTENT_URI, values, "_id=$id", null)
}
query.close()
}
override fun updateAppDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
val uri = intent.data
if (uri != null) {
val messageId = uri.lastPathSegment?.toLong() ?: 0L
ensureBackgroundThread {
val status = Telephony.Sms.STATUS_COMPLETE
context.updateMessageStatus(messageId, status)
val status = Sms.Sent.STATUS_COMPLETE
val updated = context.messagesDB.updateStatus(messageId, status)
if (updated == 0) {
Handler(Looper.getMainLooper()).postDelayed({

View file

@ -1,35 +1,98 @@
package com.simplemobiletools.smsmessenger.receivers
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import android.provider.Telephony.Sms
import android.telephony.SmsManager.RESULT_ERROR_GENERIC_FAILURE
import android.telephony.SmsManager.RESULT_ERROR_NO_SERVICE
import android.telephony.SmsManager.RESULT_ERROR_NULL_PDU
import android.telephony.SmsManager.RESULT_ERROR_RADIO_OFF
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ProcessLifecycleOwner
import com.klinker.android.send_message.SentReceiver
import com.simplemobiletools.commons.extensions.getMyContactsCursor
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.smsmessenger.extensions.*
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
import com.simplemobiletools.smsmessenger.messaging.SendStatusReceiver
class SmsStatusSentReceiver : SentReceiver() {
/** Handles updating databases and states when a SMS message is sent. */
@SuppressLint("Range")
class SmsStatusSentReceiver : SendStatusReceiver() {
override fun onMessageStatusUpdated(context: Context, intent: Intent, receiverResultCode: Int) {
if (intent.extras?.containsKey("message_uri") == true) {
val uri = Uri.parse(intent.getStringExtra("message_uri"))
val messageId = uri?.lastPathSegment?.toLong() ?: 0L
override fun updateAndroidDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
val messageUri: Uri? = intent.data
val resultCode = resultCode
try {
when (resultCode) {
Activity.RESULT_OK -> if (messageUri != null) {
try {
val values = ContentValues()
values.put(Sms.Outbox.TYPE, Sms.MESSAGE_TYPE_SENT)
values.put(Sms.Outbox.READ, 1)
context.contentResolver.update(messageUri, values, null, null)
} catch (e: NullPointerException) {
updateLatestSms(context = context, type = Sms.MESSAGE_TYPE_SENT, read = 1)
}
} else {
updateLatestSms(context = context, type = Sms.MESSAGE_TYPE_FAILED, read = 1)
}
RESULT_ERROR_GENERIC_FAILURE, RESULT_ERROR_NO_SERVICE, RESULT_ERROR_NULL_PDU, RESULT_ERROR_RADIO_OFF -> {
if (messageUri != null) {
val values = ContentValues()
values.put(Sms.Outbox.TYPE, Sms.MESSAGE_TYPE_FAILED)
values.put(Sms.Outbox.READ, true)
values.put(Sms.Outbox.ERROR_CODE, resultCode)
context.contentResolver.update(messageUri, values, null, null)
} else {
updateLatestSms(context = context, type = Sms.MESSAGE_TYPE_FAILED, read = 1, resultCode = resultCode)
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
context.messagingUtils.maybeShowErrorToast(
resultCode = resultCode,
errorCode = intent.getIntExtra(EXTRA_ERROR_CODE, NO_ERROR_CODE)
)
}
private fun updateLatestSms(context: Context, type: Int, read: Int, resultCode: Int = -1) {
val query = context.contentResolver.query(Sms.Outbox.CONTENT_URI, null, null, null, null)
if (query != null && query.moveToFirst()) {
val id = query.getString(query.getColumnIndex(Sms.Outbox._ID))
val values = ContentValues()
values.put(Sms.Outbox.TYPE, type)
values.put(Sms.Outbox.READ, read)
if (resultCode != -1) {
values.put(Sms.Outbox.ERROR_CODE, resultCode)
}
context.contentResolver.update(Sms.Outbox.CONTENT_URI, values, "_id=$id", null)
query.close()
}
}
override fun updateAppDatabase(context: Context, intent: Intent, receiverResultCode: Int) {
val uri = intent.data
if (uri != null) {
val messageId = uri.lastPathSegment?.toLong() ?: 0L
ensureBackgroundThread {
val type = if (receiverResultCode == Activity.RESULT_OK) {
Telephony.Sms.MESSAGE_TYPE_SENT
Sms.MESSAGE_TYPE_SENT
} else {
showSendingFailedNotification(context, messageId)
Telephony.Sms.MESSAGE_TYPE_FAILED
Sms.MESSAGE_TYPE_FAILED
}
context.updateMessageType(messageId, type)
val updated = context.messagesDB.updateType(messageId, type)
if (updated == 0) {
Handler(Looper.getMainLooper()).postDelayed({