Add message details menu button
Adds a "Properties" menu button in conversation, when one message is selected, which displays details about the message: - Type (SMS or MMS) - Sender phone number (or receiver if it is a sent message) - Used SIM - Date sent at - Date received at (if it is an incoming message) This closes #19
This commit is contained in:
parent
9942fb788a
commit
bdd506c96e
56 changed files with 530 additions and 29 deletions
|
|
@ -1602,6 +1602,7 @@ class ThreadActivity : SimpleActivity() {
|
|||
status = STATUS_NONE,
|
||||
participants = participants,
|
||||
date = (scheduledDateTime.millis / 1000).toInt(),
|
||||
dateSent = (scheduledDateTime.millis / 1000).toInt(),
|
||||
read = false,
|
||||
threadId = threadId,
|
||||
isMMS = isMmsMessage(text),
|
||||
|
|
|
|||
|
|
@ -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,12 @@ class ThreadAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun showMessageDetails() {
|
||||
val message = getSelectedItems().firstOrNull() as? Message ?: return
|
||||
MessageDetailsDialog(activity, message)
|
||||
}
|
||||
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
val itemsCnt = selectedKeys.size
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = 7)
|
||||
@Database(entities = [Conversation::class, Attachment::class, MessageAttachment::class, Message::class], version = 8)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class MessagesDatabase : RoomDatabase() {
|
||||
|
||||
|
|
@ -44,6 +44,7 @@ abstract class MessagesDatabase : RoomDatabase() {
|
|||
.addMigrations(MIGRATION_4_5)
|
||||
.addMigrations(MIGRATION_5_6)
|
||||
.addMigrations(MIGRATION_6_7)
|
||||
.addMigrations(MIGRATION_7_8)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
@ -115,5 +116,14 @@ abstract class MessagesDatabase : RoomDatabase() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val MIGRATION_7_8 = object : Migration(7, 8) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.apply {
|
||||
execSQL("ALTER TABLE messages ADD COLUMN date_sent INTEGER NOT NULL DEFAULT 0")
|
||||
execSQL("UPDATE messages SET date_sent = date")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
package com.simplemobiletools.smsmessenger.dialogs
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.telephony.SubscriptionInfo
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
|
||||
import com.simplemobiletools.commons.extensions.getTimeFormat
|
||||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import com.simplemobiletools.smsmessenger.R
|
||||
import com.simplemobiletools.smsmessenger.extensions.config
|
||||
import com.simplemobiletools.smsmessenger.extensions.subscriptionManagerCompat
|
||||
import com.simplemobiletools.smsmessenger.models.Message
|
||||
import kotlinx.android.synthetic.main.dialog_message_details.view.dialog_message_details_text_value
|
||||
import org.joda.time.DateTime
|
||||
|
||||
class MessageDetailsDialog(val activity: BaseSimpleActivity, val message: Message) {
|
||||
init {
|
||||
@SuppressLint("MissingPermission")
|
||||
val availableSIMs = activity.subscriptionManagerCompat().activeSubscriptionInfoList
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
val view = activity.layoutInflater.inflate(R.layout.dialog_message_details, null).apply {
|
||||
dialog_message_details_text_value.text = """
|
||||
${activity.getString(R.string.message_details_type)}: ${message.getMessageType()}
|
||||
${message.getReceiverOrSenderLabel()}: ${message.getReceiverOrSenderPhoneNumbers()}
|
||||
SIM: ${message.getSIM(availableSIMs)}
|
||||
${activity.getString(R.string.message_details_sent_at)}: ${message.getSentAt()}
|
||||
${message.getReceivedAtLine()}
|
||||
""".trimIndent().trimEnd()
|
||||
}
|
||||
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok) { _, _ -> }
|
||||
.apply {
|
||||
activity.setupDialogStuff(view, this, R.string.message_details)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Message.getMessageType(): String = if (isMMS) "MMS" else "SMS"
|
||||
|
||||
private fun Message.getReceiverOrSenderLabel(): String {
|
||||
return if (isReceivedMessage()) {
|
||||
activity.getString(R.string.message_details_sender)
|
||||
} else {
|
||||
activity.getString(R.string.message_details_receiver)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Message.getReceiverOrSenderPhoneNumbers(): String {
|
||||
return participants.joinToString(", ") { it.phoneNumbers.first().value }
|
||||
}
|
||||
|
||||
private fun Message.getSIM(availableSIMs: List<SubscriptionInfo>): String {
|
||||
return availableSIMs.firstOrNull { it.subscriptionId == subscriptionId }?.displayName?.toString() ?: activity.getString(R.string.unknown)
|
||||
}
|
||||
|
||||
private fun Message.getSentAt(): String {
|
||||
return DateTime(dateSent * 1000L).toString(activity.config.dateFormat + " " + activity.getTimeFormat())
|
||||
}
|
||||
|
||||
private fun Message.getReceivedAtLine(): String {
|
||||
return if (isReceivedMessage()) {
|
||||
"${activity.getString(R.string.message_details_received_at)}: ${getReceivedAt()}"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
private fun Message.getReceivedAt(): String {
|
||||
return DateTime(date * 1000L).toString(activity.config.dateFormat + " " + activity.getTimeFormat())
|
||||
}
|
||||
}
|
||||
|
|
@ -70,6 +70,7 @@ fun Context.getMessages(
|
|||
Sms.TYPE,
|
||||
Sms.ADDRESS,
|
||||
Sms.DATE,
|
||||
Sms.DATE_SENT,
|
||||
Sms.READ,
|
||||
Sms.THREAD_ID,
|
||||
Sms.SUBSCRIPTION_ID,
|
||||
|
|
@ -106,6 +107,7 @@ fun Context.getMessages(
|
|||
val senderName = namePhoto.name
|
||||
val photoUri = namePhoto.photoUri ?: ""
|
||||
val date = (cursor.getLongValue(Sms.DATE) / 1000).toInt()
|
||||
val dateSent = (cursor.getLongValue(Sms.DATE_SENT) / 1000).toInt()
|
||||
val read = cursor.getIntValue(Sms.READ) == 1
|
||||
val thread = cursor.getLongValue(Sms.THREAD_ID)
|
||||
val subscriptionId = cursor.getIntValue(Sms.SUBSCRIPTION_ID)
|
||||
|
|
@ -117,7 +119,23 @@ fun Context.getMessages(
|
|||
}
|
||||
val isMMS = false
|
||||
val message =
|
||||
Message(id, body, type, status, ArrayList(participants), date, read, thread, isMMS, null, senderNumber, senderName, photoUri, subscriptionId)
|
||||
Message(
|
||||
id,
|
||||
body,
|
||||
type,
|
||||
status,
|
||||
ArrayList(participants),
|
||||
date,
|
||||
dateSent,
|
||||
read,
|
||||
thread,
|
||||
isMMS,
|
||||
null,
|
||||
senderNumber,
|
||||
senderName,
|
||||
photoUri,
|
||||
subscriptionId
|
||||
)
|
||||
messages.add(message)
|
||||
}
|
||||
|
||||
|
|
@ -148,6 +166,7 @@ fun Context.getMMS(threadId: Long? = null, getImageResolutions: Boolean = false,
|
|||
val projection = arrayOf(
|
||||
Mms._ID,
|
||||
Mms.DATE,
|
||||
Mms.DATE_SENT,
|
||||
Mms.READ,
|
||||
Mms.MESSAGE_BOX,
|
||||
Mms.THREAD_ID,
|
||||
|
|
@ -175,6 +194,7 @@ fun Context.getMMS(threadId: Long? = null, getImageResolutions: Boolean = false,
|
|||
val mmsId = cursor.getLongValue(Mms._ID)
|
||||
val type = cursor.getIntValue(Mms.MESSAGE_BOX)
|
||||
val date = cursor.getLongValue(Mms.DATE).toInt()
|
||||
val dateSent = cursor.getLongValue(Mms.DATE_SENT).toInt()
|
||||
val read = cursor.getIntValue(Mms.READ) == 1
|
||||
val threadId = cursor.getLongValue(Mms.THREAD_ID)
|
||||
val subscriptionId = cursor.getIntValue(Mms.SUBSCRIPTION_ID)
|
||||
|
|
@ -202,7 +222,23 @@ fun Context.getMMS(threadId: Long? = null, getImageResolutions: Boolean = false,
|
|||
}
|
||||
|
||||
val message =
|
||||
Message(mmsId, body, type, status, participants, date, read, threadId, isMMS, attachment, senderNumber, senderName, senderPhotoUri, subscriptionId)
|
||||
Message(
|
||||
mmsId,
|
||||
body,
|
||||
type,
|
||||
status,
|
||||
participants,
|
||||
date,
|
||||
dateSent,
|
||||
read,
|
||||
threadId,
|
||||
isMMS,
|
||||
attachment,
|
||||
senderNumber,
|
||||
senderName,
|
||||
senderPhotoUri,
|
||||
subscriptionId
|
||||
)
|
||||
messages.add(message)
|
||||
|
||||
participants.forEach {
|
||||
|
|
@ -560,13 +596,24 @@ 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,
|
||||
dateSent: Long,
|
||||
read: Int,
|
||||
threadId: Long,
|
||||
type: Int,
|
||||
subscriptionId: Int
|
||||
): Long {
|
||||
val uri = Sms.CONTENT_URI
|
||||
val contentValues = ContentValues().apply {
|
||||
put(Sms.ADDRESS, address)
|
||||
put(Sms.SUBJECT, subject)
|
||||
put(Sms.BODY, body)
|
||||
put(Sms.DATE, date)
|
||||
put(Sms.DATE_SENT, dateSent)
|
||||
put(Sms.READ, read)
|
||||
put(Sms.THREAD_ID, threadId)
|
||||
put(Sms.TYPE, type)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ data class Message(
|
|||
@ColumnInfo(name = "status") val status: Int,
|
||||
@ColumnInfo(name = "participants") val participants: ArrayList<SimpleContact>,
|
||||
@ColumnInfo(name = "date") val date: Int,
|
||||
@ColumnInfo(name = "date_sent") val dateSent: Int,
|
||||
@ColumnInfo(name = "read") val read: Boolean,
|
||||
@ColumnInfo(name = "thread_id") val threadId: Long,
|
||||
@ColumnInfo(name = "is_mms") val isMMS: Boolean,
|
||||
|
|
@ -58,6 +59,7 @@ data class Message(
|
|||
return old.body == new.body &&
|
||||
old.threadId == new.threadId &&
|
||||
old.date == new.date &&
|
||||
old.dateSent == new.dateSent &&
|
||||
old.isMMS == new.isMMS &&
|
||||
old.attachment == new.attachment &&
|
||||
old.senderPhoneNumber == new.senderPhoneNumber &&
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class SmsReceiver : BroadcastReceiver() {
|
|||
var body = ""
|
||||
var subject = ""
|
||||
var date = 0L
|
||||
var dateSent = 0L
|
||||
var threadId = 0L
|
||||
var status = Telephony.Sms.STATUS_NONE
|
||||
val type = Telephony.Sms.MESSAGE_TYPE_INBOX
|
||||
|
|
@ -38,6 +39,7 @@ class SmsReceiver : BroadcastReceiver() {
|
|||
status = it.status
|
||||
body += it.messageBody
|
||||
date = System.currentTimeMillis()
|
||||
dateSent = it.timestampMillis
|
||||
threadId = context.getThreadId(address)
|
||||
}
|
||||
|
||||
|
|
@ -45,17 +47,27 @@ class SmsReceiver : BroadcastReceiver() {
|
|||
val simpleContactsHelper = SimpleContactsHelper(context)
|
||||
simpleContactsHelper.exists(address, privateCursor) { exists ->
|
||||
if (exists) {
|
||||
handleMessage(context, address, subject, body, date, read, threadId, type, subscriptionId, status)
|
||||
handleMessage(context, address, subject, body, date, dateSent, read, threadId, type, subscriptionId, status)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handleMessage(context, address, subject, body, date, read, threadId, type, subscriptionId, status)
|
||||
handleMessage(context, address, subject, body, date, dateSent, read, threadId, type, subscriptionId, status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
dateSent: Long,
|
||||
read: Int,
|
||||
threadId: Long,
|
||||
type: Int,
|
||||
subscriptionId: Int,
|
||||
status: Int
|
||||
) {
|
||||
val photoUri = SimpleContactsHelper(context).getPhotoUriFromPhoneNumber(address)
|
||||
val bitmap = context.getNotificationBitmap(photoUri)
|
||||
|
|
@ -63,7 +75,7 @@ class SmsReceiver : BroadcastReceiver() {
|
|||
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 newMessageId = context.insertNewSMS(address, subject, body, date, dateSent, read, threadId, type, subscriptionId)
|
||||
|
||||
val conversation = context.getConversations(threadId).firstOrNull() ?: return@ensureBackgroundThread
|
||||
try {
|
||||
|
|
@ -81,6 +93,7 @@ class SmsReceiver : BroadcastReceiver() {
|
|||
val participant = SimpleContact(0, 0, senderName, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
|
||||
val participants = arrayListOf(participant)
|
||||
val messageDate = (date / 1000).toInt()
|
||||
val messageSentDate = (dateSent / 1000).toInt()
|
||||
|
||||
val message =
|
||||
Message(
|
||||
|
|
@ -90,6 +103,7 @@ class SmsReceiver : BroadcastReceiver() {
|
|||
status,
|
||||
participants,
|
||||
messageDate,
|
||||
messageSentDate,
|
||||
false,
|
||||
threadId,
|
||||
false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue