Merge branch 'master' into export_import_settings

This commit is contained in:
Konstantin Merenkov 2023-07-18 16:27:09 +10:00 committed by GitHub
commit 321e4f11ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 1266 additions and 63 deletions

View file

@ -0,0 +1,89 @@
package com.simplemobiletools.smsmessenger.activities
import android.os.Bundle
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.getProperPrimaryColor
import com.simplemobiletools.commons.extensions.underlineText
import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.commons.helpers.APP_ICON_IDS
import com.simplemobiletools.commons.helpers.APP_LAUNCHER_NAME
import com.simplemobiletools.commons.helpers.NavigationIcon
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.dialogs.AddBlockedKeywordDialog
import com.simplemobiletools.smsmessenger.dialogs.ManageBlockedKeywordsAdapter
import com.simplemobiletools.smsmessenger.extensions.config
import com.simplemobiletools.smsmessenger.extensions.toArrayList
import kotlinx.android.synthetic.main.activity_manage_blocked_keywords.*
class ManageBlockedKeywordsActivity : BaseSimpleActivity(), RefreshRecyclerViewListener {
override fun getAppIconIDs() = intent.getIntegerArrayListExtra(APP_ICON_IDS) ?: ArrayList()
override fun getAppLauncherName() = intent.getStringExtra(APP_LAUNCHER_NAME) ?: ""
override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_manage_blocked_keywords)
updateBlockedKeywords()
setupOptionsMenu()
updateMaterialActivityViews(block_keywords_coordinator, manage_blocked_keywords_list, useTransparentNavigation = true, useTopSearchMenu = false)
setupMaterialScrollListener(manage_blocked_keywords_list, block_keywords_toolbar)
updateTextColors(manage_blocked_keywords_wrapper)
manage_blocked_keywords_placeholder_2.apply {
underlineText()
setTextColor(getProperPrimaryColor())
setOnClickListener {
addOrEditBlockedKeyword()
}
}
}
override fun onResume() {
super.onResume()
setupToolbar(block_keywords_toolbar, NavigationIcon.Arrow)
}
private fun setupOptionsMenu() {
block_keywords_toolbar.setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
R.id.add_blocked_keyword -> {
addOrEditBlockedKeyword()
true
}
else -> false
}
}
}
override fun refreshItems() {
updateBlockedKeywords()
}
private fun updateBlockedKeywords() {
ensureBackgroundThread {
val blockedKeywords = config.blockedKeywords
runOnUiThread {
ManageBlockedKeywordsAdapter(this, blockedKeywords.toArrayList(), this, manage_blocked_keywords_list) {
addOrEditBlockedKeyword(it as String)
}.apply {
manage_blocked_keywords_list.adapter = this
}
manage_blocked_keywords_placeholder.beVisibleIf(blockedKeywords.isEmpty())
manage_blocked_keywords_placeholder_2.beVisibleIf(blockedKeywords.isEmpty())
}
}
}
private fun addOrEditBlockedKeyword(keyword: String? = null) {
AddBlockedKeywordDialog(this, keyword) {
updateBlockedKeywords()
}
}
}

View file

