Remove support for Android and older versions
See https://github.com/orgs/FossifyOrg/discussions/241
|
|
@ -76,7 +76,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
val currentJavaVersionFromLibs = JavaVersion.valueOf(libs.versions.app.build.javaVersion.get().toString())
|
val currentJavaVersionFromLibs = JavaVersion.valueOf(libs.versions.app.build.javaVersion.get())
|
||||||
sourceCompatibility = currentJavaVersionFromLibs
|
sourceCompatibility = currentJavaVersionFromLibs
|
||||||
targetCompatibility = currentJavaVersionFromLibs
|
targetCompatibility = currentJavaVersionFromLibs
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,31 @@ import android.content.Intent
|
||||||
import android.media.AudioAttributes
|
import android.media.AudioAttributes
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.media.RingtoneManager
|
import android.media.RingtoneManager
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import org.fossify.commons.extensions.*
|
import org.fossify.commons.extensions.applyColorFilter
|
||||||
|
import org.fossify.commons.extensions.beGone
|
||||||
|
import org.fossify.commons.extensions.beVisible
|
||||||
|
import org.fossify.commons.extensions.beVisibleIf
|
||||||
|
import org.fossify.commons.extensions.getProperPrimaryColor
|
||||||
|
import org.fossify.commons.extensions.getProperTextColor
|
||||||
|
import org.fossify.commons.extensions.notificationManager
|
||||||
|
import org.fossify.commons.extensions.updateTextColors
|
||||||
|
import org.fossify.commons.extensions.viewBinding
|
||||||
import org.fossify.commons.helpers.NavigationIcon
|
import org.fossify.commons.helpers.NavigationIcon
|
||||||
import org.fossify.commons.helpers.ensureBackgroundThread
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.commons.helpers.isOreoPlus
|
|
||||||
import org.fossify.commons.models.SimpleContact
|
import org.fossify.commons.models.SimpleContact
|
||||||
import org.fossify.messages.adapters.ContactsAdapter
|
import org.fossify.messages.adapters.ContactsAdapter
|
||||||
import org.fossify.messages.databinding.ActivityConversationDetailsBinding
|
import org.fossify.messages.databinding.ActivityConversationDetailsBinding
|
||||||
import org.fossify.messages.dialogs.RenameConversationDialog
|
import org.fossify.messages.dialogs.RenameConversationDialog
|
||||||
import org.fossify.messages.extensions.*
|
import org.fossify.messages.extensions.config
|
||||||
|
import org.fossify.messages.extensions.conversationsDB
|
||||||
|
import org.fossify.messages.extensions.getContactFromAddress
|
||||||
|
import org.fossify.messages.extensions.getThreadParticipants
|
||||||
|
import org.fossify.messages.extensions.messagesDB
|
||||||
|
import org.fossify.messages.extensions.renameConversation
|
||||||
|
import org.fossify.messages.extensions.startContactDetailsIntent
|
||||||
import org.fossify.messages.helpers.THREAD_ID
|
import org.fossify.messages.helpers.THREAD_ID
|
||||||
import org.fossify.messages.models.Conversation
|
import org.fossify.messages.models.Conversation
|
||||||
|
|
||||||
|
|
@ -42,7 +53,10 @@ class ConversationDetailsActivity : SimpleActivity() {
|
||||||
useTransparentNavigation = true,
|
useTransparentNavigation = true,
|
||||||
useTopSearchMenu = false
|
useTopSearchMenu = false
|
||||||
)
|
)
|
||||||
setupMaterialScrollListener(scrollingView = binding.participantsRecyclerview, toolbar = binding.conversationDetailsToolbar)
|
setupMaterialScrollListener(
|
||||||
|
scrollingView = binding.participantsRecyclerview,
|
||||||
|
toolbar = binding.conversationDetailsToolbar
|
||||||
|
)
|
||||||
|
|
||||||
threadId = intent.getLongExtra(THREAD_ID, 0L)
|
threadId = intent.getLongExtra(THREAD_ID, 0L)
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
|
|
@ -56,12 +70,10 @@ class ConversationDetailsActivity : SimpleActivity() {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
setupTextViews()
|
setupTextViews()
|
||||||
setupParticipants()
|
setupParticipants()
|
||||||
if (isOreoPlus()) {
|
|
||||||
setupCustomNotifications()
|
setupCustomNotifications()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
@ -73,7 +85,6 @@ class ConversationDetailsActivity : SimpleActivity() {
|
||||||
binding.membersHeading.setTextColor(primaryColor)
|
binding.membersHeading.setTextColor(primaryColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
private fun setupCustomNotifications() {
|
private fun setupCustomNotifications() {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
notificationsHeading.beVisible()
|
notificationsHeading.beVisible()
|
||||||
|
|
@ -104,7 +115,6 @@ class ConversationDetailsActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
private fun createNotificationChannel() {
|
private fun createNotificationChannel() {
|
||||||
val name = conversation?.title
|
val name = conversation?.title
|
||||||
val audioAttributes = AudioAttributes.Builder()
|
val audioAttributes = AudioAttributes.Builder()
|
||||||
|
|
@ -116,27 +126,36 @@ class ConversationDetailsActivity : SimpleActivity() {
|
||||||
NotificationChannel(threadId.toString(), name, NotificationManager.IMPORTANCE_HIGH).apply {
|
NotificationChannel(threadId.toString(), name, NotificationManager.IMPORTANCE_HIGH).apply {
|
||||||
setBypassDnd(false)
|
setBypassDnd(false)
|
||||||
enableLights(true)
|
enableLights(true)
|
||||||
setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), audioAttributes)
|
setSound(
|
||||||
|
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
|
||||||
|
audioAttributes
|
||||||
|
)
|
||||||
enableVibration(true)
|
enableVibration(true)
|
||||||
notificationManager.createNotificationChannel(this)
|
notificationManager.createNotificationChannel(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
private fun removeNotificationChannel() {
|
private fun removeNotificationChannel() {
|
||||||
notificationManager.deleteNotificationChannel(threadId.toString())
|
notificationManager.deleteNotificationChannel(threadId.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupTextViews() {
|
private fun setupTextViews() {
|
||||||
binding.conversationName.apply {
|
binding.conversationName.apply {
|
||||||
ResourcesCompat.getDrawable(resources, org.fossify.commons.R.drawable.ic_edit_vector, theme)?.apply {
|
ResourcesCompat.getDrawable(
|
||||||
|
resources,
|
||||||
|
org.fossify.commons.R.drawable.ic_edit_vector,
|
||||||
|
theme
|
||||||
|
)?.apply {
|
||||||
applyColorFilter(getProperTextColor())
|
applyColorFilter(getProperTextColor())
|
||||||
setCompoundDrawablesWithIntrinsicBounds(null, null, this, null)
|
setCompoundDrawablesWithIntrinsicBounds(null, null, this, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
text = conversation?.title
|
text = conversation?.title
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
RenameConversationDialog(this@ConversationDetailsActivity, conversation!!) { title ->
|
RenameConversationDialog(
|
||||||
|
this@ConversationDetailsActivity,
|
||||||
|
conversation!!
|
||||||
|
) { title ->
|
||||||
text = title
|
text = title
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
conversation = renameConversation(conversation!!, newTitle = title)
|
conversation = renameConversation(conversation!!, newTitle = title)
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ import org.fossify.commons.helpers.PERMISSION_READ_SMS
|
||||||
import org.fossify.commons.helpers.PERMISSION_SEND_SMS
|
import org.fossify.commons.helpers.PERMISSION_SEND_SMS
|
||||||
import org.fossify.commons.helpers.SHORT_ANIMATION_DURATION
|
import org.fossify.commons.helpers.SHORT_ANIMATION_DURATION
|
||||||
import org.fossify.commons.helpers.ensureBackgroundThread
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.commons.helpers.isNougatMR1Plus
|
|
||||||
import org.fossify.commons.helpers.isQPlus
|
import org.fossify.commons.helpers.isQPlus
|
||||||
import org.fossify.commons.models.FAQItem
|
import org.fossify.commons.models.FAQItem
|
||||||
import org.fossify.commons.models.Release
|
import org.fossify.commons.models.Release
|
||||||
|
|
@ -494,7 +493,7 @@ class MainActivity : SimpleActivity() {
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
private fun checkShortcut() {
|
private fun checkShortcut() {
|
||||||
val appIconColor = config.appIconColor
|
val appIconColor = config.appIconColor
|
||||||
if (isNougatMR1Plus() && config.lastHandledShortcutColor != appIconColor) {
|
if (config.lastHandledShortcutColor != appIconColor) {
|
||||||
val newConversation = getCreateNewContactShortcut(appIconColor)
|
val newConversation = getCreateNewContactShortcut(appIconColor)
|
||||||
|
|
||||||
val manager = getSystemService(ShortcutManager::class.java)
|
val manager = getSystemService(ShortcutManager::class.java)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
package org.fossify.messages.activities
|
package org.fossify.messages.activities
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
|
@ -16,7 +14,9 @@ import org.fossify.commons.dialogs.FeatureLockedDialog
|
||||||
import org.fossify.commons.dialogs.RadioGroupDialog
|
import org.fossify.commons.dialogs.RadioGroupDialog
|
||||||
import org.fossify.commons.dialogs.SecurityDialog
|
import org.fossify.commons.dialogs.SecurityDialog
|
||||||
import org.fossify.commons.extensions.addLockedLabelIfNeeded
|
import org.fossify.commons.extensions.addLockedLabelIfNeeded
|
||||||
|
import org.fossify.commons.extensions.beGone
|
||||||
import org.fossify.commons.extensions.beGoneIf
|
import org.fossify.commons.extensions.beGoneIf
|
||||||
|
import org.fossify.commons.extensions.beVisible
|
||||||
import org.fossify.commons.extensions.beVisibleIf
|
import org.fossify.commons.extensions.beVisibleIf
|
||||||
import org.fossify.commons.extensions.getBlockedNumbers
|
import org.fossify.commons.extensions.getBlockedNumbers
|
||||||
import org.fossify.commons.extensions.getCustomizeColorsString
|
import org.fossify.commons.extensions.getCustomizeColorsString
|
||||||
|
|
@ -36,8 +36,6 @@ import org.fossify.commons.helpers.NavigationIcon
|
||||||
import org.fossify.commons.helpers.PROTECTION_FINGERPRINT
|
import org.fossify.commons.helpers.PROTECTION_FINGERPRINT
|
||||||
import org.fossify.commons.helpers.SHOW_ALL_TABS
|
import org.fossify.commons.helpers.SHOW_ALL_TABS
|
||||||
import org.fossify.commons.helpers.ensureBackgroundThread
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.commons.helpers.isNougatPlus
|
|
||||||
import org.fossify.commons.helpers.isOreoPlus
|
|
||||||
import org.fossify.commons.helpers.isPiePlus
|
import org.fossify.commons.helpers.isPiePlus
|
||||||
import org.fossify.commons.helpers.isTiramisuPlus
|
import org.fossify.commons.helpers.isTiramisuPlus
|
||||||
import org.fossify.commons.models.RadioItem
|
import org.fossify.commons.models.RadioItem
|
||||||
|
|
@ -226,7 +224,6 @@ class SettingsActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCustomizeNotifications() = binding.apply {
|
private fun setupCustomizeNotifications() = binding.apply {
|
||||||
settingsCustomizeNotificationsHolder.beVisibleIf(isOreoPlus())
|
|
||||||
settingsCustomizeNotificationsHolder.setOnClickListener {
|
settingsCustomizeNotificationsHolder.setOnClickListener {
|
||||||
launchCustomizeNotificationsIntent()
|
launchCustomizeNotificationsIntent()
|
||||||
}
|
}
|
||||||
|
|
@ -247,19 +244,20 @@ class SettingsActivity : SimpleActivity() {
|
||||||
|
|
||||||
private fun setupLanguage() = binding.apply {
|
private fun setupLanguage() = binding.apply {
|
||||||
settingsLanguage.text = Locale.getDefault().displayLanguage
|
settingsLanguage.text = Locale.getDefault().displayLanguage
|
||||||
settingsLanguageHolder.beVisibleIf(isTiramisuPlus())
|
if (isTiramisuPlus()) {
|
||||||
|
settingsLanguageHolder.beVisible()
|
||||||
settingsLanguageHolder.setOnClickListener {
|
settingsLanguageHolder.setOnClickListener {
|
||||||
launchChangeAppLanguageIntent()
|
launchChangeAppLanguageIntent()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
settingsLanguageHolder.beGone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// support for device-wise blocking came on Android 7, rely only on that
|
|
||||||
@TargetApi(Build.VERSION_CODES.N)
|
|
||||||
private fun setupManageBlockedNumbers() = binding.apply {
|
private fun setupManageBlockedNumbers() = binding.apply {
|
||||||
settingsManageBlockedNumbers.text =
|
settingsManageBlockedNumbers.text =
|
||||||
addLockedLabelIfNeeded(org.fossify.commons.R.string.manage_blocked_numbers)
|
addLockedLabelIfNeeded(org.fossify.commons.R.string.manage_blocked_numbers)
|
||||||
settingsManageBlockedNumbersHolder.beVisibleIf(isNougatPlus())
|
settingsManageBlockedNumbersHolder.beVisible()
|
||||||
|
|
||||||
settingsManageBlockedNumbersHolder.setOnClickListener {
|
settingsManageBlockedNumbersHolder.setOnClickListener {
|
||||||
if (isOrWasThankYouInstalled()) {
|
if (isOrWasThankYouInstalled()) {
|
||||||
Intent(this@SettingsActivity, ManageBlockedNumbersActivity::class.java).apply {
|
Intent(this@SettingsActivity, ManageBlockedNumbersActivity::class.java).apply {
|
||||||
|
|
|
||||||
|
|
@ -95,8 +95,6 @@ import org.fossify.commons.helpers.PERMISSION_READ_PHONE_STATE
|
||||||
import org.fossify.commons.helpers.SimpleContactsHelper
|
import org.fossify.commons.helpers.SimpleContactsHelper
|
||||||
import org.fossify.commons.helpers.VcfExporter
|
import org.fossify.commons.helpers.VcfExporter
|
||||||
import org.fossify.commons.helpers.ensureBackgroundThread
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.commons.helpers.isNougatPlus
|
|
||||||
import org.fossify.commons.helpers.isOreoPlus
|
|
||||||
import org.fossify.commons.helpers.isSPlus
|
import org.fossify.commons.helpers.isSPlus
|
||||||
import org.fossify.commons.models.PhoneNumber
|
import org.fossify.commons.models.PhoneNumber
|
||||||
import org.fossify.commons.models.RadioItem
|
import org.fossify.commons.models.RadioItem
|
||||||
|
|
@ -349,7 +347,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
findItem(R.id.conversation_details).isVisible = conversation != null && !isRecycleBin
|
findItem(R.id.conversation_details).isVisible = conversation != null && !isRecycleBin
|
||||||
findItem(R.id.block_number).title =
|
findItem(R.id.block_number).title =
|
||||||
addLockedLabelIfNeeded(org.fossify.commons.R.string.block_number)
|
addLockedLabelIfNeeded(org.fossify.commons.R.string.block_number)
|
||||||
findItem(R.id.block_number).isVisible = isNougatPlus() && !isRecycleBin
|
findItem(R.id.block_number).isVisible = !isRecycleBin
|
||||||
findItem(R.id.dial_number).isVisible =
|
findItem(R.id.dial_number).isVisible =
|
||||||
participants.size == 1 && !isSpecialNumber() && !isRecycleBin
|
participants.size == 1 && !isSpecialNumber() && !isRecycleBin
|
||||||
findItem(R.id.manage_people).isVisible = !isSpecialNumber() && !isRecycleBin
|
findItem(R.id.manage_people).isVisible = !isSpecialNumber() && !isRecycleBin
|
||||||
|
|
@ -983,12 +981,10 @@ class ThreadActivity : SimpleActivity() {
|
||||||
text = getString(R.string.invalid_short_code_desc)
|
text = getString(R.string.invalid_short_code_desc)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (isOreoPlus()) {
|
|
||||||
tooltipText = getString(org.fossify.commons.R.string.more_info)
|
tooltipText = getString(org.fossify.commons.R.string.more_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupThreadTitle() {
|
private fun setupThreadTitle() {
|
||||||
val title = conversation?.title
|
val title = conversation?.title
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,34 @@ import android.text.TextUtils
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import org.fossify.commons.dialogs.ConfirmationDialog
|
import org.fossify.commons.dialogs.ConfirmationDialog
|
||||||
import org.fossify.commons.dialogs.FeatureLockedDialog
|
import org.fossify.commons.dialogs.FeatureLockedDialog
|
||||||
import org.fossify.commons.extensions.*
|
import org.fossify.commons.extensions.addBlockedNumber
|
||||||
|
import org.fossify.commons.extensions.addLockedLabelIfNeeded
|
||||||
|
import org.fossify.commons.extensions.copyToClipboard
|
||||||
|
import org.fossify.commons.extensions.isOrWasThankYouInstalled
|
||||||
|
import org.fossify.commons.extensions.launchActivityIntent
|
||||||
|
import org.fossify.commons.extensions.notificationManager
|
||||||
import org.fossify.commons.helpers.KEY_PHONE
|
import org.fossify.commons.helpers.KEY_PHONE
|
||||||
import org.fossify.commons.helpers.ensureBackgroundThread
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.commons.helpers.isNougatPlus
|
|
||||||
import org.fossify.commons.views.MyRecyclerView
|
import org.fossify.commons.views.MyRecyclerView
|
||||||
import org.fossify.messages.R
|
import org.fossify.messages.R
|
||||||
import org.fossify.messages.activities.SimpleActivity
|
import org.fossify.messages.activities.SimpleActivity
|
||||||
import org.fossify.messages.dialogs.RenameConversationDialog
|
import org.fossify.messages.dialogs.RenameConversationDialog
|
||||||
import org.fossify.messages.extensions.*
|
import org.fossify.messages.extensions.config
|
||||||
|
import org.fossify.messages.extensions.deleteConversation
|
||||||
|
import org.fossify.messages.extensions.dialNumber
|
||||||
|
import org.fossify.messages.extensions.markThreadMessagesRead
|
||||||
|
import org.fossify.messages.extensions.markThreadMessagesUnread
|
||||||
|
import org.fossify.messages.extensions.renameConversation
|
||||||
|
import org.fossify.messages.extensions.updateConversationArchivedStatus
|
||||||
import org.fossify.messages.helpers.refreshMessages
|
import org.fossify.messages.helpers.refreshMessages
|
||||||
import org.fossify.messages.messaging.isShortCodeWithLetters
|
import org.fossify.messages.messaging.isShortCodeWithLetters
|
||||||
import org.fossify.messages.models.Conversation
|
import org.fossify.messages.models.Conversation
|
||||||
|
|
||||||
class ConversationsAdapter(
|
class ConversationsAdapter(
|
||||||
activity: SimpleActivity, recyclerView: MyRecyclerView, onRefresh: () -> Unit, itemClick: (Any) -> Unit
|
activity: SimpleActivity,
|
||||||
|
recyclerView: MyRecyclerView,
|
||||||
|
onRefresh: () -> Unit,
|
||||||
|
itemClick: (Any) -> Unit
|
||||||
) : BaseConversationsAdapter(activity, recyclerView, onRefresh, itemClick) {
|
) : BaseConversationsAdapter(activity, recyclerView, onRefresh, itemClick) {
|
||||||
override fun getActionMenuId() = R.menu.cab_conversations
|
override fun getActionMenuId() = R.menu.cab_conversations
|
||||||
|
|
||||||
|
|
@ -31,12 +44,16 @@ class ConversationsAdapter(
|
||||||
val archiveAvailable = activity.config.isArchiveAvailable
|
val archiveAvailable = activity.config.isArchiveAvailable
|
||||||
|
|
||||||
menu.apply {
|
menu.apply {
|
||||||
findItem(R.id.cab_block_number).title = activity.addLockedLabelIfNeeded(org.fossify.commons.R.string.block_number)
|
findItem(R.id.cab_block_number).title =
|
||||||
findItem(R.id.cab_block_number).isVisible = isNougatPlus()
|
activity.addLockedLabelIfNeeded(org.fossify.commons.R.string.block_number)
|
||||||
findItem(R.id.cab_add_number_to_contact).isVisible = isSingleSelection && !isGroupConversation
|
findItem(R.id.cab_add_number_to_contact).isVisible =
|
||||||
findItem(R.id.cab_dial_number).isVisible = isSingleSelection && !isGroupConversation && !isShortCodeWithLetters(selectedConversation.phoneNumber)
|
isSingleSelection && !isGroupConversation
|
||||||
|
findItem(R.id.cab_dial_number).isVisible =
|
||||||
|
isSingleSelection && !isGroupConversation &&
|
||||||
|
!isShortCodeWithLetters(selectedConversation.phoneNumber)
|
||||||
findItem(R.id.cab_copy_number).isVisible = isSingleSelection && !isGroupConversation
|
findItem(R.id.cab_copy_number).isVisible = isSingleSelection && !isGroupConversation
|
||||||
findItem(R.id.cab_rename_conversation).isVisible = isSingleSelection && isGroupConversation
|
findItem(R.id.cab_rename_conversation).isVisible =
|
||||||
|
isSingleSelection && isGroupConversation
|
||||||
findItem(R.id.cab_mark_as_read).isVisible = selectedItems.any { !it.read }
|
findItem(R.id.cab_mark_as_read).isVisible = selectedItems.any { !it.read }
|
||||||
findItem(R.id.cab_mark_as_unread).isVisible = selectedItems.any { it.read }
|
findItem(R.id.cab_mark_as_unread).isVisible = selectedItems.any { it.read }
|
||||||
findItem(R.id.cab_archive).isVisible = archiveAvailable
|
findItem(R.id.cab_archive).isVisible = archiveAvailable
|
||||||
|
|
@ -76,7 +93,10 @@ class ConversationsAdapter(
|
||||||
private fun askConfirmBlock() {
|
private fun askConfirmBlock() {
|
||||||
val numbers = getSelectedItems().distinctBy { it.phoneNumber }.map { it.phoneNumber }
|
val numbers = getSelectedItems().distinctBy { it.phoneNumber }.map { it.phoneNumber }
|
||||||
val numbersString = TextUtils.join(", ", numbers)
|
val numbersString = TextUtils.join(", ", numbers)
|
||||||
val question = String.format(resources.getString(org.fossify.commons.R.string.block_confirmation), numbersString)
|
val question = String.format(
|
||||||
|
resources.getString(org.fossify.commons.R.string.block_confirmation),
|
||||||
|
numbersString
|
||||||
|
)
|
||||||
|
|
||||||
ConfirmationDialog(activity, question) {
|
ConfirmationDialog(activity, question) {
|
||||||
blockNumbers()
|
blockNumbers()
|
||||||
|
|
@ -149,7 +169,8 @@ class ConversationsAdapter(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val conversationsToRemove = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
val conversationsToRemove =
|
||||||
|
currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||||
conversationsToRemove.forEach {
|
conversationsToRemove.forEach {
|
||||||
activity.updateConversationArchivedStatus(it.threadId, true)
|
activity.updateConversationArchivedStatus(it.threadId, true)
|
||||||
activity.notificationManager.cancel(it.threadId.hashCode())
|
activity.notificationManager.cancel(it.threadId.hashCode())
|
||||||
|
|
@ -179,7 +200,8 @@ class ConversationsAdapter(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val conversationsToRemove = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
val conversationsToRemove =
|
||||||
|
currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||||
conversationsToRemove.forEach {
|
conversationsToRemove.forEach {
|
||||||
activity.deleteConversation(it.threadId)
|
activity.deleteConversation(it.threadId)
|
||||||
activity.notificationManager.cancel(it.threadId.hashCode())
|
activity.notificationManager.cancel(it.threadId.hashCode())
|
||||||
|
|
@ -224,7 +246,8 @@ class ConversationsAdapter(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val conversationsMarkedAsRead = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
val conversationsMarkedAsRead =
|
||||||
|
currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
conversationsMarkedAsRead.filter { conversation -> !conversation.read }.forEach {
|
conversationsMarkedAsRead.filter { conversation -> !conversation.read }.forEach {
|
||||||
activity.markThreadMessagesRead(it.threadId)
|
activity.markThreadMessagesRead(it.threadId)
|
||||||
|
|
@ -239,7 +262,8 @@ class ConversationsAdapter(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val conversationsMarkedAsUnread = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
val conversationsMarkedAsUnread =
|
||||||
|
currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
conversationsMarkedAsUnread.filter { conversation -> conversation.read }.forEach {
|
conversationsMarkedAsUnread.filter { conversation -> conversation.read }.forEach {
|
||||||
activity.markThreadMessagesUnread(it.threadId)
|
activity.markThreadMessagesUnread(it.threadId)
|
||||||
|
|
@ -280,8 +304,10 @@ class ConversationsAdapter(
|
||||||
private fun checkPinBtnVisibility(menu: Menu) {
|
private fun checkPinBtnVisibility(menu: Menu) {
|
||||||
val pinnedConversations = activity.config.pinnedConversations
|
val pinnedConversations = activity.config.pinnedConversations
|
||||||
val selectedConversations = getSelectedItems()
|
val selectedConversations = getSelectedItems()
|
||||||
menu.findItem(R.id.cab_pin_conversation).isVisible = selectedConversations.any { !pinnedConversations.contains(it.threadId.toString()) }
|
menu.findItem(R.id.cab_pin_conversation).isVisible =
|
||||||
menu.findItem(R.id.cab_unpin_conversation).isVisible = selectedConversations.any { pinnedConversations.contains(it.threadId.toString()) }
|
selectedConversations.any { !pinnedConversations.contains(it.threadId.toString()) }
|
||||||
|
menu.findItem(R.id.cab_unpin_conversation).isVisible =
|
||||||
|
selectedConversations.any { pinnedConversations.contains(it.threadId.toString()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refreshConversations() {
|
private fun refreshConversations() {
|
||||||
|
|
|
||||||
|
|
@ -14,21 +14,49 @@ import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.provider.ContactsContract.PhoneLookup
|
import android.provider.ContactsContract.PhoneLookup
|
||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
import android.provider.Telephony.*
|
import android.provider.Telephony.Mms
|
||||||
|
import android.provider.Telephony.MmsSms
|
||||||
|
import android.provider.Telephony.Sms
|
||||||
|
import android.provider.Telephony.Threads
|
||||||
|
import android.provider.Telephony.ThreadsColumns
|
||||||
import android.telephony.SubscriptionManager
|
import android.telephony.SubscriptionManager
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import me.leolin.shortcutbadger.ShortcutBadger
|
import me.leolin.shortcutbadger.ShortcutBadger
|
||||||
import org.fossify.commons.extensions.*
|
import org.fossify.commons.extensions.areDigitsOnly
|
||||||
import org.fossify.commons.helpers.*
|
import org.fossify.commons.extensions.getBlockedNumbers
|
||||||
|
import org.fossify.commons.extensions.getIntValue
|
||||||
|
import org.fossify.commons.extensions.getLongValue
|
||||||
|
import org.fossify.commons.extensions.getMyContactsCursor
|
||||||
|
import org.fossify.commons.extensions.getStringValue
|
||||||
|
import org.fossify.commons.extensions.hasPermission
|
||||||
|
import org.fossify.commons.extensions.isNumberBlocked
|
||||||
|
import org.fossify.commons.extensions.normalizeString
|
||||||
|
import org.fossify.commons.extensions.notificationManager
|
||||||
|
import org.fossify.commons.extensions.queryCursor
|
||||||
|
import org.fossify.commons.extensions.showErrorToast
|
||||||
|
import org.fossify.commons.extensions.toInt
|
||||||
|
import org.fossify.commons.extensions.toast
|
||||||
|
import org.fossify.commons.extensions.trimToComparableNumber
|
||||||
|
import org.fossify.commons.helpers.DAY_SECONDS
|
||||||
|
import org.fossify.commons.helpers.MONTH_SECONDS
|
||||||
|
import org.fossify.commons.helpers.MyContactsContentProvider
|
||||||
|
import org.fossify.commons.helpers.PERMISSION_READ_CONTACTS
|
||||||
|
import org.fossify.commons.helpers.SimpleContactsHelper
|
||||||
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
|
import org.fossify.commons.helpers.isQPlus
|
||||||
import org.fossify.commons.models.PhoneNumber
|
import org.fossify.commons.models.PhoneNumber
|
||||||
import org.fossify.commons.models.SimpleContact
|
import org.fossify.commons.models.SimpleContact
|
||||||
import org.fossify.messages.R
|
import org.fossify.messages.R
|
||||||
import org.fossify.messages.databases.MessagesDatabase
|
import org.fossify.messages.databases.MessagesDatabase
|
||||||
import org.fossify.messages.helpers.*
|
|
||||||
import org.fossify.messages.helpers.AttachmentUtils.parseAttachmentNames
|
import org.fossify.messages.helpers.AttachmentUtils.parseAttachmentNames
|
||||||
|
import org.fossify.messages.helpers.Config
|
||||||
|
import org.fossify.messages.helpers.FILE_SIZE_NONE
|
||||||
|
import org.fossify.messages.helpers.MESSAGES_LIMIT
|
||||||
|
import org.fossify.messages.helpers.NotificationHelper
|
||||||
|
import org.fossify.messages.helpers.generateRandomId
|
||||||
import org.fossify.messages.interfaces.AttachmentsDao
|
import org.fossify.messages.interfaces.AttachmentsDao
|
||||||
import org.fossify.messages.interfaces.ConversationsDao
|
import org.fossify.messages.interfaces.ConversationsDao
|
||||||
import org.fossify.messages.interfaces.MessageAttachmentsDao
|
import org.fossify.messages.interfaces.MessageAttachmentsDao
|
||||||
|
|
@ -36,7 +64,12 @@ import org.fossify.messages.interfaces.MessagesDao
|
||||||
import org.fossify.messages.messaging.MessagingUtils
|
import org.fossify.messages.messaging.MessagingUtils
|
||||||
import org.fossify.messages.messaging.MessagingUtils.Companion.ADDRESS_SEPARATOR
|
import org.fossify.messages.messaging.MessagingUtils.Companion.ADDRESS_SEPARATOR
|
||||||
import org.fossify.messages.messaging.SmsSender
|
import org.fossify.messages.messaging.SmsSender
|
||||||
import org.fossify.messages.models.*
|
import org.fossify.messages.models.Attachment
|
||||||
|
import org.fossify.messages.models.Conversation
|
||||||
|
import org.fossify.messages.models.Message
|
||||||
|
import org.fossify.messages.models.MessageAttachment
|
||||||
|
import org.fossify.messages.models.NamePhoto
|
||||||
|
import org.fossify.messages.models.RecycleBinMessage
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
|
|
||||||
val Context.config: Config get() = Config.newInstance(applicationContext)
|
val Context.config: Config get() = Config.newInstance(applicationContext)
|
||||||
|
|
@ -114,7 +147,15 @@ fun Context.getMessages(
|
||||||
val participants = senderNumber.split(ADDRESS_SEPARATOR).map { number ->
|
val participants = senderNumber.split(ADDRESS_SEPARATOR).map { number ->
|
||||||
val phoneNumber = PhoneNumber(number, 0, "", number)
|
val phoneNumber = PhoneNumber(number, 0, "", number)
|
||||||
val participantPhoto = getNameAndPhotoFromPhoneNumber(number)
|
val participantPhoto = getNameAndPhotoFromPhoneNumber(number)
|
||||||
SimpleContact(0, 0, participantPhoto.name, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
|
SimpleContact(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
participantPhoto.name,
|
||||||
|
photoUri,
|
||||||
|
arrayListOf(phoneNumber),
|
||||||
|
ArrayList(),
|
||||||
|
ArrayList()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val isMMS = false
|
val isMMS = false
|
||||||
val message =
|
val message =
|
||||||
|
|
@ -159,7 +200,12 @@ fun Context.getMessages(
|
||||||
}
|
}
|
||||||
|
|
||||||
// as soon as a message contains multiple recipients it counts as an MMS instead of SMS
|
// as soon as a message contains multiple recipients it counts as an MMS instead of SMS
|
||||||
fun Context.getMMS(threadId: Long? = null, getImageResolutions: Boolean = false, sortOrder: String? = null, dateFrom: Int = -1): ArrayList<Message> {
|
fun Context.getMMS(
|
||||||
|
threadId: Long? = null,
|
||||||
|
getImageResolutions: Boolean = false,
|
||||||
|
sortOrder: String? = null,
|
||||||
|
dateFrom: Int = -1
|
||||||
|
): ArrayList<Message> {
|
||||||
val uri = Mms.CONTENT_URI
|
val uri = Mms.CONTENT_URI
|
||||||
val projection = arrayOf(
|
val projection = arrayOf(
|
||||||
Mms._ID,
|
Mms._ID,
|
||||||
|
|
@ -175,7 +221,8 @@ fun Context.getMMS(threadId: Long? = null, getImageResolutions: Boolean = false,
|
||||||
var selectionArgs: Array<String>? = null
|
var selectionArgs: Array<String>? = null
|
||||||
|
|
||||||
if (threadId == null && dateFrom != -1) {
|
if (threadId == null && dateFrom != -1) {
|
||||||
selection = "${Sms.DATE} < ${dateFrom.toLong()}" //Should not multiply 1000 here, because date in mms's database is different from sms's.
|
selection =
|
||||||
|
"${Sms.DATE} < ${dateFrom.toLong()}" //Should not multiply 1000 here, because date in mms's database is different from sms's.
|
||||||
} else if (threadId != null && dateFrom == -1) {
|
} else if (threadId != null && dateFrom == -1) {
|
||||||
selection = "${Sms.THREAD_ID} = ?"
|
selection = "${Sms.THREAD_ID} = ?"
|
||||||
selectionArgs = arrayOf(threadId.toString())
|
selectionArgs = arrayOf(threadId.toString())
|
||||||
|
|
@ -262,7 +309,10 @@ fun Context.getMMSSender(msgId: Long): String {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.getConversations(threadId: Long? = null, privateContacts: ArrayList<SimpleContact> = ArrayList()): ArrayList<Conversation> {
|
fun Context.getConversations(
|
||||||
|
threadId: Long? = null,
|
||||||
|
privateContacts: ArrayList<SimpleContact> = ArrayList()
|
||||||
|
): ArrayList<Conversation> {
|
||||||
val archiveAvailable = config.isArchiveAvailable
|
val archiveAvailable = config.isArchiveAvailable
|
||||||
|
|
||||||
val uri = Uri.parse("${Threads.CONTENT_URI}?simple=true")
|
val uri = Uri.parse("${Threads.CONTENT_URI}?simple=true")
|
||||||
|
|
@ -291,7 +341,13 @@ fun Context.getConversations(threadId: Long? = null, privateContacts: ArrayList<
|
||||||
val simpleContactHelper = SimpleContactsHelper(this)
|
val simpleContactHelper = SimpleContactsHelper(this)
|
||||||
val blockedNumbers = getBlockedNumbers()
|
val blockedNumbers = getBlockedNumbers()
|
||||||
try {
|
try {
|
||||||
queryCursorUnsafe(uri, projection.toTypedArray(), selection, selectionArgs, sortOrder) { cursor ->
|
queryCursorUnsafe(
|
||||||
|
uri,
|
||||||
|
projection.toTypedArray(),
|
||||||
|
selection,
|
||||||
|
selectionArgs,
|
||||||
|
sortOrder
|
||||||
|
) { cursor ->
|
||||||
val id = cursor.getLongValue(Threads._ID)
|
val id = cursor.getLongValue(Threads._ID)
|
||||||
var snippet = cursor.getStringValue(Threads.SNIPPET) ?: ""
|
var snippet = cursor.getStringValue(Threads.SNIPPET) ?: ""
|
||||||
if (snippet.isEmpty()) {
|
if (snippet.isEmpty()) {
|
||||||
|
|
@ -304,19 +360,39 @@ fun Context.getConversations(threadId: Long? = null, privateContacts: ArrayList<
|
||||||
}
|
}
|
||||||
|
|
||||||
val rawIds = cursor.getStringValue(Threads.RECIPIENT_IDS)
|
val rawIds = cursor.getStringValue(Threads.RECIPIENT_IDS)
|
||||||
val recipientIds = rawIds.split(" ").filter { it.areDigitsOnly() }.map { it.toInt() }.toMutableList()
|
val recipientIds =
|
||||||
|
rawIds.split(" ").filter { it.areDigitsOnly() }.map { it.toInt() }.toMutableList()
|
||||||
val phoneNumbers = getThreadPhoneNumbers(recipientIds)
|
val phoneNumbers = getThreadPhoneNumbers(recipientIds)
|
||||||
if (phoneNumbers.isEmpty() || phoneNumbers.any { isNumberBlocked(it, blockedNumbers) }) {
|
if (phoneNumbers.isEmpty() || phoneNumbers.any {
|
||||||
|
isNumberBlocked(
|
||||||
|
it,
|
||||||
|
blockedNumbers
|
||||||
|
)
|
||||||
|
}) {
|
||||||
return@queryCursorUnsafe
|
return@queryCursorUnsafe
|
||||||
}
|
}
|
||||||
|
|
||||||
val names = getThreadContactNames(phoneNumbers, privateContacts)
|
val names = getThreadContactNames(phoneNumbers, privateContacts)
|
||||||
val title = TextUtils.join(", ", names.toTypedArray())
|
val title = TextUtils.join(", ", names.toTypedArray())
|
||||||
val photoUri = if (phoneNumbers.size == 1) simpleContactHelper.getPhotoUriFromPhoneNumber(phoneNumbers.first()) else ""
|
val photoUri =
|
||||||
|
if (phoneNumbers.size == 1) simpleContactHelper.getPhotoUriFromPhoneNumber(
|
||||||
|
phoneNumbers.first()
|
||||||
|
) else ""
|
||||||
val isGroupConversation = phoneNumbers.size > 1
|
val isGroupConversation = phoneNumbers.size > 1
|
||||||
val read = cursor.getIntValue(Threads.READ) == 1
|
val read = cursor.getIntValue(Threads.READ) == 1
|
||||||
val archived = if (archiveAvailable) cursor.getIntValue(Threads.ARCHIVED) == 1 else false
|
val archived =
|
||||||
val conversation = Conversation(id, snippet, date.toInt(), read, title, photoUri, isGroupConversation, phoneNumbers.first(), isArchived = archived)
|
if (archiveAvailable) cursor.getIntValue(Threads.ARCHIVED) == 1 else false
|
||||||
|
val conversation = Conversation(
|
||||||
|
id,
|
||||||
|
snippet,
|
||||||
|
date.toInt(),
|
||||||
|
read,
|
||||||
|
title,
|
||||||
|
photoUri,
|
||||||
|
isGroupConversation,
|
||||||
|
phoneNumbers.first(),
|
||||||
|
isArchived = archived
|
||||||
|
)
|
||||||
conversations.add(conversation)
|
conversations.add(conversation)
|
||||||
}
|
}
|
||||||
} catch (sqliteException: SQLiteException) {
|
} catch (sqliteException: SQLiteException) {
|
||||||
|
|
@ -399,7 +475,11 @@ fun Context.getMmsAttachment(id: Long, getImageResolutions: Boolean): MessageAtt
|
||||||
try {
|
try {
|
||||||
val options = BitmapFactory.Options()
|
val options = BitmapFactory.Options()
|
||||||
options.inJustDecodeBounds = true
|
options.inJustDecodeBounds = true
|
||||||
BitmapFactory.decodeStream(contentResolver.openInputStream(fileUri), null, options)
|
BitmapFactory.decodeStream(
|
||||||
|
contentResolver.openInputStream(fileUri),
|
||||||
|
null,
|
||||||
|
options
|
||||||
|
)
|
||||||
width = options.outWidth
|
width = options.outWidth
|
||||||
height = options.outHeight
|
height = options.outHeight
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
@ -410,7 +490,15 @@ fun Context.getMmsAttachment(id: Long, getImageResolutions: Boolean): MessageAtt
|
||||||
messageAttachment.attachments.add(attachment)
|
messageAttachment.attachments.add(attachment)
|
||||||
} else if (mimetype != "application/smil") {
|
} else if (mimetype != "application/smil") {
|
||||||
val attachmentName = attachmentNames?.getOrNull(attachmentCount) ?: ""
|
val attachmentName = attachmentNames?.getOrNull(attachmentCount) ?: ""
|
||||||
val attachment = Attachment(partId, id, Uri.withAppendedPath(uri, partId.toString()).toString(), mimetype, 0, 0, attachmentName)
|
val attachment = Attachment(
|
||||||
|
partId,
|
||||||
|
id,
|
||||||
|
Uri.withAppendedPath(uri, partId.toString()).toString(),
|
||||||
|
mimetype,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
attachmentName
|
||||||
|
)
|
||||||
messageAttachment.attachments.add(attachment)
|
messageAttachment.attachments.add(attachment)
|
||||||
attachmentCount++
|
attachmentCount++
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -476,7 +564,10 @@ fun Context.getMessageRecipientAddress(messageId: Long): String {
|
||||||
return ""
|
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(
|
||||||
ThreadsColumns.RECIPIENT_IDS
|
ThreadsColumns.RECIPIENT_IDS
|
||||||
|
|
@ -501,7 +592,15 @@ fun Context.getThreadParticipants(threadId: Long, contactsMap: HashMap<Int, Simp
|
||||||
val name = namePhoto.name
|
val name = namePhoto.name
|
||||||
val photoUri = namePhoto.photoUri ?: ""
|
val photoUri = namePhoto.photoUri ?: ""
|
||||||
val phoneNumber = PhoneNumber(number, 0, "", number)
|
val phoneNumber = PhoneNumber(number, 0, "", number)
|
||||||
val contact = SimpleContact(addressId, addressId, name, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
|
val contact = SimpleContact(
|
||||||
|
addressId,
|
||||||
|
addressId,
|
||||||
|
name,
|
||||||
|
photoUri,
|
||||||
|
arrayListOf(phoneNumber),
|
||||||
|
ArrayList(),
|
||||||
|
ArrayList()
|
||||||
|
)
|
||||||
participants.add(contact)
|
participants.add(contact)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -520,7 +619,10 @@ fun Context.getThreadPhoneNumbers(recipientIds: List<Int>): ArrayList<String> {
|
||||||
return numbers
|
return numbers
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.getThreadContactNames(phoneNumbers: List<String>, privateContacts: ArrayList<SimpleContact>): ArrayList<String> {
|
fun Context.getThreadContactNames(
|
||||||
|
phoneNumbers: List<String>,
|
||||||
|
privateContacts: ArrayList<SimpleContact>
|
||||||
|
): ArrayList<String> {
|
||||||
val names = ArrayList<String>()
|
val names = ArrayList<String>()
|
||||||
phoneNumbers.forEach { number ->
|
phoneNumbers.forEach { number ->
|
||||||
val name = SimpleContactsHelper(this).getNameFromPhoneNumber(number)
|
val name = SimpleContactsHelper(this).getNameFromPhoneNumber(number)
|
||||||
|
|
@ -578,7 +680,8 @@ fun Context.getSuggestedContacts(privateContacts: ArrayList<SimpleContact>): Arr
|
||||||
return@queryCursor
|
return@queryCursor
|
||||||
} else if (namePhoto.name == senderNumber) {
|
} else if (namePhoto.name == senderNumber) {
|
||||||
if (privateContacts.isNotEmpty()) {
|
if (privateContacts.isNotEmpty()) {
|
||||||
val privateContact = privateContacts.firstOrNull { it.phoneNumbers.first().normalizedNumber == senderNumber }
|
val privateContact =
|
||||||
|
privateContacts.firstOrNull { it.phoneNumbers.first().normalizedNumber == senderNumber }
|
||||||
if (privateContact != null) {
|
if (privateContact != null) {
|
||||||
senderName = privateContact.name
|
senderName = privateContact.name
|
||||||
photoUri = privateContact.photoUri
|
photoUri = privateContact.photoUri
|
||||||
|
|
@ -591,8 +694,17 @@ fun Context.getSuggestedContacts(privateContacts: ArrayList<SimpleContact>): Arr
|
||||||
}
|
}
|
||||||
|
|
||||||
val phoneNumber = PhoneNumber(senderNumber, 0, "", senderNumber)
|
val phoneNumber = PhoneNumber(senderNumber, 0, "", senderNumber)
|
||||||
val contact = SimpleContact(0, 0, senderName, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
|
val contact = SimpleContact(
|
||||||
if (!contacts.map { it.phoneNumbers.first().normalizedNumber.trimToComparableNumber() }.contains(senderNumber.trimToComparableNumber())) {
|
0,
|
||||||
|
0,
|
||||||
|
senderName,
|
||||||
|
photoUri,
|
||||||
|
arrayListOf(phoneNumber),
|
||||||
|
ArrayList(),
|
||||||
|
ArrayList()
|
||||||
|
)
|
||||||
|
if (!contacts.map { it.phoneNumbers.first().normalizedNumber.trimToComparableNumber() }
|
||||||
|
.contains(senderNumber.trimToComparableNumber())) {
|
||||||
contacts.add(contact)
|
contacts.add(contact)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -690,7 +802,7 @@ fun Context.deleteConversation(threadId: Long) {
|
||||||
conversationsDB.deleteThreadId(threadId)
|
conversationsDB.deleteThreadId(threadId)
|
||||||
messagesDB.deleteThreadMessages(threadId)
|
messagesDB.deleteThreadMessages(threadId)
|
||||||
|
|
||||||
if (config.customNotifications.contains(threadId.toString()) && isOreoPlus()) {
|
if (config.customNotifications.contains(threadId.toString())) {
|
||||||
config.removeCustomNotificationsByThreadId(threadId)
|
config.removeCustomNotificationsByThreadId(threadId)
|
||||||
notificationManager.deleteNotificationChannel(threadId.toString())
|
notificationManager.deleteNotificationChannel(threadId.toString())
|
||||||
}
|
}
|
||||||
|
|
@ -853,13 +965,26 @@ fun Context.getThreadId(addresses: Set<String>): Long {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.showReceivedMessageNotification(messageId: Long, address: String, body: String, threadId: Long, bitmap: Bitmap?) {
|
fun Context.showReceivedMessageNotification(
|
||||||
|
messageId: Long,
|
||||||
|
address: String,
|
||||||
|
body: String,
|
||||||
|
threadId: Long,
|
||||||
|
bitmap: Bitmap?
|
||||||
|
) {
|
||||||
val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
|
val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
val senderName = getNameFromAddress(address, privateCursor)
|
val senderName = getNameFromAddress(address, privateCursor)
|
||||||
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
notificationHelper.showMessageNotification(messageId, address, body, threadId, bitmap, senderName)
|
notificationHelper.showMessageNotification(
|
||||||
|
messageId,
|
||||||
|
address,
|
||||||
|
body,
|
||||||
|
threadId,
|
||||||
|
bitmap,
|
||||||
|
senderName
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -993,7 +1118,8 @@ fun Context.updateLastConversationMessage(threadId: Long) {
|
||||||
// following Android code (which runs even if no messages are deleted):
|
// following Android code (which runs even if no messages are deleted):
|
||||||
// https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/android14-release/src/com/android/providers/telephony/MmsSmsProvider.java#1409
|
// https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/android14-release/src/com/android/providers/telephony/MmsSmsProvider.java#1409
|
||||||
val uri = Threads.CONTENT_URI
|
val uri = Threads.CONTENT_URI
|
||||||
val selection = "1 = 0" // always-false condition, because we don't actually want to delete any messages
|
val selection =
|
||||||
|
"1 = 0" // always-false condition, because we don't actually want to delete any messages
|
||||||
try {
|
try {
|
||||||
contentResolver.delete(uri, selection, null)
|
contentResolver.delete(uri, selection, null)
|
||||||
val newConversation = getConversations(threadId)[0]
|
val newConversation = getConversations(threadId)[0]
|
||||||
|
|
@ -1017,7 +1143,8 @@ fun Context.getFileSizeFromUri(uri: Uri): Long {
|
||||||
|
|
||||||
// if "content://" uri scheme, try contentResolver table
|
// if "content://" uri scheme, try contentResolver table
|
||||||
if (uri.scheme.equals(ContentResolver.SCHEME_CONTENT)) {
|
if (uri.scheme.equals(ContentResolver.SCHEME_CONTENT)) {
|
||||||
return contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null)?.use { cursor ->
|
return contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null)
|
||||||
|
?.use { cursor ->
|
||||||
// maybe shouldn't trust ContentResolver for size:
|
// maybe shouldn't trust ContentResolver for size:
|
||||||
// https://stackoverflow.com/questions/48302972/content-resolver-returns-wrong-size
|
// https://stackoverflow.com/questions/48302972/content-resolver-returns-wrong-size
|
||||||
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
|
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
|
||||||
|
|
@ -1061,7 +1188,8 @@ fun Context.insertOrUpdateConversation(
|
||||||
) {
|
) {
|
||||||
var updatedConv = conversation
|
var updatedConv = conversation
|
||||||
if (cachedConv != null && cachedConv.usesCustomTitle) {
|
if (cachedConv != null && cachedConv.usesCustomTitle) {
|
||||||
updatedConv = updatedConv.copy(title = cachedConv.title, usesCustomTitle = cachedConv.usesCustomTitle)
|
updatedConv =
|
||||||
|
updatedConv.copy(title = cachedConv.title, usesCustomTitle = cachedConv.usesCustomTitle)
|
||||||
}
|
}
|
||||||
conversationsDB.insertOrUpdate(updatedConv)
|
conversationsDB.insertOrUpdate(updatedConv)
|
||||||
}
|
}
|
||||||
|
|
@ -1076,10 +1204,15 @@ fun Context.renameConversation(conversation: Conversation, newTitle: String): Co
|
||||||
return updatedConv
|
return updatedConv
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.createTemporaryThread(message: Message, threadId: Long = generateRandomId(), cachedConv: Conversation?) {
|
fun Context.createTemporaryThread(
|
||||||
|
message: Message,
|
||||||
|
threadId: Long = generateRandomId(),
|
||||||
|
cachedConv: Conversation?
|
||||||
|
) {
|
||||||
val simpleContactHelper = SimpleContactsHelper(this)
|
val simpleContactHelper = SimpleContactsHelper(this)
|
||||||
val addresses = message.participants.getAddresses()
|
val addresses = message.participants.getAddresses()
|
||||||
val photoUri = if (addresses.size == 1) simpleContactHelper.getPhotoUriFromPhoneNumber(addresses.first()) else ""
|
val photoUri =
|
||||||
|
if (addresses.size == 1) simpleContactHelper.getPhotoUriFromPhoneNumber(addresses.first()) else ""
|
||||||
val title = if (cachedConv != null && cachedConv.usesCustomTitle) {
|
val title = if (cachedConv != null && cachedConv.usesCustomTitle) {
|
||||||
cachedConv.title
|
cachedConv.title
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1132,4 +1265,5 @@ fun Context.clearExpiredScheduledMessages(threadId: Long, messagesToDelete: List
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.getDefaultKeyboardHeight() = resources.getDimensionPixelSize(R.dimen.default_keyboard_height)
|
fun Context.getDefaultKeyboardHeight() =
|
||||||
|
resources.getDimensionPixelSize(R.dimen.default_keyboard_height)
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ import androidx.core.app.RemoteInput
|
||||||
import org.fossify.commons.extensions.getProperPrimaryColor
|
import org.fossify.commons.extensions.getProperPrimaryColor
|
||||||
import org.fossify.commons.extensions.notificationManager
|
import org.fossify.commons.extensions.notificationManager
|
||||||
import org.fossify.commons.helpers.SimpleContactsHelper
|
import org.fossify.commons.helpers.SimpleContactsHelper
|
||||||
import org.fossify.commons.helpers.isNougatPlus
|
|
||||||
import org.fossify.commons.helpers.isOreoPlus
|
|
||||||
import org.fossify.messages.R
|
import org.fossify.messages.R
|
||||||
import org.fossify.messages.activities.ThreadActivity
|
import org.fossify.messages.activities.ThreadActivity
|
||||||
import org.fossify.messages.extensions.config
|
import org.fossify.messages.extensions.config
|
||||||
|
|
@ -45,10 +43,12 @@ class NotificationHelper(private val context: Context) {
|
||||||
sender: String?,
|
sender: String?,
|
||||||
alertOnlyOnce: Boolean = false
|
alertOnlyOnce: Boolean = false
|
||||||
) {
|
) {
|
||||||
val hasCustomNotifications = context.config.customNotifications.contains(threadId.toString())
|
val hasCustomNotifications =
|
||||||
val notificationChannelId = if (hasCustomNotifications) threadId.toString() else NOTIFICATION_CHANNEL_ID
|
context.config.customNotifications.contains(threadId.toString())
|
||||||
|
val notificationChannelId =
|
||||||
|
if (hasCustomNotifications) threadId.toString() else NOTIFICATION_CHANNEL_ID
|
||||||
if (!hasCustomNotifications) {
|
if (!hasCustomNotifications) {
|
||||||
maybeCreateChannel(notificationChannelId, context.getString(R.string.channel_received_sms))
|
createChannel(notificationChannelId, context.getString(R.string.channel_received_sms))
|
||||||
}
|
}
|
||||||
|
|
||||||
val notificationId = threadId.hashCode()
|
val notificationId = threadId.hashCode()
|
||||||
|
|
@ -56,25 +56,40 @@ class NotificationHelper(private val context: Context) {
|
||||||
putExtra(THREAD_ID, threadId)
|
putExtra(THREAD_ID, threadId)
|
||||||
}
|
}
|
||||||
val contentPendingIntent =
|
val contentPendingIntent =
|
||||||
PendingIntent.getActivity(context, notificationId, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
|
PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
notificationId,
|
||||||
|
contentIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
||||||
|
)
|
||||||
|
|
||||||
val markAsReadIntent = Intent(context, MarkAsReadReceiver::class.java).apply {
|
val markAsReadIntent = Intent(context, MarkAsReadReceiver::class.java).apply {
|
||||||
action = MARK_AS_READ
|
action = MARK_AS_READ
|
||||||
putExtra(THREAD_ID, threadId)
|
putExtra(THREAD_ID, threadId)
|
||||||
}
|
}
|
||||||
val markAsReadPendingIntent =
|
val markAsReadPendingIntent =
|
||||||
PendingIntent.getBroadcast(context, notificationId, markAsReadIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
notificationId,
|
||||||
|
markAsReadIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
||||||
|
)
|
||||||
|
|
||||||
val deleteSmsIntent = Intent(context, DeleteSmsReceiver::class.java).apply {
|
val deleteSmsIntent = Intent(context, DeleteSmsReceiver::class.java).apply {
|
||||||
putExtra(THREAD_ID, threadId)
|
putExtra(THREAD_ID, threadId)
|
||||||
putExtra(MESSAGE_ID, messageId)
|
putExtra(MESSAGE_ID, messageId)
|
||||||
}
|
}
|
||||||
val deleteSmsPendingIntent =
|
val deleteSmsPendingIntent =
|
||||||
PendingIntent.getBroadcast(context, notificationId, deleteSmsIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
notificationId,
|
||||||
|
deleteSmsIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
||||||
|
)
|
||||||
|
|
||||||
var replyAction: NotificationCompat.Action? = null
|
var replyAction: NotificationCompat.Action? = null
|
||||||
val isNoReplySms = isShortCodeWithLetters(address)
|
val isNoReplySms = isShortCodeWithLetters(address)
|
||||||
if (isNougatPlus() && !isNoReplySms) {
|
if (!isNoReplySms) {
|
||||||
val replyLabel = context.getString(R.string.reply)
|
val replyLabel = context.getString(R.string.reply)
|
||||||
val remoteInput = RemoteInput.Builder(REPLY)
|
val remoteInput = RemoteInput.Builder(REPLY)
|
||||||
.setLabel(replyLabel)
|
.setLabel(replyLabel)
|
||||||
|
|
@ -92,7 +107,11 @@ class NotificationHelper(private val context: Context) {
|
||||||
replyIntent,
|
replyIntent,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
||||||
)
|
)
|
||||||
replyAction = NotificationCompat.Action.Builder(R.drawable.ic_send_vector, replyLabel, replyPendingIntent)
|
replyAction = NotificationCompat.Action.Builder(
|
||||||
|
R.drawable.ic_send_vector,
|
||||||
|
replyLabel,
|
||||||
|
replyPendingIntent
|
||||||
|
)
|
||||||
.addRemoteInput(remoteInput)
|
.addRemoteInput(remoteInput)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +132,9 @@ class NotificationHelper(private val context: Context) {
|
||||||
setContentTitle(sender)
|
setContentTitle(sender)
|
||||||
setLargeIcon(largeIcon)
|
setLargeIcon(largeIcon)
|
||||||
val summaryText = context.getString(R.string.new_message)
|
val summaryText = context.getString(R.string.new_message)
|
||||||
setStyle(NotificationCompat.BigTextStyle().setSummaryText(summaryText).bigText(body))
|
setStyle(
|
||||||
|
NotificationCompat.BigTextStyle().setSummaryText(summaryText).bigText(body)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,7 +153,11 @@ class NotificationHelper(private val context: Context) {
|
||||||
builder.addAction(replyAction)
|
builder.addAction(replyAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.addAction(org.fossify.commons.R.drawable.ic_check_vector, context.getString(R.string.mark_as_read), markAsReadPendingIntent)
|
builder.addAction(
|
||||||
|
org.fossify.commons.R.drawable.ic_check_vector,
|
||||||
|
context.getString(R.string.mark_as_read),
|
||||||
|
markAsReadPendingIntent
|
||||||
|
)
|
||||||
.setChannelId(notificationChannelId)
|
.setChannelId(notificationChannelId)
|
||||||
if (isNoReplySms) {
|
if (isNoReplySms) {
|
||||||
builder.addAction(
|
builder.addAction(
|
||||||
|
|
@ -146,19 +171,27 @@ class NotificationHelper(private val context: Context) {
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
fun showSendingFailedNotification(recipientName: String, threadId: Long) {
|
fun showSendingFailedNotification(recipientName: String, threadId: Long) {
|
||||||
val hasCustomNotifications = context.config.customNotifications.contains(threadId.toString())
|
val hasCustomNotifications =
|
||||||
val notificationChannelId = if (hasCustomNotifications) threadId.toString() else NOTIFICATION_CHANNEL_ID
|
context.config.customNotifications.contains(threadId.toString())
|
||||||
|
val notificationChannelId =
|
||||||
|
if (hasCustomNotifications) threadId.toString() else NOTIFICATION_CHANNEL_ID
|
||||||
if (!hasCustomNotifications) {
|
if (!hasCustomNotifications) {
|
||||||
maybeCreateChannel(notificationChannelId, context.getString(R.string.message_not_sent_short))
|
createChannel(notificationChannelId, context.getString(R.string.message_not_sent_short))
|
||||||
}
|
}
|
||||||
|
|
||||||
val notificationId = generateRandomId().hashCode()
|
val notificationId = generateRandomId().hashCode()
|
||||||
val intent = Intent(context, ThreadActivity::class.java).apply {
|
val intent = Intent(context, ThreadActivity::class.java).apply {
|
||||||
putExtra(THREAD_ID, threadId)
|
putExtra(THREAD_ID, threadId)
|
||||||
}
|
}
|
||||||
val contentPendingIntent = PendingIntent.getActivity(context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
|
val contentPendingIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
notificationId,
|
||||||
|
intent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
||||||
|
)
|
||||||
|
|
||||||
val summaryText = String.format(context.getString(R.string.message_sending_error), recipientName)
|
val summaryText =
|
||||||
|
String.format(context.getString(R.string.message_sending_error), recipientName)
|
||||||
val largeIcon = SimpleContactsHelper(context).getContactLetterIcon(recipientName)
|
val largeIcon = SimpleContactsHelper(context).getContactLetterIcon(recipientName)
|
||||||
val builder = NotificationCompat.Builder(context, notificationChannelId)
|
val builder = NotificationCompat.Builder(context, notificationChannelId)
|
||||||
.setContentTitle(context.getString(R.string.message_not_sent_short))
|
.setContentTitle(context.getString(R.string.message_not_sent_short))
|
||||||
|
|
@ -177,8 +210,7 @@ class NotificationHelper(private val context: Context) {
|
||||||
notificationManager.notify(notificationId, builder.build())
|
notificationManager.notify(notificationId, builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun maybeCreateChannel(id: String, name: String) {
|
private fun createChannel(id: String, name: String) {
|
||||||
if (isOreoPlus()) {
|
|
||||||
val audioAttributes = AudioAttributes.Builder()
|
val audioAttributes = AudioAttributes.Builder()
|
||||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
|
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
|
||||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||||
|
|
@ -194,9 +226,13 @@ class NotificationHelper(private val context: Context) {
|
||||||
notificationManager.createNotificationChannel(this)
|
notificationManager.createNotificationChannel(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun getMessagesStyle(address: String, body: String, notificationId: Int, name: String?): NotificationCompat.MessagingStyle {
|
private fun getMessagesStyle(
|
||||||
|
address: String,
|
||||||
|
body: String,
|
||||||
|
notificationId: Int,
|
||||||
|
name: String?
|
||||||
|
): NotificationCompat.MessagingStyle {
|
||||||
val sender = if (name != null) {
|
val sender = if (name != null) {
|
||||||
Person.Builder()
|
Person.Builder()
|
||||||
.setName(name)
|
.setName(name)
|
||||||
|
|
@ -210,18 +246,20 @@ class NotificationHelper(private val context: Context) {
|
||||||
getOldMessages(notificationId).forEach {
|
getOldMessages(notificationId).forEach {
|
||||||
style.addMessage(it)
|
style.addMessage(it)
|
||||||
}
|
}
|
||||||
val newMessage = NotificationCompat.MessagingStyle.Message(body, System.currentTimeMillis(), sender)
|
val newMessage =
|
||||||
|
NotificationCompat.MessagingStyle.Message(body, System.currentTimeMillis(), sender)
|
||||||
style.addMessage(newMessage)
|
style.addMessage(newMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOldMessages(notificationId: Int): List<NotificationCompat.MessagingStyle.Message> {
|
private fun getOldMessages(notificationId: Int): List<NotificationCompat.MessagingStyle.Message> {
|
||||||
if (!isNougatPlus()) {
|
val currentNotification =
|
||||||
return emptyList()
|
notificationManager.activeNotifications.find { it.id == notificationId }
|
||||||
}
|
|
||||||
val currentNotification = notificationManager.activeNotifications.find { it.id == notificationId }
|
|
||||||
return if (currentNotification != null) {
|
return if (currentNotification != null) {
|
||||||
val activeStyle = NotificationCompat.MessagingStyle.extractMessagingStyleFromNotification(currentNotification.notification)
|
val activeStyle =
|
||||||
|
NotificationCompat.MessagingStyle.extractMessagingStyleFromNotification(
|
||||||
|
currentNotification.notification
|
||||||
|
)
|
||||||
activeStyle?.messages.orEmpty()
|
activeStyle?.messages.orEmpty()
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 890 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 5 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |