Improve and organise notification related code

Improvements related to the "Mark as read" button but it's not completely fixed yet. There's still a minor issue on android 13 devices

### Changes:
 - Move notification related code to a separate helper
 - Update notification instead of cancelling when using inline replies
 - Disable sound on inline replies
 - Reuse existing transaction api extensions for sending inline replies
This commit is contained in:
Naveen 2022-12-04 00:49:41 +05:30
parent fb8cb95e19
commit 0ab85419af
5 changed files with 247 additions and 258 deletions

View file

@ -4,58 +4,58 @@ import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import androidx.core.app.RemoteInput
import com.klinker.android.send_message.Transaction
import com.simplemobiletools.commons.extensions.notificationManager
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
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.getSendMessageSettings
import com.simplemobiletools.smsmessenger.helpers.sendMessage
class DirectReplyReceiver : BroadcastReceiver() {
@SuppressLint("MissingPermission")
override fun onReceive(context: Context, intent: Intent) {
val address = intent.getStringExtra(THREAD_NUMBER)
val threadId = intent.getLongExtra(THREAD_ID, 0L)
var msg = RemoteInput.getResultsFromIntent(intent)?.getCharSequence(REPLY)?.toString() ?: return
var body = RemoteInput.getResultsFromIntent(intent)?.getCharSequence(REPLY)?.toString() ?: return
msg = context.removeDiacriticsIfNeeded(msg)
body = context.removeDiacriticsIfNeeded(body)
val settings = context.getSendMessageSettings()
if (address != null) {
var subscriptionId: Int? = null
val availableSIMs = context.subscriptionManagerCompat().activeSubscriptionInfoList
if ((availableSIMs?.size ?: 0) > 1) {
val currentSIMCardIndex = context.config.getUseSIMIdAtNumber(address)
val wantedId = availableSIMs.getOrNull(currentSIMCardIndex)
if (wantedId != null) {
settings.subscriptionId = wantedId.subscriptionId
subscriptionId = wantedId.subscriptionId
}
}
}
val transaction = Transaction(context, settings)
val message = com.klinker.android.send_message.Message(msg, address)
ensureBackgroundThread {
try {
context.sendMessage(body, listOf(address), subscriptionId, emptyList())
val message = context.getMessages(threadId, getImageResolutions = false, includeScheduledMessages = false, limit = 1).firstOrNull()
if (message != null) {
context.messagesDB.insertOrUpdate(message)
}
} catch (e: Exception) {
context.showErrorToast(e)
}
ensureBackgroundThread {
try {
val smsSentIntent = Intent(context, SmsStatusSentReceiver::class.java)
val deliveredIntent = Intent(context, SmsStatusDeliveredReceiver::class.java)
val photoUri = SimpleContactsHelper(context).getPhotoUriFromPhoneNumber(address)
val bitmap = context.getNotificationBitmap(photoUri)
Handler(Looper.getMainLooper()).post {
context.notificationHelper.showMessageNotification(address, body, threadId, bitmap, sender = null, alertOnlyOnce = true)
}
transaction.setExplicitBroadcastForSentSms(smsSentIntent)
transaction.setExplicitBroadcastForDeliveredSms(deliveredIntent)
transaction.sendNewMessage(message)
} catch (e: Exception) {
context.showErrorToast(e)
context.markThreadMessagesRead(threadId)
context.conversationsDB.markRead(threadId)
}
context.notificationManager.cancel(threadId.hashCode())
context.markThreadMessagesRead(threadId)
context.conversationsDB.markRead(threadId)
}
}
}

View file

@ -3,13 +3,9 @@ package com.simplemobiletools.smsmessenger.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.simplemobiletools.commons.extensions.baseConfig
import com.simplemobiletools.commons.extensions.getMyContactsCursor
import com.simplemobiletools.commons.extensions.isNumberBlocked
@ -17,7 +13,6 @@ import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.PhoneNumber
import com.simplemobiletools.commons.models.SimpleContact
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.extensions.*
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
import com.simplemobiletools.smsmessenger.models.Message
@ -63,7 +58,7 @@ class SmsReceiver : BroadcastReceiver() {
context: Context, address: String, subject: String, body: String, date: Long, read: Int, threadId: Long, type: Int, subscriptionId: Int, status: Int
) {
val photoUri = SimpleContactsHelper(context).getPhotoUriFromPhoneNumber(address)
val bitmap = getPhotoForNotification(photoUri, context)
val bitmap = context.getNotificationBitmap(photoUri)
Handler(Looper.getMainLooper()).post {
if (!context.isNumberBlocked(address)) {
val privateCursor = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
@ -97,27 +92,4 @@ class SmsReceiver : BroadcastReceiver() {
}
}
}
private fun getPhotoForNotification(photoUri: String, context: Context): Bitmap? {
val size = context.resources.getDimension(R.dimen.notification_large_icon_size).toInt()
if (photoUri.isEmpty()) {
return null
}
val options = RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerCrop()
return try {
Glide.with(context)
.asBitmap()
.load(photoUri)
.apply(options)
.apply(RequestOptions.circleCropTransform())
.into(size, size)
.get()
} catch (e: Exception) {
null
}
}
}

View file

@ -1,31 +1,15 @@
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.Context
import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.RingtoneManager
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import androidx.core.app.NotificationCompat
import com.klinker.android.send_message.SentReceiver
import com.simplemobiletools.commons.extensions.getMyContactsCursor
import com.simplemobiletools.commons.extensions.getProperPrimaryColor
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isOreoPlus
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
class SmsStatusSentReceiver : SentReceiver() {
@ -59,61 +43,13 @@ class SmsStatusSentReceiver : SentReceiver() {
private fun showSendingFailedNotification(context: Context, messageId: Long) {
Handler(Looper.getMainLooper()).post {
val privateCursor = context.getMyContactsCursor(false, true)
val privateCursor = context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
ensureBackgroundThread {
val address = context.getMessageRecipientAddress(messageId)
val threadId = context.getThreadId(address)
val senderName = context.getNameFromAddress(address, privateCursor)
showNotification(context, senderName, threadId)
val recipientName = context.getNameFromAddress(address, privateCursor)
context.notificationHelper.showSendingFailedNotification(recipientName, 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 or PendingIntent.FLAG_MUTABLE)
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.getProperPrimaryColor())
.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())
}
}