@ -48,6 +48,7 @@ class SettingsActivity : SimpleActivity() {
setupUseEnglish()
setupLanguage()
setupManageBlockedNumbers()
setupManageBlockedKeywords()
setupChangeDateTimeFormat()
setupFontSize()
setupShowCharacterCounter()
@ -212,6 +213,20 @@ class SettingsActivity : SimpleActivity() {
}
}
private fun setupManageBlockedKeywords() {
settings_manage_blocked_keywords.text = addLockedLabelIfNeeded(R.string.manage_blocked_keywords)
settings_manage_blocked_keywords_holder.setOnClickListener {
if (isOrWasThankYouInstalled()) {
Intent(this, ManageBlockedKeywordsActivity::class.java).apply {
startActivity(this)
}
} else {
FeatureLockedDialog(this) { }
}
}
}
private fun setupChangeDateTimeFormat() {
settings_change_date_time_format_holder.setOnClickListener {
ChangeDateTimeFormatDialog(this) {

View file

@ -1606,6 +1606,7 @@ class ThreadActivity : SimpleActivity() {
threadId = threadId,
isMMS = isMmsMessage(text),
attachment = MessageAttachment(messageId, text, buildMessageAttachments(messageId)),
senderPhoneNumber = "",
senderName = "",
senderPhotoUri = "",
subscriptionId = subscriptionId,

View file

@ -33,6 +33,7 @@ import com.simplemobiletools.smsmessenger.activities.NewConversationActivity
import com.simplemobiletools.smsmessenger.activities.SimpleActivity
import com.simplemobiletools.smsmessenger.activities.ThreadActivity
import com.simplemobiletools.smsmessenger.activities.VCardViewerActivity
import com.simplemobiletools.smsmessenger.dialogs.MessageDetailsDialog
import com.simplemobiletools.smsmessenger.dialogs.SelectTextDialog
import com.simplemobiletools.smsmessenger.extensions.*
import com.simplemobiletools.smsmessenger.helpers.*
@ -82,6 +83,7 @@ class ThreadAdapter(
findItem(R.id.cab_share).isVisible = isOneItemSelected && hasText
findItem(R.id.cab_forward_message).isVisible = isOneItemSelected
findItem(R.id.cab_select_text).isVisible = isOneItemSelected && hasText
findItem(R.id.cab_properties).isVisible = isOneItemSelected
}
}
@ -98,6 +100,7 @@ class ThreadAdapter(
R.id.cab_select_text -> selectText()
R.id.cab_delete -> askConfirmDelete()
R.id.cab_select_all -> selectAll()
R.id.cab_properties -> showMessageDetails()
}
}
@ -184,6 +187,11 @@ class ThreadAdapter(
}
}
private fun showMessageDetails() {
val message = getSelectedItems().firstOrNull() as? Message ?: return
MessageDetailsDialog(activity, message)
}
private fun askConfirmDelete() {
val itemsCnt = selectedKeys.size
@ -283,7 +291,7 @@ class ThreadAdapter(
view.apply {
thread_message_sender_photo.beVisible()
thread_message_sender_photo.setOnClickListener {
val contact = message.participants.first()
val contact = message.getSender()!!
context.getContactFromAddress(contact.phoneNumbers.first().normalizedNumber) {
if (it != null) {
activity.startContactDetailsIntent(it)

View file

@ -17,7 +17,7 @@ import com.simplemobiletools.smsmessenger.models.Conversation
import com.simplemobiletools.smsmessenger.models.Message
import com.simplemobiletools.smsmessenger.models.MessageAttachment
@Database(entities = [Conversation::class, Attachment::class, MessageAttachment::class, Message::class], version = 6)
@Database(entities = [Conversation::class, Attachment::class, MessageAttachment::class, Message::class], version = 7)
@TypeConverters(Converters::class)
abstract class MessagesDatabase : RoomDatabase() {
@ -43,6 +43,7 @@ abstract class MessagesDatabase : RoomDatabase() {
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.addMigrations(MIGRATION_5_6)
.addMigrations(MIGRATION_6_7)
.build()
}
}
@ -106,5 +107,13 @@ abstract class MessagesDatabase : RoomDatabase() {
}
}
}
private val MIGRATION_6_7 = object : Migration(6, 7) {
override fun migrate(database: SupportSQLiteDatabase) {
database.apply {
execSQL("ALTER TABLE messages ADD COLUMN sender_phone_number TEXT NOT NULL DEFAULT ''")
}
}
}
}
}

View file

@ -0,0 +1,43 @@
package com.simplemobiletools.smsmessenger.dialogs
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.showKeyboard
import com.simplemobiletools.commons.extensions.value
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.extensions.config
import kotlinx.android.synthetic.main.dialog_add_blocked_keyword.view.add_blocked_keyword_edittext
class AddBlockedKeywordDialog(val activity: BaseSimpleActivity, private val originalKeyword: String? = null, val callback: () -> Unit) {
init {
val view = activity.layoutInflater.inflate(R.layout.dialog_add_blocked_keyword, null).apply {
if (originalKeyword != null) {
add_blocked_keyword_edittext.setText(originalKeyword)
}
}
activity.getAlertDialogBuilder()
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null)
.apply {
activity.setupDialogStuff(view, this) { alertDialog ->
alertDialog.showKeyboard(view.add_blocked_keyword_edittext)
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
val newBlockedKeyword = view.add_blocked_keyword_edittext.value
if (originalKeyword != null && newBlockedKeyword != originalKeyword) {
activity.config.removeBlockedKeyword(originalKeyword)
}
if (newBlockedKeyword.isNotEmpty()) {
activity.config.addBlockedKeyword(newBlockedKeyword)
}
callback()
alertDialog.dismiss()
}
}
}
}
}

View file

@ -15,6 +15,7 @@ import kotlinx.android.synthetic.main.dialog_export_messages.view.export_message
import kotlinx.android.synthetic.main.dialog_export_messages.view.export_mms_checkbox
import kotlinx.android.synthetic.main.dialog_export_messages.view.export_sms_checkbox
class ExportMessagesDialog(
private val activity: SimpleActivity,
private val callback: (fileName: String) -> Unit,
@ -39,6 +40,7 @@ class ExportMessagesDialog(
filename.isAValidFilename() -> {
callback(filename)
alertDialog.dismiss()
}
else -> activity.toast(R.string.invalid_name)

View file

@ -0,0 +1,148 @@
package com.simplemobiletools.smsmessenger.dialogs
import android.view.*
import android.widget.PopupMenu
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.extensions.copyToClipboard
import com.simplemobiletools.commons.extensions.getPopupMenuTheme
import com.simplemobiletools.commons.extensions.getProperTextColor
import com.simplemobiletools.commons.extensions.setupViewBackground
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.extensions.config
import kotlinx.android.synthetic.main.item_manage_blocked_keyword.view.manage_blocked_keyword_holder
import kotlinx.android.synthetic.main.item_manage_blocked_keyword.view.manage_blocked_keyword_title
import kotlinx.android.synthetic.main.item_manage_blocked_keyword.view.overflow_menu_anchor
import kotlinx.android.synthetic.main.item_manage_blocked_keyword.view.overflow_menu_icon
class ManageBlockedKeywordsAdapter(
activity: BaseSimpleActivity, var blockedKeywords: ArrayList<String>, val listener: RefreshRecyclerViewListener?,
recyclerView: MyRecyclerView, itemClick: (Any) -> Unit
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
init {
setupDragListener(true)
}
override fun getActionMenuId() = R.menu.cab_blocked_keywords
override fun prepareActionMode(menu: Menu) {
menu.apply {
findItem(R.id.cab_copy_keyword).isVisible = isOneItemSelected()
}
}
override fun actionItemPressed(id: Int) {
if (selectedKeys.isEmpty()) {
return
}
when (id) {
R.id.cab_copy_keyword -> copyKeywordToClipboard()
R.id.cab_delete -> deleteSelection()
}
}
override fun getSelectableItemCount() = blockedKeywords.size
override fun getIsItemSelectable(position: Int) = true
override fun getItemSelectionKey(position: Int) = blockedKeywords.getOrNull(position)?.hashCode()
override fun getItemKeyPosition(key: Int) = blockedKeywords.indexOfFirst { it.hashCode() == key }
override fun onActionModeCreated() {}
override fun onActionModeDestroyed() {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_manage_blocked_keyword, parent)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val blockedKeyword = blockedKeywords[position]
holder.bindView(blockedKeyword, true, true) { itemView, _ ->
setupView(itemView, blockedKeyword)
}
bindViewHolder(holder)
}
override fun getItemCount() = blockedKeywords.size
private fun getSelectedItems() = blockedKeywords.filter { selectedKeys.contains(it.hashCode()) }
private fun setupView(view: View, blockedKeyword: String) {
view.apply {
setupViewBackground(activity)
manage_blocked_keyword_holder?.isSelected = selectedKeys.contains(blockedKeyword.hashCode())
manage_blocked_keyword_title.apply {
text = blockedKeyword
setTextColor(textColor)
}
overflow_menu_icon.drawable.apply {
mutate()
setTint(activity.getProperTextColor())
}
overflow_menu_icon.setOnClickListener {
showPopupMenu(overflow_menu_anchor, blockedKeyword)
}
}
}
private fun showPopupMenu(view: View, blockedKeyword: String) {
finishActMode()
val theme = activity.getPopupMenuTheme()
val contextTheme = ContextThemeWrapper(activity, theme)
PopupMenu(contextTheme, view, Gravity.END).apply {
inflate(getActionMenuId())
setOnMenuItemClickListener { item ->
val blockedKeywordId = blockedKeyword.hashCode()
when (item.itemId) {
R.id.cab_copy_keyword -> {
executeItemMenuOperation(blockedKeywordId) {
copyKeywordToClipboard()
}
}
R.id.cab_delete -> {
executeItemMenuOperation(blockedKeywordId) {
deleteSelection()
}
}
}
true
}
show()
}
}
private fun executeItemMenuOperation(blockedKeywordId: Int, callback: () -> Unit) {
selectedKeys.add(blockedKeywordId)
callback()
selectedKeys.remove(blockedKeywordId)
}
private fun copyKeywordToClipboard() {
val selectedKeyword = getSelectedItems().firstOrNull() ?: return
activity.copyToClipboard(selectedKeyword)
finishActMode()
}
private fun deleteSelection() {
val deleteBlockedKeywords = HashSet<String>(selectedKeys.size)
val positions = getSelectedItemPositions()
getSelectedItems().forEach {
deleteBlockedKeywords.add(it)
activity.config.removeBlockedKeyword(it)
}
blockedKeywords.removeAll(deleteBlockedKeywords)
removeSelectedItems(positions)
if (blockedKeywords.isEmpty()) {
listener?.refreshItems()
}
}
}

View file

@ -0,0 +1,73 @@
package com.simplemobiletools.smsmessenger.dialogs
import android.annotation.SuppressLint
import android.telephony.SubscriptionInfo
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.BasePropertiesDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.extensions.config
import com.simplemobiletools.smsmessenger.extensions.subscriptionManagerCompat
import com.simplemobiletools.smsmessenger.models.Message
import org.joda.time.DateTime
class MessageDetailsDialog(val activity: BaseSimpleActivity, val message: Message) : BasePropertiesDialog(activity) {
init {
@SuppressLint("MissingPermission")
val availableSIMs = activity.subscriptionManagerCompat().activeSubscriptionInfoList
addProperty(message.getSenderOrReceiverLabel(), message.getSenderOrReceiverPhoneNumbers())
if (availableSIMs.count() > 1) {
addProperty(R.string.message_details_sim, message.getSIM(availableSIMs))
}
addProperty(message.getSentOrReceivedAtLabel(), message.getSentOrReceivedAt())
activity.getAlertDialogBuilder()
.setPositiveButton(R.string.ok) { _, _ -> }
.apply {
activity.setupDialogStuff(mDialogView, this, R.string.message_details)
}
}
private fun Message.getSenderOrReceiverLabel(): Int {
return if (isReceivedMessage()) {
R.string.message_details_sender
} else {
R.string.message_details_receiver
}
}
private fun Message.getSenderOrReceiverPhoneNumbers(): String {
return if (isReceivedMessage()) {
formatContactInfo(senderName, senderPhoneNumber)
} else {
participants.joinToString(", ") {
formatContactInfo(it.name, it.phoneNumbers.first().value)
}
}
}
private fun formatContactInfo(name: String, phoneNumber: String): String {
return if (name != phoneNumber) {
"$name ($phoneNumber)"
} else {
phoneNumber
}
}
private fun Message.getSIM(availableSIMs: List<SubscriptionInfo>): String {
return availableSIMs.firstOrNull { it.subscriptionId == subscriptionId }?.displayName?.toString() ?: activity.getString(R.string.unknown)
}
private fun Message.getSentOrReceivedAtLabel(): Int {
return if (isReceivedMessage()) {
R.string.message_details_received_at
} else {
R.string.message_details_sent_at
}
}
private fun Message.getSentOrReceivedAt(): String {
return DateTime(date * 1000L).toString("${activity.config.dateFormat} ${activity.getTimeFormat()}")
}
}

View file

@ -116,7 +116,23 @@ fun Context.getMessages(
SimpleContact(0, 0, participantPhoto.name, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
}
val isMMS = false
val message = Message(id, body, type, status, ArrayList(participants), date, read, thread, isMMS, null, senderName, photoUri, subscriptionId)
val message =
Message(
id,
body,
type,
status,
ArrayList(participants),
date,
read,
thread,
isMMS,
null,
senderNumber,
senderName,
photoUri,
subscriptionId
)
messages.add(message)
}
@ -189,17 +205,34 @@ fun Context.getMMS(threadId: Long? = null, getImageResolutions: Boolean = false,
val isMMS = true
val attachment = getMmsAttachment(mmsId, getImageResolutions)
val body = attachment.text
var senderNumber = ""
var senderName = ""
var senderPhotoUri = ""
if (type != Mms.MESSAGE_BOX_SENT && type != Mms.MESSAGE_BOX_FAILED) {
val number = getMMSSender(mmsId)
val namePhoto = getNameAndPhotoFromPhoneNumber(number)
senderNumber = getMMSSender(mmsId)
val namePhoto = getNameAndPhotoFromPhoneNumber(senderNumber)
senderName = namePhoto.name
senderPhotoUri = namePhoto.photoUri ?: ""
}
val message = Message(mmsId, body, type, status, participants, date, read, threadId, isMMS, attachment, senderName, senderPhotoUri, subscriptionId)
val message =
Message(
mmsId,
body,
type,
status,
participants,
date,
read,
threadId,
isMMS,
attachment,
senderNumber,
senderName,
senderPhotoUri,
subscriptionId
)
messages.add(message)
participants.forEach {
@ -557,7 +590,16 @@ fun Context.getNameAndPhotoFromPhoneNumber(number: String): NamePhoto {
return NamePhoto(number, null)
}
fun Context.insertNewSMS(address: String, subject: String, body: String, date: Long, read: Int, threadId: Long, type: Int, subscriptionId: Int): Long {
fun Context.insertNewSMS(
address: String,
subject: String,
body: String,
date: Long,
read: Int,
threadId: Long,
type: Int,
subscriptionId: Int
): Long {
val uri = Sms.CONTENT_URI
val contentValues = ContentValues().apply {
put(Sms.ADDRESS, address)

View file

@ -68,6 +68,18 @@ class Config(context: Context) : BaseConfig(context) {
pinnedConversations = pinnedConversations.minus(conversations.map { it.threadId.toString() })
}
var blockedKeywords: Set<String>
get() = prefs.getStringSet(BLOCKED_KEYWORDS, HashSet<String>())!!
set(blockedKeywords) = prefs.edit().putStringSet(BLOCKED_KEYWORDS, blockedKeywords).apply()
fun addBlockedKeyword(keyword: String) {
blockedKeywords = blockedKeywords.plus(keyword)
}
fun removeBlockedKeyword(keyword: String) {
blockedKeywords = blockedKeywords.minus(keyword)
}
var exportSms: Boolean
get() = prefs.getBoolean(EXPORT_SMS, true)
set(exportSms) = prefs.edit().putBoolean(EXPORT_SMS, exportSms).apply()

View file

@ -25,10 +25,13 @@ const val SEND_LONG_MESSAGE_MMS = "send_long_message_mms"
const val SEND_GROUP_MESSAGE_MMS = "send_group_message_mms"
const val MMS_FILE_SIZE_LIMIT = "mms_file_size_limit"
const val PINNED_CONVERSATIONS = "pinned_conversations"
const val BLOCKED_KEYWORDS = "blocked_keywords"
const val EXPORT_SMS = "export_sms"
const val EXPORT_MMS = "export_mms"
const val EXPORT_MIME_TYPE = "application/json"
const val EXPORT_FILE_EXT = ".json"
const val JSON_FILE_EXTENSION = ".json"
const val JSON_MIME_TYPE = "application/json"
const val XML_MIME_TYPE = "text/xml"
const val TXT_MIME_TYPE = "text/plain"
const val IMPORT_SMS = "import_sms"
const val IMPORT_MMS = "import_mms"
const val WAS_DB_CLEARED = "was_db_cleared_2"

View file

@ -6,6 +6,7 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.smsmessenger.extensions.config
import com.simplemobiletools.smsmessenger.models.*
class MessagesImporter(private val context: Context) {
private val messageWriter = MessagesWriter(context)

View file

@ -58,7 +58,6 @@ class MessagesReader(private val context: Context) {
smsList.add(SmsBackup(subscriptionId, address, body, date, dateSent, locked, protocol, read, status, type, serviceCenter))
}
}
return smsList
}

View file

@ -18,6 +18,7 @@ data class Message(
@ColumnInfo(name = "thread_id") val threadId: Long,
@ColumnInfo(name = "is_mms") val isMMS: Boolean,
@ColumnInfo(name = "attachment") val attachment: MessageAttachment?,
@ColumnInfo(name = "sender_phone_number") val senderPhoneNumber: String,
@ColumnInfo(name = "sender_name") var senderName: String,
@ColumnInfo(name = "sender_photo_uri") val senderPhotoUri: String,
@ColumnInfo(name = "subscription_id") var subscriptionId: Int,
@ -28,6 +29,11 @@ data class Message(
fun millis() = date * 1000L
fun getSender(): SimpleContact? =
participants.firstOrNull { it.doesHavePhoneNumber(senderPhoneNumber) }
?: participants.firstOrNull { it.name == senderName }
?: participants.firstOrNull()
companion object {
fun getStableId(message: Message): Long {
@ -37,6 +43,7 @@ data class Message(
result = 31 * result + message.threadId.hashCode()
result = 31 * result + message.isMMS.hashCode()
result = 31 * result + (message.attachment?.hashCode() ?: 0)
result = 31 * result + message.senderPhoneNumber.hashCode()
result = 31 * result + message.senderName.hashCode()
result = 31 * result + message.senderPhotoUri.hashCode()
result = 31 * result + message.isScheduled.hashCode()
@ -53,6 +60,7 @@ data class Message(
old.date == new.date &&
old.isMMS == new.isMMS &&
old.attachment == new.attachment &&
old.senderPhoneNumber == new.senderPhoneNumber &&
old.senderName == new.senderName &&
old.senderPhotoUri == new.senderPhotoUri &&
old.isScheduled == new.isScheduled

View file

@ -37,13 +37,15 @@ class DirectReplyReceiver : BroadcastReceiver() {
}
ensureBackgroundThread {
var messageId: Long = 0L
var messageId = 0L
try {
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)
messageId = message.id
context.updateLastConversationMessage(threadId)
}
} catch (e: Exception) {
context.showErrorToast(e)

View file

@ -5,6 +5,7 @@ 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 com.simplemobiletools.commons.extensions.isNumberBlocked
import com.simplemobiletools.commons.extensions.normalizePhoneNumber
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
@ -13,7 +14,7 @@ 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 : MmsReceivedReceiver() {
override fun isAddressBlocked(context: Context, address: String): Boolean {
val normalizedAddress = address.normalizePhoneNumber()
@ -22,7 +23,7 @@ class MmsReceiver : com.klinker.android.send_message.MmsReceivedReceiver() {
override fun onMessageReceived(context: Context, messageUri: Uri) {
val mms = context.getLatestMMS() ?: return
val address = mms.participants.firstOrNull()?.phoneNumbers?.first()?.normalizedNumber ?: ""
val address = mms.getSender()?.phoneNumbers?.first()?.normalizedNumber ?: ""
val size = context.resources.getDimension(R.dimen.notification_large_icon_size).toInt()
ensureBackgroundThread {

View file

@ -55,8 +55,21 @@ class SmsReceiver : BroadcastReceiver() {
}
private fun handleMessage(
context: Context, address: String, subject: String, body: String, date: Long, read: Int, threadId: Long, type: Int, subscriptionId: Int, status: Int
context: Context,
address: String,
subject: String,
body: String,
date: Long,
read: Int,
threadId: Long,
type: Int,
subscriptionId: Int,
status: Int
) {
if (isMessageFilteredOut(context, body)) {
return
}
val photoUri = SimpleContactsHelper(context).getPhotoUriFromPhoneNumber(address)
val bitmap = context.getNotificationBitmap(photoUri)
Handler(Looper.getMainLooper()).post {
@ -83,7 +96,22 @@ class SmsReceiver : BroadcastReceiver() {
val messageDate = (date / 1000).toInt()
val message =
Message(newMessageId, body, type, status, participants, messageDate, false, threadId, false, null, senderName, photoUri, subscriptionId)
Message(
newMessageId,
body,
type,
status,
participants,
messageDate,
false,
threadId,
false,
null,
address,
senderName,
photoUri,
subscriptionId
)
context.messagesDB.insertOrUpdate(message)
refreshMessages()
context.showReceivedMessageNotification(newMessageId, address, body, threadId, bitmap)
@ -91,4 +119,14 @@ class SmsReceiver : BroadcastReceiver() {
}
}
}
private fun isMessageFilteredOut(context: Context, body: String): Boolean {
for (blockedKeyword in context.config.blockedKeywords) {
if (body.contains(blockedKeyword, ignoreCase = true)) {
return true
}
}
return false
}
}