show a notification if a message sending failed

This commit is contained in:
tibbi 2021-01-01 22:52:23 +01:00
parent 868b6fcd1a
commit 7554bb1f10
2 changed files with 122 additions and 12 deletions

View File

@ -8,6 +8,7 @@ import android.app.PendingIntent
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.database.Cursor
import android.graphics.Bitmap import android.graphics.Bitmap
import android.media.AudioAttributes import android.media.AudioAttributes
import android.media.AudioManager import android.media.AudioManager
@ -320,6 +321,28 @@ fun Context.getThreadSnippet(threadId: Long): String {
return snippet return snippet
} }
fun Context.getMessageRecipientAddress(messageId: Long): String {
val uri = Sms.CONTENT_URI
val projection = arrayOf(
Sms.ADDRESS
)
val selection = "${Sms._ID} = ?"
val selectionArgs = arrayOf(messageId.toString())
try {
val cursor = contentResolver.query(uri, projection, selection, selectionArgs, null)
cursor?.use {
if (cursor.moveToFirst()) {
return cursor.getStringValue(Sms.ADDRESS)
}
}
} catch (e: Exception) {
}
return ""
}
fun Context.getThreadParticipants(threadId: Long, contactsMap: HashMap<Int, SimpleContact>?): ArrayList<SimpleContact> { fun Context.getThreadParticipants(threadId: Long, contactsMap: HashMap<Int, SimpleContact>?): ArrayList<SimpleContact> {
val uri = Uri.parse("${MmsSms.CONTENT_CONVERSATIONS_URI}?simple=true") val uri = Uri.parse("${MmsSms.CONTENT_CONVERSATIONS_URI}?simple=true")
val projection = arrayOf( val projection = arrayOf(
@ -612,18 +635,23 @@ fun Context.getThreadId(addresses: Set<String>): Long {
fun Context.showReceivedMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?) { fun Context.showReceivedMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?) {
val privateCursor = getMyContactsCursor()?.loadInBackground() val privateCursor = getMyContactsCursor()?.loadInBackground()
ensureBackgroundThread { ensureBackgroundThread {
var sender = getNameAndPhotoFromPhoneNumber(address).name val senderName = getNameFromAddress(address, privateCursor)
if (address == sender) {
val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
sender = privateContacts.firstOrNull { it.doesContainPhoneNumber(address) }?.name ?: address
}
Handler(Looper.getMainLooper()).post { Handler(Looper.getMainLooper()).post {
showMessageNotification(address, body, threadId, bitmap, sender) showMessageNotification(address, body, threadId, bitmap, senderName)
} }
} }
} }
fun Context.getNameFromAddress(address: String, privateCursor: Cursor?): String {
var sender = getNameAndPhotoFromPhoneNumber(address).name
if (address == sender) {
val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
sender = privateContacts.firstOrNull { it.doesContainPhoneNumber(address) }?.name ?: address
}
return sender
}
@SuppressLint("NewApi") @SuppressLint("NewApi")
fun Context.showMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?, sender: String) { fun Context.showMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?, sender: String) {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

View File

@ -1,13 +1,30 @@
package com.simplemobiletools.smsmessenger.receivers package com.simplemobiletools.smsmessenger.receivers
import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.RingtoneManager
import android.net.Uri import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.Telephony import android.provider.Telephony
import androidx.core.app.NotificationCompat
import com.simplemobiletools.commons.extensions.getMyContactsCursor
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.smsmessenger.extensions.messagesDB import com.simplemobiletools.commons.helpers.isOreoPlus
import com.simplemobiletools.smsmessenger.extensions.updateMessageType import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.activities.ThreadActivity
import com.simplemobiletools.smsmessenger.extensions.*
import com.simplemobiletools.smsmessenger.helpers.NOTIFICATION_CHANNEL
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
import com.simplemobiletools.smsmessenger.helpers.refreshMessages import com.simplemobiletools.smsmessenger.helpers.refreshMessages
class SmsStatusSentReceiver : BroadcastReceiver() { class SmsStatusSentReceiver : BroadcastReceiver() {
@ -15,13 +32,78 @@ class SmsStatusSentReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
if (intent.extras?.containsKey("message_uri") == true) { if (intent.extras?.containsKey("message_uri") == true) {
val uri = Uri.parse(intent.getStringExtra("message_uri")) val uri = Uri.parse(intent.getStringExtra("message_uri"))
val id = uri?.lastPathSegment?.toLong() ?: 0L val messageId = uri?.lastPathSegment?.toLong() ?: 0L
ensureBackgroundThread { ensureBackgroundThread {
val type = if (intent.extras!!.containsKey("errorCode")) Telephony.Sms.MESSAGE_TYPE_FAILED else Telephony.Sms.MESSAGE_TYPE_OUTBOX val type = if (intent.extras!!.containsKey("errorCode")) {
context.updateMessageType(id, type) showSendingFailedNotification(context, messageId)
context.messagesDB.updateType(id, type) Telephony.Sms.MESSAGE_TYPE_FAILED
} else {
Telephony.Sms.MESSAGE_TYPE_OUTBOX
}
context.updateMessageType(messageId, type)
context.messagesDB.updateType(messageId, type)
refreshMessages() refreshMessages()
} }
} }
} }
private fun showSendingFailedNotification(context: Context, messageId: Long) {
Handler(Looper.getMainLooper()).post {
val privateCursor = context.getMyContactsCursor()?.loadInBackground()
ensureBackgroundThread {
val address = context.getMessageRecipientAddress(messageId)
val threadId = context.getThreadId(address)
val senderName = context.getNameFromAddress(address, privateCursor)
showNotification(context, senderName, threadId)
}
}
}
@SuppressLint("NewApi")
private fun showNotification(context: Context, recipientName: String, threadId: Long) {
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
if (isOreoPlus()) {
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setLegacyStreamType(AudioManager.STREAM_NOTIFICATION)
.build()
val name = context.getString(R.string.message_not_sent_short)
val importance = NotificationManager.IMPORTANCE_HIGH
NotificationChannel(NOTIFICATION_CHANNEL, name, importance).apply {
setBypassDnd(false)
enableLights(true)
setSound(soundUri, audioAttributes)
enableVibration(true)
notificationManager.createNotificationChannel(this)
}
}
val intent = Intent(context, ThreadActivity::class.java).apply {
putExtra(THREAD_ID, threadId)
}
val pendingIntent = PendingIntent.getActivity(context, threadId.hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT)
val summaryText = String.format(context.getString(R.string.message_sending_error), recipientName)
val largeIcon = SimpleContactsHelper(context).getContactLetterIcon(recipientName)
val builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
.setContentTitle(context.getString(R.string.message_not_sent_short))
.setContentText(summaryText)
.setColor(context.config.primaryColor)
.setSmallIcon(R.drawable.ic_messenger)
.setLargeIcon(largeIcon)
.setStyle(NotificationCompat.BigTextStyle().bigText(summaryText))
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_LIGHTS)
.setCategory(Notification.CATEGORY_MESSAGE)
.setAutoCancel(true)
.setSound(soundUri, AudioManager.STREAM_NOTIFICATION)
.setChannelId(NOTIFICATION_CHANNEL)
notificationManager.notify(threadId.hashCode(), builder.build())
}
} }