mirror of
https://github.com/SimpleMobileTools/Simple-SMS-Messenger.git
synced 2025-06-05 21:49:22 +02:00
@@ -1,6 +1,14 @@
|
|||||||
Changelog
|
Changelog
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
Version 5.8.0 *(2021-01-02)*
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
* Improved delivery reports, show a notification at failed messages
|
||||||
|
* Allow resending failed messages with tapping them
|
||||||
|
* Added multiple dual-SIM related improvements
|
||||||
|
* Many other UX, stability, performance and translation improvements
|
||||||
|
|
||||||
Version 5.7.0 *(2020-12-30)*
|
Version 5.7.0 *(2020-12-30)*
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
@@ -16,8 +16,8 @@ android {
|
|||||||
applicationId "com.simplemobiletools.smsmessenger"
|
applicationId "com.simplemobiletools.smsmessenger"
|
||||||
minSdkVersion 22
|
minSdkVersion 22
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 23
|
versionCode 25
|
||||||
versionName "5.7.0"
|
versionName "5.8.0"
|
||||||
setProperty("archivesBaseName", "sms-messenger")
|
setProperty("archivesBaseName", "sms-messenger")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.simplemobiletools:commons:5.32.19'
|
implementation 'com.simplemobiletools:commons:5.32.20'
|
||||||
implementation 'org.greenrobot:eventbus:3.2.0'
|
implementation 'org.greenrobot:eventbus:3.2.0'
|
||||||
implementation 'com.klinkerapps:android-smsmms:5.2.6'
|
implementation 'com.klinkerapps:android-smsmms:5.2.6'
|
||||||
implementation 'com.github.tibbi:IndicatorFastScroll:08f512858a'
|
implementation 'com.github.tibbi:IndicatorFastScroll:08f512858a'
|
||||||
|
@@ -121,6 +121,10 @@
|
|||||||
|
|
||||||
<service android:name="com.android.mms.transaction.TransactionService" />
|
<service android:name="com.android.mms.transaction.TransactionService" />
|
||||||
|
|
||||||
|
<receiver android:name=".receivers.SmsStatusSentReceiver" />
|
||||||
|
|
||||||
|
<receiver android:name=".receivers.SmsStatusDeliveredReceiver" />
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".receivers.SmsReceiver"
|
android:name=".receivers.SmsReceiver"
|
||||||
android:permission="android.permission.BROADCAST_SMS">
|
android:permission="android.permission.BROADCAST_SMS">
|
||||||
@@ -149,11 +153,6 @@
|
|||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:taskAffinity="com.klinker.android.messaging.MMS_RECEIVED" />
|
android:taskAffinity="com.klinker.android.messaging.MMS_RECEIVED" />
|
||||||
|
|
||||||
<receiver
|
|
||||||
android:name=".receivers.SmsSentReceiver"
|
|
||||||
android:exported="true"
|
|
||||||
android:taskAffinity="${applicationId}.SMS_SENT" />
|
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".receivers.MarkAsReadReceiver"
|
android:name=".receivers.MarkAsReadReceiver"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
|
@@ -8,6 +8,7 @@ import android.graphics.drawable.Drawable
|
|||||||
import android.media.MediaMetadataRetriever
|
import android.media.MediaMetadataRetriever
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
import android.provider.Telephony
|
import android.provider.Telephony
|
||||||
import android.telephony.SubscriptionManager
|
import android.telephony.SubscriptionManager
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
@@ -39,6 +40,9 @@ import com.simplemobiletools.smsmessenger.adapters.ThreadAdapter
|
|||||||
import com.simplemobiletools.smsmessenger.extensions.*
|
import com.simplemobiletools.smsmessenger.extensions.*
|
||||||
import com.simplemobiletools.smsmessenger.helpers.*
|
import com.simplemobiletools.smsmessenger.helpers.*
|
||||||
import com.simplemobiletools.smsmessenger.models.*
|
import com.simplemobiletools.smsmessenger.models.*
|
||||||
|
import com.simplemobiletools.smsmessenger.receivers.SmsStatusDeliveredReceiver
|
||||||
|
import com.simplemobiletools.smsmessenger.receivers.SmsStatusSentReceiver
|
||||||
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import kotlinx.android.synthetic.main.activity_thread.*
|
import kotlinx.android.synthetic.main.activity_thread.*
|
||||||
import kotlinx.android.synthetic.main.item_attachment.view.*
|
import kotlinx.android.synthetic.main.item_attachment.view.*
|
||||||
import kotlinx.android.synthetic.main.item_selected_contact.view.*
|
import kotlinx.android.synthetic.main.item_selected_contact.view.*
|
||||||
@@ -53,6 +57,7 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
private var threadId = 0L
|
private var threadId = 0L
|
||||||
private var currentSIMCardIndex = 0
|
private var currentSIMCardIndex = 0
|
||||||
private var isActivityVisible = false
|
private var isActivityVisible = false
|
||||||
|
private var refreshedSinceSent = false
|
||||||
private var threadItems = ArrayList<ThreadItem>()
|
private var threadItems = ArrayList<ThreadItem>()
|
||||||
private var bus: EventBus? = null
|
private var bus: EventBus? = null
|
||||||
private var participants = ArrayList<SimpleContact>()
|
private var participants = ArrayList<SimpleContact>()
|
||||||
@@ -219,8 +224,18 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
invalidateOptionsMenu()
|
invalidateOptionsMenu()
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
val adapter = ThreadAdapter(this, threadItems, thread_messages_list, thread_messages_fastscroller) {}
|
val currAdapter = thread_messages_list.adapter
|
||||||
thread_messages_list.adapter = adapter
|
if (currAdapter == null) {
|
||||||
|
ThreadAdapter(this, threadItems, thread_messages_list, thread_messages_fastscroller) {
|
||||||
|
(it as? ThreadError)?.apply {
|
||||||
|
thread_type_message.setText(it.messageText)
|
||||||
|
}
|
||||||
|
}.apply {
|
||||||
|
thread_messages_list.adapter = this
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(currAdapter as ThreadAdapter).updateMessages(threadItems)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleContactsHelper(this).getAvailableContacts(false) { contacts ->
|
SimpleContactsHelper(this).getAvailableContacts(false) { contacts ->
|
||||||
@@ -509,7 +524,11 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
items.add(message)
|
items.add(message)
|
||||||
|
|
||||||
if (message.type == Telephony.Sms.MESSAGE_TYPE_FAILED) {
|
if (message.type == Telephony.Sms.MESSAGE_TYPE_FAILED) {
|
||||||
items.add(ThreadError(message.id))
|
items.add(ThreadError(message.id, message.body))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.type == Telephony.Sms.MESSAGE_TYPE_OUTBOX) {
|
||||||
|
items.add(ThreadSending(message.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message.read) {
|
if (!message.read) {
|
||||||
@@ -637,12 +656,24 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
transaction.sendNewMessage(message, threadId)
|
val smsSentIntent = Intent(this, SmsStatusSentReceiver::class.java)
|
||||||
|
val deliveredIntent = Intent(this, SmsStatusDeliveredReceiver::class.java)
|
||||||
|
|
||||||
|
transaction.setExplicitBroadcastForSentSms(smsSentIntent)
|
||||||
|
transaction.setExplicitBroadcastForDeliveredSms(deliveredIntent)
|
||||||
|
|
||||||
|
refreshedSinceSent = false
|
||||||
|
transaction.sendNewMessage(message, threadId)
|
||||||
thread_type_message.setText("")
|
thread_type_message.setText("")
|
||||||
attachmentUris.clear()
|
attachmentUris.clear()
|
||||||
thread_attachments_holder.beGone()
|
thread_attachments_holder.beGone()
|
||||||
thread_attachments_wrapper.removeAllViews()
|
thread_attachments_wrapper.removeAllViews()
|
||||||
|
|
||||||
|
Handler().postDelayed({
|
||||||
|
if (!refreshedSinceSent) {
|
||||||
|
refreshMessages()
|
||||||
|
}
|
||||||
|
}, 2000)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
showErrorToast(e)
|
showErrorToast(e)
|
||||||
} catch (e: Error) {
|
} catch (e: Error) {
|
||||||
@@ -704,8 +735,10 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
showSelectedContacts()
|
showSelectedContacts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
@Subscribe(threadMode = ThreadMode.ASYNC)
|
@Subscribe(threadMode = ThreadMode.ASYNC)
|
||||||
fun refreshMessages(event: Events.RefreshMessages) {
|
fun refreshMessages(event: Events.RefreshMessages) {
|
||||||
|
refreshedSinceSent = true
|
||||||
if (isActivityVisible) {
|
if (isActivityVisible) {
|
||||||
notificationManager.cancel(threadId.hashCode())
|
notificationManager.cancel(threadId.hashCode())
|
||||||
}
|
}
|
||||||
@@ -713,8 +746,17 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
val lastMaxId = messages.maxByOrNull { it.id }?.id ?: 0L
|
val lastMaxId = messages.maxByOrNull { it.id }?.id ?: 0L
|
||||||
messages = getMessages(threadId)
|
messages = getMessages(threadId)
|
||||||
|
|
||||||
messages.filter { !it.isReceivedMessage() && it.id > lastMaxId }.forEach {
|
messages.filter { !it.isReceivedMessage() && it.id > lastMaxId }.forEach { latestMessage ->
|
||||||
messagesDB.insertOrIgnore(it)
|
// subscriptionIds seem to be not filled out at sending with multiple SIM cards, so fill it manually
|
||||||
|
if (SubscriptionManager.from(this).activeSubscriptionInfoList?.size ?: 0 > 1) {
|
||||||
|
val SIMId = availableSIMCards.getOrNull(currentSIMCardIndex)?.subscriptionId
|
||||||
|
if (SIMId != null) {
|
||||||
|
updateMessageSubscriptionId(latestMessage.id, SIMId)
|
||||||
|
latestMessage.subscriptionId = SIMId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messagesDB.insertOrIgnore(latestMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
setupAdapter()
|
setupAdapter()
|
||||||
|
@@ -56,6 +56,7 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis
|
|||||||
R.id.cab_dial_number -> dialNumber()
|
R.id.cab_dial_number -> dialNumber()
|
||||||
R.id.cab_copy_number -> copyNumberToClipboard()
|
R.id.cab_copy_number -> copyNumberToClipboard()
|
||||||
R.id.cab_delete -> askConfirmDelete()
|
R.id.cab_delete -> askConfirmDelete()
|
||||||
|
R.id.cab_select_all -> selectAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@ import kotlinx.android.synthetic.main.item_received_unknown_attachment.view.*
|
|||||||
import kotlinx.android.synthetic.main.item_sent_unknown_attachment.view.*
|
import kotlinx.android.synthetic.main.item_sent_unknown_attachment.view.*
|
||||||
import kotlinx.android.synthetic.main.item_thread_date_time.view.*
|
import kotlinx.android.synthetic.main.item_thread_date_time.view.*
|
||||||
import kotlinx.android.synthetic.main.item_thread_error.view.*
|
import kotlinx.android.synthetic.main.item_thread_error.view.*
|
||||||
|
import kotlinx.android.synthetic.main.item_thread_sending.view.*
|
||||||
import kotlinx.android.synthetic.main.item_thread_success.view.*
|
import kotlinx.android.synthetic.main.item_thread_success.view.*
|
||||||
|
|
||||||
class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
|
class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
|
||||||
@@ -74,6 +75,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
R.id.cab_share -> shareText()
|
R.id.cab_share -> shareText()
|
||||||
R.id.cab_select_text -> selectText()
|
R.id.cab_select_text -> selectText()
|
||||||
R.id.cab_delete -> askConfirmDelete()
|
R.id.cab_delete -> askConfirmDelete()
|
||||||
|
R.id.cab_select_all -> selectAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +97,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
THREAD_RECEIVED_MESSAGE -> R.layout.item_received_message
|
THREAD_RECEIVED_MESSAGE -> R.layout.item_received_message
|
||||||
THREAD_SENT_MESSAGE_ERROR -> R.layout.item_thread_error
|
THREAD_SENT_MESSAGE_ERROR -> R.layout.item_thread_error
|
||||||
THREAD_SENT_MESSAGE_SUCCESS -> R.layout.item_thread_success
|
THREAD_SENT_MESSAGE_SUCCESS -> R.layout.item_thread_success
|
||||||
|
THREAD_SENT_MESSAGE_SENDING -> R.layout.item_thread_sending
|
||||||
else -> R.layout.item_sent_message
|
else -> R.layout.item_sent_message
|
||||||
}
|
}
|
||||||
return createViewHolder(layout, parent)
|
return createViewHolder(layout, parent)
|
||||||
@@ -102,11 +105,14 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val item = messages[position]
|
val item = messages[position]
|
||||||
holder.bindView(item, true, item is Message) { itemView, layoutPosition ->
|
val isClickable = item is ThreadError || item is Message
|
||||||
|
val isLongClickable = item is Message
|
||||||
|
holder.bindView(item, isClickable, isLongClickable) { itemView, layoutPosition ->
|
||||||
when (item) {
|
when (item) {
|
||||||
is ThreadDateTime -> setupDateTime(itemView, item)
|
is ThreadDateTime -> setupDateTime(itemView, item)
|
||||||
is ThreadSuccess -> setupThreadSuccess(itemView)
|
is ThreadSuccess -> setupThreadSuccess(itemView)
|
||||||
is ThreadError -> setupThreadError(itemView)
|
is ThreadError -> setupThreadError(itemView)
|
||||||
|
is ThreadSending -> setupThreadSending(itemView)
|
||||||
else -> setupView(itemView, item as Message)
|
else -> setupView(itemView, item as Message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,6 +128,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
(messages[position] as? Message)?.isReceivedMessage() == true -> THREAD_RECEIVED_MESSAGE
|
(messages[position] as? Message)?.isReceivedMessage() == true -> THREAD_RECEIVED_MESSAGE
|
||||||
item is ThreadError -> THREAD_SENT_MESSAGE_ERROR
|
item is ThreadError -> THREAD_SENT_MESSAGE_ERROR
|
||||||
item is ThreadSuccess -> THREAD_SENT_MESSAGE_SUCCESS
|
item is ThreadSuccess -> THREAD_SENT_MESSAGE_SUCCESS
|
||||||
|
item is ThreadSending -> THREAD_SENT_MESSAGE_SENDING
|
||||||
else -> THREAD_SENT_MESSAGE
|
else -> THREAD_SENT_MESSAGE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,10 +197,13 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
|
|
||||||
private fun isThreadDateTime(position: Int) = messages.getOrNull(position) is ThreadDateTime
|
private fun isThreadDateTime(position: Int) = messages.getOrNull(position) is ThreadDateTime
|
||||||
|
|
||||||
override fun onViewRecycled(holder: ViewHolder) {
|
fun updateMessages(newMessages: ArrayList<ThreadItem>) {
|
||||||
super.onViewRecycled(holder)
|
val oldHashCode = messages.hashCode()
|
||||||
if (!activity.isDestroyed && !activity.isFinishing && holder.itemView.thread_message_sender_photo != null) {
|
val newHashCode = newMessages.hashCode()
|
||||||
Glide.with(activity).clear(holder.itemView.thread_message_sender_photo)
|
if (newHashCode != oldHashCode) {
|
||||||
|
messages = newMessages
|
||||||
|
notifyDataSetChanged()
|
||||||
|
recyclerView.scrollToPosition(messages.size - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +266,9 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
}
|
}
|
||||||
|
|
||||||
builder.into(imageView.attachment_image)
|
builder.into(imageView.attachment_image)
|
||||||
imageView.attachment_image.setOnClickListener { launchViewIntent(uri, mimetype, attachment.filename) }
|
imageView.attachment_image.setOnClickListener {
|
||||||
|
launchViewIntent(uri, mimetype, attachment.filename)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (message.isReceivedMessage()) {
|
if (message.isReceivedMessage()) {
|
||||||
val attachmentView = layoutInflater.inflate(R.layout.item_received_unknown_attachment, null).apply {
|
val attachmentView = layoutInflater.inflate(R.layout.item_received_unknown_attachment, null).apply {
|
||||||
@@ -265,7 +277,9 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
thread_received_attachment_label.text = attachment.filename
|
thread_received_attachment_label.text = attachment.filename
|
||||||
}
|
}
|
||||||
setTextColor(textColor)
|
setTextColor(textColor)
|
||||||
setOnClickListener { launchViewIntent(uri, mimetype, attachment.filename) }
|
setOnClickListener {
|
||||||
|
launchViewIntent(uri, mimetype, attachment.filename)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thread_mesage_attachments_holder.addView(attachmentView)
|
thread_mesage_attachments_holder.addView(attachmentView)
|
||||||
@@ -278,7 +292,9 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
if (attachment.filename.isNotEmpty()) {
|
if (attachment.filename.isNotEmpty()) {
|
||||||
thread_sent_attachment_label.text = attachment.filename
|
thread_sent_attachment_label.text = attachment.filename
|
||||||
}
|
}
|
||||||
setOnClickListener { launchViewIntent(uri, mimetype, attachment.filename) }
|
setOnClickListener {
|
||||||
|
launchViewIntent(uri, mimetype, attachment.filename)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thread_mesage_attachments_holder.addView(attachmentView)
|
thread_mesage_attachments_holder.addView(attachmentView)
|
||||||
@@ -333,6 +349,20 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupThreadError(view: View) {
|
private fun setupThreadError(view: View) {
|
||||||
view.thread_error.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
|
view.thread_error.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize - 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupThreadSending(view: View) {
|
||||||
|
view.thread_sending.apply {
|
||||||
|
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
|
||||||
|
setTextColor(textColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewRecycled(holder: ViewHolder) {
|
||||||
|
super.onViewRecycled(holder)
|
||||||
|
if (!activity.isDestroyed && !activity.isFinishing && holder.itemView.thread_message_sender_photo != null) {
|
||||||
|
Glide.with(activity).clear(holder.itemView.thread_message_sender_photo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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(
|
||||||
@@ -554,6 +577,26 @@ fun Context.markThreadMessagesUnread(threadId: Long) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Context.updateMessageType(id: Long, status: Int) {
|
||||||
|
val uri = Sms.CONTENT_URI
|
||||||
|
val contentValues = ContentValues().apply {
|
||||||
|
put(Sms.TYPE, status)
|
||||||
|
}
|
||||||
|
val selection = "${Sms._ID} = ?"
|
||||||
|
val selectionArgs = arrayOf(id.toString())
|
||||||
|
contentResolver.update(uri, contentValues, selection, selectionArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.updateMessageSubscriptionId(messageId: Long, subscriptionId: Int) {
|
||||||
|
val uri = Sms.CONTENT_URI
|
||||||
|
val contentValues = ContentValues().apply {
|
||||||
|
put(Sms.SUBSCRIPTION_ID, subscriptionId)
|
||||||
|
}
|
||||||
|
val selection = "${Sms._ID} = ?"
|
||||||
|
val selectionArgs = arrayOf(messageId.toString())
|
||||||
|
contentResolver.update(uri, contentValues, selection, selectionArgs)
|
||||||
|
}
|
||||||
|
|
||||||
fun Context.updateUnreadCountBadge(conversations: List<Conversation>) {
|
fun Context.updateUnreadCountBadge(conversations: List<Conversation>) {
|
||||||
val unreadCount = conversations.count { !it.read }
|
val unreadCount = conversations.count { !it.read }
|
||||||
if (unreadCount == 0) {
|
if (unreadCount == 0) {
|
||||||
@@ -592,16 +635,21 @@ 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 {
|
||||||
|
val senderName = getNameFromAddress(address, privateCursor)
|
||||||
|
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
showMessageNotification(address, body, threadId, bitmap, senderName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.getNameFromAddress(address: String, privateCursor: Cursor?): String {
|
||||||
var sender = getNameAndPhotoFromPhoneNumber(address).name
|
var sender = getNameAndPhotoFromPhoneNumber(address).name
|
||||||
if (address == sender) {
|
if (address == sender) {
|
||||||
val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
||||||
sender = privateContacts.firstOrNull { it.doesContainPhoneNumber(address) }?.name ?: address
|
sender = privateContacts.firstOrNull { it.doesContainPhoneNumber(address) }?.name ?: address
|
||||||
}
|
}
|
||||||
|
return sender
|
||||||
Handler(Looper.getMainLooper()).post {
|
|
||||||
showMessageNotification(address, body, threadId, bitmap, sender)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
|
@@ -23,6 +23,7 @@ const val THREAD_RECEIVED_MESSAGE = 2
|
|||||||
const val THREAD_SENT_MESSAGE = 3
|
const val THREAD_SENT_MESSAGE = 3
|
||||||
const val THREAD_SENT_MESSAGE_ERROR = 4
|
const val THREAD_SENT_MESSAGE_ERROR = 4
|
||||||
const val THREAD_SENT_MESSAGE_SUCCESS = 5
|
const val THREAD_SENT_MESSAGE_SUCCESS = 5
|
||||||
|
const val THREAD_SENT_MESSAGE_SENDING = 6
|
||||||
|
|
||||||
fun refreshMessages() {
|
fun refreshMessages() {
|
||||||
EventBus.getDefault().post(Events.RefreshMessages())
|
EventBus.getDefault().post(Events.RefreshMessages())
|
||||||
|
@@ -29,6 +29,9 @@ interface MessagesDao {
|
|||||||
@Query("UPDATE messages SET read = 1 WHERE thread_id = :threadId")
|
@Query("UPDATE messages SET read = 1 WHERE thread_id = :threadId")
|
||||||
fun markThreadRead(threadId: Long)
|
fun markThreadRead(threadId: Long)
|
||||||
|
|
||||||
|
@Query("UPDATE messages SET type = :type WHERE id = :id")
|
||||||
|
fun updateType(id: Long, type: Int): Int
|
||||||
|
|
||||||
@Query("DELETE FROM messages WHERE id = :id")
|
@Query("DELETE FROM messages WHERE id = :id")
|
||||||
fun delete(id: Long)
|
fun delete(id: Long)
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ data class Message(
|
|||||||
@ColumnInfo(name = "attachment") val attachment: MessageAttachment?,
|
@ColumnInfo(name = "attachment") val attachment: MessageAttachment?,
|
||||||
@ColumnInfo(name = "sender_name") var senderName: String,
|
@ColumnInfo(name = "sender_name") var senderName: String,
|
||||||
@ColumnInfo(name = "sender_photo_uri") val senderPhotoUri: String,
|
@ColumnInfo(name = "sender_photo_uri") val senderPhotoUri: String,
|
||||||
@ColumnInfo(name = "subscription_id") val subscriptionId: Int) : ThreadItem() {
|
@ColumnInfo(name = "subscription_id") var subscriptionId: Int) : ThreadItem() {
|
||||||
|
|
||||||
fun isReceivedMessage() = type == Telephony.Sms.MESSAGE_TYPE_INBOX
|
fun isReceivedMessage() = type == Telephony.Sms.MESSAGE_TYPE_INBOX
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
package com.simplemobiletools.smsmessenger.models
|
package com.simplemobiletools.smsmessenger.models
|
||||||
|
|
||||||
data class ThreadError(val messageID: Long) : ThreadItem()
|
data class ThreadError(val messageId: Long, val messageText: String) : ThreadItem()
|
||||||
|
@@ -0,0 +1,3 @@
|
|||||||
|
package com.simplemobiletools.smsmessenger.models
|
||||||
|
|
||||||
|
data class ThreadSending(val messageId: Long) : ThreadItem()
|
@@ -44,7 +44,8 @@ class SmsReceiver : BroadcastReceiver() {
|
|||||||
context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations())
|
context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations())
|
||||||
|
|
||||||
val participant = SimpleContact(0, 0, address, "", arrayListOf(address), ArrayList(), ArrayList())
|
val participant = SimpleContact(0, 0, address, "", arrayListOf(address), ArrayList(), ArrayList())
|
||||||
val message = Message(newMessageId, body, type, arrayListOf(participant), (date / 1000).toInt(), false, threadId, false, null, address, "", subscriptionId)
|
val message = Message(newMessageId, body, type, arrayListOf(participant), (date / 1000).toInt(), false, threadId,
|
||||||
|
false, null, address, "", subscriptionId)
|
||||||
context.messagesDB.insertOrUpdate(message)
|
context.messagesDB.insertOrUpdate(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
package com.simplemobiletools.smsmessenger.receivers
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import com.klinker.android.send_message.SentReceiver
|
|
||||||
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
|
|
||||||
|
|
||||||
class SmsSentReceiver : SentReceiver() {
|
|
||||||
override fun onMessageStatusUpdated(context: Context, intent: Intent, receiverResultCode: Int) {
|
|
||||||
refreshMessages()
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,37 @@
|
|||||||
|
package com.simplemobiletools.smsmessenger.receivers
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.provider.Telephony
|
||||||
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.messagesDB
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.updateMessageType
|
||||||
|
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
|
||||||
|
|
||||||
|
class SmsStatusDeliveredReceiver : BroadcastReceiver() {
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
if (intent.extras?.containsKey("message_uri") == true) {
|
||||||
|
val uri = Uri.parse(intent.getStringExtra("message_uri"))
|
||||||
|
val messageId = uri?.lastPathSegment?.toLong() ?: 0L
|
||||||
|
ensureBackgroundThread {
|
||||||
|
val type = Telephony.Sms.MESSAGE_TYPE_SENT
|
||||||
|
context.updateMessageType(messageId, type)
|
||||||
|
val updated = context.messagesDB.updateType(messageId, type)
|
||||||
|
if (updated == 0) {
|
||||||
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
|
ensureBackgroundThread {
|
||||||
|
context.messagesDB.updateType(messageId, type)
|
||||||
|
}
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshMessages()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,109 @@
|
|||||||
|
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.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.simplemobiletools.commons.extensions.getMyContactsCursor
|
||||||
|
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 : BroadcastReceiver() {
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
if (intent.extras?.containsKey("message_uri") == true) {
|
||||||
|
val uri = Uri.parse(intent.getStringExtra("message_uri"))
|
||||||
|
val messageId = uri?.lastPathSegment?.toLong() ?: 0L
|
||||||
|
ensureBackgroundThread {
|
||||||
|
val type = if (intent.extras!!.containsKey("errorCode")) {
|
||||||
|
showSendingFailedNotification(context, messageId)
|
||||||
|
Telephony.Sms.MESSAGE_TYPE_FAILED
|
||||||
|
} else {
|
||||||
|
Telephony.Sms.MESSAGE_TYPE_OUTBOX
|
||||||
|
}
|
||||||
|
context.updateMessageType(messageId, type)
|
||||||
|
context.messagesDB.updateType(messageId, type)
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
@@ -42,7 +42,7 @@
|
|||||||
android:id="@+id/no_contacts_placeholder"
|
android:id="@+id/no_contacts_placeholder"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/message_divider_two"
|
android:layout_below="@+id/suggestions_scrollview"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_marginTop="@dimen/bigger_margin"
|
android:layout_marginTop="@dimen/bigger_margin"
|
||||||
android:alpha="0.8"
|
android:alpha="0.8"
|
||||||
|
@@ -6,6 +6,6 @@
|
|||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:paddingStart="@dimen/activity_margin"
|
android:paddingStart="@dimen/activity_margin"
|
||||||
android:paddingEnd="@dimen/activity_margin"
|
android:paddingEnd="@dimen/activity_margin"
|
||||||
android:text="@string/message_not_sent"
|
android:text="@string/message_not_sent_touch_retry"
|
||||||
android:textColor="@color/theme_dark_red_primary_color"
|
android:textColor="@color/theme_dark_red_primary_color"
|
||||||
android:textSize="@dimen/normal_text_size" />
|
android:textSize="@dimen/normal_text_size" />
|
||||||
|
10
app/src/main/res/layout/item_thread_sending.xml
Normal file
10
app/src/main/res/layout/item_thread_sending.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/thread_sending"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="end"
|
||||||
|
android:paddingStart="@dimen/activity_margin"
|
||||||
|
android:paddingEnd="@dimen/activity_margin"
|
||||||
|
android:text="@string/sending"
|
||||||
|
android:textSize="@dimen/normal_text_size" />
|
@@ -25,4 +25,8 @@
|
|||||||
android:id="@+id/cab_copy_number"
|
android:id="@+id/cab_copy_number"
|
||||||
android:title="@string/copy_number_to_clipboard"
|
android:title="@string/copy_number_to_clipboard"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/cab_select_all"
|
||||||
|
android:title="@string/select_all"
|
||||||
|
app:showAsAction="never" />
|
||||||
</menu>
|
</menu>
|
||||||
|
@@ -20,4 +20,8 @@
|
|||||||
android:icon="@drawable/ic_delete_vector"
|
android:icon="@drawable/ic_delete_vector"
|
||||||
android:title="@string/delete"
|
android:title="@string/delete"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/cab_select_all"
|
||||||
|
android:title="@string/select_all"
|
||||||
|
app:showAsAction="never" />
|
||||||
</menu>
|
</menu>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Schlichter SMS Messenger</string>
|
<string name="app_name">Schlichter SMS Messenger</string>
|
||||||
<string name="app_launcher_name">SMS Messenger</string>
|
<string name="app_launcher_name">SMS Messenger</string>
|
||||||
<string name="type_a_message">Schreibe eine Nachricht…</string>
|
<string name="type_a_message">Schreibe eine Nachricht…</string>
|
||||||
<string name="message_not_sent">Nachricht wurde nicht gesendet.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Person hinzufügen</string>
|
<string name="add_person">Person hinzufügen</string>
|
||||||
<string name="attachment">Anhang</string>
|
<string name="attachment">Anhang</string>
|
||||||
<string name="no_conversations_found">Keine gespeicherten Chats gefunden</string>
|
<string name="no_conversations_found">Keine gespeicherten Chats gefunden</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Απλός SMS Messenger</string>
|
<string name="app_name">Απλός SMS Messenger</string>
|
||||||
<string name="app_launcher_name">SMS Messenger</string>
|
<string name="app_launcher_name">SMS Messenger</string>
|
||||||
<string name="type_a_message">Πληκτρολογήστε ένα μήνυμα…</string>
|
<string name="type_a_message">Πληκτρολογήστε ένα μήνυμα…</string>
|
||||||
<string name="message_not_sent">Το μήνυμα δεν έχει σταλεί.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Προσθήκη ατόμου</string>
|
<string name="add_person">Προσθήκη ατόμου</string>
|
||||||
<string name="attachment">Συνημμένο</string>
|
<string name="attachment">Συνημμένο</string>
|
||||||
<string name="no_conversations_found">Δεν βρέθηκαν αποθηκευμένες συνομιλίες</string>
|
<string name="no_conversations_found">Δεν βρέθηκαν αποθηκευμένες συνομιλίες</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Mensajería SMS Simple</string>
|
<string name="app_name">Mensajería SMS Simple</string>
|
||||||
<string name="app_launcher_name">Mensajería SMS</string>
|
<string name="app_launcher_name">Mensajería SMS</string>
|
||||||
<string name="type_a_message">Escribe un mensaje…</string>
|
<string name="type_a_message">Escribe un mensaje…</string>
|
||||||
<string name="message_not_sent">El mensaje no se ha enviado.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Añadir persona</string>
|
<string name="add_person">Añadir persona</string>
|
||||||
<string name="attachment">Archivo adjunto</string>
|
<string name="attachment">Archivo adjunto</string>
|
||||||
<string name="no_conversations_found">No se han encontrado conversaciones</string>
|
<string name="no_conversations_found">No se han encontrado conversaciones</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Simple SMS Messenger</string>
|
<string name="app_name">Simple SMS Messenger</string>
|
||||||
<string name="app_launcher_name">SMS Messenger</string>
|
<string name="app_launcher_name">SMS Messenger</string>
|
||||||
<string name="type_a_message">Écrivez un message…</string>
|
<string name="type_a_message">Écrivez un message…</string>
|
||||||
<string name="message_not_sent">Le message n\'a pas été envoyé.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Ajouter une personne</string>
|
<string name="add_person">Ajouter une personne</string>
|
||||||
<string name="attachment">Pièce jointe</string>
|
<string name="attachment">Pièce jointe</string>
|
||||||
<string name="no_conversations_found">Aucune conversation enregistrée n\'a été trouvée</string>
|
<string name="no_conversations_found">Aucune conversation enregistrée n\'a été trouvée</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Simple SMS Messenger</string>
|
<string name="app_name">Simple SMS Messenger</string>
|
||||||
<string name="app_launcher_name">SMS Messenger</string>
|
<string name="app_launcher_name">SMS Messenger</string>
|
||||||
<string name="type_a_message">Ketik pesan…</string>
|
<string name="type_a_message">Ketik pesan…</string>
|
||||||
<string name="message_not_sent">Pesan belum terkirim.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Tambahkan Orang</string>
|
<string name="add_person">Tambahkan Orang</string>
|
||||||
<string name="attachment">Lampiran</string>
|
<string name="attachment">Lampiran</string>
|
||||||
<string name="no_conversations_found">Tidak ada percakapan tersimpan yang ditemukan</string>
|
<string name="no_conversations_found">Tidak ada percakapan tersimpan yang ditemukan</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Simple ショートメール</string>
|
<string name="app_name">Simple ショートメール</string>
|
||||||
<string name="app_launcher_name">ショートメール</string>
|
<string name="app_launcher_name">ショートメール</string>
|
||||||
<string name="type_a_message">メッセージを入力してください…</string>
|
<string name="type_a_message">メッセージを入力してください…</string>
|
||||||
<string name="message_not_sent">送信されませんでした。</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">宛先を追加</string>
|
<string name="add_person">宛先を追加</string>
|
||||||
<string name="attachment">添付</string>
|
<string name="attachment">添付</string>
|
||||||
<string name="no_conversations_found">保存された会話はありません</string>
|
<string name="no_conversations_found">保存された会話はありません</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Paprastas SMS Siuntiklis</string>
|
<string name="app_name">Paprastas SMS Siuntiklis</string>
|
||||||
<string name="app_launcher_name">SMS Siuntiklis</string>
|
<string name="app_launcher_name">SMS Siuntiklis</string>
|
||||||
<string name="type_a_message">Rašykite žinutę…</string>
|
<string name="type_a_message">Rašykite žinutę…</string>
|
||||||
<string name="message_not_sent">Žinutė neišsiųsta.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Pridėti žmogų</string>
|
<string name="add_person">Pridėti žmogų</string>
|
||||||
<string name="attachment">Priedas</string>
|
<string name="attachment">Priedas</string>
|
||||||
<string name="no_conversations_found">Nebuvo rasta išsaugotų pokalbių</string>
|
<string name="no_conversations_found">Nebuvo rasta išsaugotų pokalbių</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Simple SMS Messenger</string>
|
<string name="app_name">Simple SMS Messenger</string>
|
||||||
<string name="app_launcher_name">SMS മെസഞ്ചർ</string>
|
<string name="app_launcher_name">SMS മെസഞ്ചർ</string>
|
||||||
<string name="type_a_message">മെസ്സേജ് ടൈപ്പ് ചെയ്യുക</string>
|
<string name="type_a_message">മെസ്സേജ് ടൈപ്പ് ചെയ്യുക</string>
|
||||||
<string name="message_not_sent">മെസ്സേജ് അയച്ചിട്ടില്ല.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">വ്യക്തിയെ ചേർക്കുക</string>
|
<string name="add_person">വ്യക്തിയെ ചേർക്കുക</string>
|
||||||
<string name="attachment">അറ്റാച്ചുമെന്റ്</string>
|
<string name="attachment">അറ്റാച്ചുമെന്റ്</string>
|
||||||
<string name="no_conversations_found">സ്റ്റോർ ചെയ്ത സംഭാഷണങ്ങളൊന്നും കണ്ടെത്തിയില്ല</string>
|
<string name="no_conversations_found">സ്റ്റോർ ചെയ്ത സംഭാഷണങ്ങളൊന്നും കണ്ടെത്തിയില്ല</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Eenvoudig Berichtenbeheer (SMS)</string>
|
<string name="app_name">Eenvoudig Berichtenbeheer (SMS)</string>
|
||||||
<string name="app_launcher_name">Berichten</string>
|
<string name="app_launcher_name">Berichten</string>
|
||||||
<string name="type_a_message">Typ een bericht…</string>
|
<string name="type_a_message">Typ een bericht…</string>
|
||||||
<string name="message_not_sent">Bericht niet verzonden.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Persoon toevoegen</string>
|
<string name="add_person">Persoon toevoegen</string>
|
||||||
<string name="attachment">Bijlage</string>
|
<string name="attachment">Bijlage</string>
|
||||||
<string name="no_conversations_found">Geen opgeslagen berichten gevonden</string>
|
<string name="no_conversations_found">Geen opgeslagen berichten gevonden</string>
|
||||||
@@ -10,9 +12,9 @@
|
|||||||
<string name="reply">Beantwoorden</string>
|
<string name="reply">Beantwoorden</string>
|
||||||
<string name="show_character_counter">Teller voor het aantal tekens weergeven</string>
|
<string name="show_character_counter">Teller voor het aantal tekens weergeven</string>
|
||||||
<string name="loading_messages">Berichten laden…</string>
|
<string name="loading_messages">Berichten laden…</string>
|
||||||
<string name="no_reply_support">Sender doesn\'t support replies</string>
|
<string name="no_reply_support">Afzender ondersteunt geen antwoorden</string>
|
||||||
<string name="draft">Draft</string>
|
<string name="draft">Concept</string>
|
||||||
<string name="sending">Sending…</string>
|
<string name="sending">Versturen…</string>
|
||||||
|
|
||||||
<!-- New conversation -->
|
<!-- New conversation -->
|
||||||
<string name="new_conversation">Nieuw gesprek</string>
|
<string name="new_conversation">Nieuw gesprek</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Simple SMS Messenger</string>
|
<string name="app_name">Simple SMS Messenger</string>
|
||||||
<string name="app_launcher_name">SMS Messenger</string>
|
<string name="app_launcher_name">SMS Messenger</string>
|
||||||
<string name="type_a_message">Escrever uma mensagem…</string>
|
<string name="type_a_message">Escrever uma mensagem…</string>
|
||||||
<string name="message_not_sent">Mensagem não enviada</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Adicionar pessoa</string>
|
<string name="add_person">Adicionar pessoa</string>
|
||||||
<string name="attachment">Anexo</string>
|
<string name="attachment">Anexo</string>
|
||||||
<string name="no_conversations_found">Não foram encontradas conversas</string>
|
<string name="no_conversations_found">Não foram encontradas conversas</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Simple SMS Messenger</string>
|
<string name="app_name">Simple SMS Messenger</string>
|
||||||
<string name="app_launcher_name">Сообщения</string>
|
<string name="app_launcher_name">Сообщения</string>
|
||||||
<string name="type_a_message">Введите сообщение…</string>
|
<string name="type_a_message">Введите сообщение…</string>
|
||||||
<string name="message_not_sent">Сообщение не отправлено.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Добавить участника</string>
|
<string name="add_person">Добавить участника</string>
|
||||||
<string name="attachment">Вложение</string>
|
<string name="attachment">Вложение</string>
|
||||||
<string name="no_conversations_found">Нет сохранённых переписок</string>
|
<string name="no_conversations_found">Нет сохранённых переписок</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Jednoduché SMS správy</string>
|
<string name="app_name">Jednoduché SMS správy</string>
|
||||||
<string name="app_launcher_name">SMS správy</string>
|
<string name="app_launcher_name">SMS správy</string>
|
||||||
<string name="type_a_message">Zadajte správu…</string>
|
<string name="type_a_message">Zadajte správu…</string>
|
||||||
<string name="message_not_sent">Správa nebola odoslaná.</string>
|
<string name="message_not_sent_short">Správa nebola odoslaná</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Správa neodoslaná. Dotykom to skúste znova.</string>
|
||||||
|
<string name="message_sending_error">Vaša správa pre \'%s\' nebola odoslaná</string>
|
||||||
<string name="add_person">Pridať osobu</string>
|
<string name="add_person">Pridať osobu</string>
|
||||||
<string name="attachment">Príloha</string>
|
<string name="attachment">Príloha</string>
|
||||||
<string name="no_conversations_found">Nenašli sa žiadne uložené konverzácie</string>
|
<string name="no_conversations_found">Nenašli sa žiadne uložené konverzácie</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Basit SMS Messenger</string>
|
<string name="app_name">Basit SMS Messenger</string>
|
||||||
<string name="app_launcher_name">SMS Messenger</string>
|
<string name="app_launcher_name">SMS Messenger</string>
|
||||||
<string name="type_a_message">Bir mesaj yazın…</string>
|
<string name="type_a_message">Bir mesaj yazın…</string>
|
||||||
<string name="message_not_sent">Mesaj gönderilmedi.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Kişi Ekle</string>
|
<string name="add_person">Kişi Ekle</string>
|
||||||
<string name="attachment">Ek</string>
|
<string name="attachment">Ek</string>
|
||||||
<string name="no_conversations_found">Kaydedilmiş görüşme bulunamadı</string>
|
<string name="no_conversations_found">Kaydedilmiş görüşme bulunamadı</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Simple SMS Messenger</string>
|
<string name="app_name">Simple SMS Messenger</string>
|
||||||
<string name="app_launcher_name">Повідомлення</string>
|
<string name="app_launcher_name">Повідомлення</string>
|
||||||
<string name="type_a_message">Введіть повідомлення…</string>
|
<string name="type_a_message">Введіть повідомлення…</string>
|
||||||
<string name="message_not_sent">Повідомлення не надіслано. </string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Додати учасник а</string>
|
<string name="add_person">Додати учасник а</string>
|
||||||
<string name="attachment">Вкладення</string>
|
<string name="attachment">Вкладення</string>
|
||||||
<string name="no_conversations_found">Немає збережених листувань</string>
|
<string name="no_conversations_found">Немає збережених листувань</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">简易短信</string>
|
<string name="app_name">简易短信</string>
|
||||||
<string name="app_launcher_name">短信</string>
|
<string name="app_launcher_name">短信</string>
|
||||||
<string name="type_a_message">输入一个消息…</string>
|
<string name="type_a_message">输入一个消息…</string>
|
||||||
<string name="message_not_sent">消息尚未发送。</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">添加人</string>
|
<string name="add_person">添加人</string>
|
||||||
<string name="attachment">附件</string>
|
<string name="attachment">附件</string>
|
||||||
<string name="no_conversations_found">未找到保存的对话</string>
|
<string name="no_conversations_found">未找到保存的对话</string>
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<string name="app_name">Simple SMS Messenger</string>
|
<string name="app_name">Simple SMS Messenger</string>
|
||||||
<string name="app_launcher_name">SMS Messenger</string>
|
<string name="app_launcher_name">SMS Messenger</string>
|
||||||
<string name="type_a_message">Type a message…</string>
|
<string name="type_a_message">Type a message…</string>
|
||||||
<string name="message_not_sent">Message has not been sent.</string>
|
<string name="message_not_sent_short">Message not sent</string>
|
||||||
|
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
|
||||||
|
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
|
||||||
<string name="add_person">Add Person</string>
|
<string name="add_person">Add Person</string>
|
||||||
<string name="attachment">Attachment</string>
|
<string name="attachment">Attachment</string>
|
||||||
<string name="no_conversations_found">No stored conversations have been found</string>
|
<string name="no_conversations_found">No stored conversations have been found</string>
|
||||||
|
4
fastlane/metadata/android/en-US/changelogs/25.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/25.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
* Improved delivery reports, show a notification at failed messages
|
||||||
|
* Allow resending failed messages with tapping them
|
||||||
|
* Added multiple dual-SIM related improvements
|
||||||
|
* Many other UX, stability, performance and translation improvements
|
Reference in New Issue
Block a user