mirror of
https://github.com/SimpleMobileTools/Simple-SMS-Messenger.git
synced 2025-02-01 01:46:46 +01:00
Merge branch 'master' of https://github.com/SimpleMobileTools/Simple-SMS-Messenger
# Conflicts: # gradle/wrapper/gradle-wrapper.properties
This commit is contained in:
commit
8e9158c09b
24
CHANGELOG.md
24
CHANGELOG.md
@ -1,6 +1,30 @@
|
||||
Changelog
|
||||
==========
|
||||
|
||||
Version 5.9.4 *(2021-05-23)*
|
||||
----------------------------
|
||||
|
||||
* Adding some UX, stability and translation improvements
|
||||
|
||||
Version 5.9.3 *(2021-04-15)*
|
||||
----------------------------
|
||||
|
||||
* Fixed a glitch with current conversation not being updated correctly at incoming messages
|
||||
* Couple other stability, translation and bugfixes
|
||||
|
||||
Version 5.9.2 *(2021-03-22)*
|
||||
----------------------------
|
||||
|
||||
* Fixed an error message wrongly popping up in some cases
|
||||
* Some stabiliy and translation improvements
|
||||
|
||||
Version 5.9.1 *(2021-03-15)*
|
||||
----------------------------
|
||||
|
||||
* Improved search
|
||||
* Properly handle sending messages from notification Reply action
|
||||
* Some design, stability and translation improvements
|
||||
|
||||
Version 5.9.0 *(2021-02-16)*
|
||||
----------------------------
|
||||
|
||||
|
@ -16,8 +16,8 @@ android {
|
||||
applicationId "com.simplemobiletools.smsmessenger"
|
||||
minSdkVersion 22
|
||||
targetSdkVersion 30
|
||||
versionCode 29
|
||||
versionName "5.9.0"
|
||||
versionCode 34
|
||||
versionName "5.9.4"
|
||||
setProperty("archivesBaseName", "sms-messenger")
|
||||
}
|
||||
|
||||
@ -56,14 +56,14 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.simplemobiletools:commons:5.33.32'
|
||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:25daba7267'
|
||||
implementation 'org.greenrobot:eventbus:3.2.0'
|
||||
implementation 'com.klinkerapps:android-smsmms:5.2.6'
|
||||
implementation 'com.github.tibbi:IndicatorFastScroll:c3de1d040a'
|
||||
implementation "me.leolin:ShortcutBadger:1.1.22"
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
|
||||
kapt "androidx.room:room-compiler:2.2.6"
|
||||
implementation "androidx.room:room-runtime:2.2.6"
|
||||
annotationProcessor "androidx.room:room-compiler:2.2.6"
|
||||
kapt "androidx.room:room-compiler:2.3.0"
|
||||
implementation "androidx.room:room-runtime:2.3.0"
|
||||
annotationProcessor "androidx.room:room-compiler:2.3.0"
|
||||
}
|
||||
|
@ -18,6 +18,11 @@
|
||||
android:name="android.permission.USE_FINGERPRINT"
|
||||
tools:node="remove" />
|
||||
|
||||
<queries>
|
||||
<package android:name="com.simplemobiletools.contacts.pro.debug" />
|
||||
<package android:name="com.simplemobiletools.contacts.pro" />
|
||||
</queries>
|
||||
|
||||
<uses-feature android:name="android.hardware.telephony" />
|
||||
|
||||
<application
|
||||
|
@ -184,7 +184,7 @@ class MainActivity : SimpleActivity() {
|
||||
}
|
||||
|
||||
private fun getNewConversations(cachedConversations: ArrayList<Conversation>) {
|
||||
val privateCursor = getMyContactsCursor()?.loadInBackground()
|
||||
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
|
||||
ensureBackgroundThread {
|
||||
val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
||||
val conversations = getConversations(privateContacts = privateContacts)
|
||||
@ -247,6 +247,7 @@ class MainActivity : SimpleActivity() {
|
||||
conversations_list.adapter = this
|
||||
}
|
||||
|
||||
conversations_list.scheduleLayoutAnimation()
|
||||
conversations_fastscroller.setViews(conversations_list) {
|
||||
val listItem = (conversations_list.adapter as? ConversationsAdapter)?.conversations?.getOrNull(it)
|
||||
conversations_fastscroller.updateBubbleText(listItem?.title ?: "")
|
||||
|
@ -64,7 +64,10 @@ class NewConversationActivity : SimpleActivity() {
|
||||
val searchString = it
|
||||
val filteredContacts = ArrayList<SimpleContact>()
|
||||
allContacts.forEach {
|
||||
if (it.phoneNumbers.any { it.contains(searchString, true) } || it.name.contains(searchString, true)) {
|
||||
if (it.phoneNumbers.any { it.contains(searchString, true) } ||
|
||||
it.name.contains(searchString, true) ||
|
||||
it.name.contains(searchString.normalizeString(), true) ||
|
||||
it.name.normalizeString().contains(searchString, true)) {
|
||||
filteredContacts.add(it)
|
||||
}
|
||||
}
|
||||
@ -135,31 +138,38 @@ class NewConversationActivity : SimpleActivity() {
|
||||
no_contacts_placeholder.text = getString(placeholderText)
|
||||
}
|
||||
|
||||
ContactsAdapter(this, contacts, contacts_list, null) {
|
||||
hideKeyboard()
|
||||
val contact = it as SimpleContact
|
||||
val phoneNumbers = contact.phoneNumbers
|
||||
if (phoneNumbers.size > 1) {
|
||||
val items = ArrayList<RadioItem>()
|
||||
phoneNumbers.forEachIndexed { index, phoneNumber ->
|
||||
items.add(RadioItem(index, phoneNumber, phoneNumber))
|
||||
}
|
||||
val currAdapter = contacts_list.adapter
|
||||
if (currAdapter == null) {
|
||||
ContactsAdapter(this, contacts, contacts_list, null) {
|
||||
hideKeyboard()
|
||||
val contact = it as SimpleContact
|
||||
val phoneNumbers = contact.phoneNumbers
|
||||
if (phoneNumbers.size > 1) {
|
||||
val items = ArrayList<RadioItem>()
|
||||
phoneNumbers.forEachIndexed { index, phoneNumber ->
|
||||
items.add(RadioItem(index, phoneNumber, phoneNumber))
|
||||
}
|
||||
|
||||
RadioGroupDialog(this, items) {
|
||||
launchThreadActivity(it as String, contact.name)
|
||||
RadioGroupDialog(this, items) {
|
||||
launchThreadActivity(it as String, contact.name)
|
||||
}
|
||||
} else {
|
||||
launchThreadActivity(phoneNumbers.first(), contact.name)
|
||||
}
|
||||
} else {
|
||||
launchThreadActivity(phoneNumbers.first(), contact.name)
|
||||
}.apply {
|
||||
contacts_list.adapter = this
|
||||
}
|
||||
}.apply {
|
||||
contacts_list.adapter = this
|
||||
|
||||
contacts_list.scheduleLayoutAnimation()
|
||||
} else {
|
||||
(currAdapter as ContactsAdapter).updateContacts(contacts)
|
||||
}
|
||||
|
||||
setupLetterFastscroller(contacts)
|
||||
}
|
||||
|
||||
private fun fillSuggestedContacts(callback: () -> Unit) {
|
||||
val privateCursor = getMyContactsCursor()?.loadInBackground()
|
||||
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
|
||||
ensureBackgroundThread {
|
||||
privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
||||
val suggestions = getSuggestedContacts(privateContacts)
|
||||
|
@ -156,7 +156,12 @@ class ThreadActivity : SimpleActivity() {
|
||||
|
||||
private fun setupCachedMessages(callback: () -> Unit) {
|
||||
ensureBackgroundThread {
|
||||
messages = messagesDB.getThreadMessages(threadId).toMutableList() as ArrayList<Message>
|
||||
messages = try {
|
||||
messagesDB.getThreadMessages(threadId).toMutableList() as ArrayList<Message>
|
||||
} catch (e: Exception) {
|
||||
ArrayList()
|
||||
}
|
||||
|
||||
setupParticipants()
|
||||
setupAdapter()
|
||||
|
||||
@ -174,12 +179,20 @@ class ThreadActivity : SimpleActivity() {
|
||||
}
|
||||
|
||||
private fun setupThread() {
|
||||
val privateCursor = getMyContactsCursor()?.loadInBackground()
|
||||
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
|
||||
ensureBackgroundThread {
|
||||
val cachedMessagesCode = messages.hashCode()
|
||||
val cachedMessagesCode = messages.clone().hashCode()
|
||||
messages = getMessages(threadId)
|
||||
if (messages.hashCode() == cachedMessagesCode && participants.isNotEmpty()) {
|
||||
return@ensureBackgroundThread
|
||||
|
||||
val hasParticipantWithoutName = participants.any {
|
||||
it.phoneNumbers.contains(it.name)
|
||||
}
|
||||
|
||||
try {
|
||||
if (participants.isNotEmpty() && messages.hashCode() == cachedMessagesCode && !hasParticipantWithoutName) {
|
||||
return@ensureBackgroundThread
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
|
||||
setupParticipants()
|
||||
@ -533,7 +546,7 @@ class ThreadActivity : SimpleActivity() {
|
||||
var hadUnreadItems = false
|
||||
val cnt = messages.size
|
||||
for (i in 0 until cnt) {
|
||||
val message = messages[i]
|
||||
val message = messages.getOrNull(i) ?: continue
|
||||
// do not show the date/time above every message, only if the difference between the 2 messages is at least MIN_DATE_TIME_DIFF_SECS
|
||||
if (message.date - prevDateTime > MIN_DATE_TIME_DIFF_SECS) {
|
||||
val simCardID = subscriptionIdToSimId[message.subscriptionId] ?: "?"
|
||||
|
@ -20,14 +20,14 @@ class AutoCompleteTextViewAdapter(val activity: SimpleActivity, val contacts: Ar
|
||||
var resultList = ArrayList<SimpleContact>()
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
val contact = resultList[position]
|
||||
val contact = resultList.getOrNull(position)
|
||||
var listItem = convertView
|
||||
if (listItem == null || listItem.tag != contact.name.isNotEmpty()) {
|
||||
if (listItem == null || listItem.tag != contact?.name?.isNotEmpty()) {
|
||||
listItem = LayoutInflater.from(activity).inflate(R.layout.item_contact_with_number, parent, false)
|
||||
}
|
||||
|
||||
listItem!!.apply {
|
||||
tag = contact.name.isNotEmpty()
|
||||
tag = contact?.name?.isNotEmpty()
|
||||
// clickable and focusable properties seem to break Autocomplete clicking, so remove them
|
||||
findViewById<View>(R.id.item_contact_frame).apply {
|
||||
isClickable = false
|
||||
@ -35,14 +35,16 @@ class AutoCompleteTextViewAdapter(val activity: SimpleActivity, val contacts: Ar
|
||||
}
|
||||
|
||||
val backgroundColor = activity.config.backgroundColor
|
||||
findViewById<TextView>(R.id.item_contact_name).text = contact.name
|
||||
findViewById<TextView>(R.id.item_contact_number).text = contact.phoneNumbers.first()
|
||||
findViewById<RelativeLayout>(R.id.item_contact_holder).setBackgroundColor(backgroundColor.darkenColor())
|
||||
|
||||
findViewById<TextView>(R.id.item_contact_name).setTextColor(backgroundColor.getContrastColor())
|
||||
findViewById<TextView>(R.id.item_contact_number).setTextColor(backgroundColor.getContrastColor())
|
||||
|
||||
SimpleContactsHelper(context).loadContactImage(contact.photoUri, findViewById(R.id.item_contact_image), contact.name)
|
||||
if (contact != null) {
|
||||
findViewById<TextView>(R.id.item_contact_name).text = contact.name
|
||||
findViewById<TextView>(R.id.item_contact_number).text = contact.phoneNumbers.first()
|
||||
SimpleContactsHelper(context).loadContactImage(contact.photoUri, findViewById(R.id.item_contact_image), contact.name)
|
||||
}
|
||||
}
|
||||
|
||||
return listItem
|
||||
|
@ -17,8 +17,10 @@ import com.simplemobiletools.smsmessenger.R
|
||||
import com.simplemobiletools.smsmessenger.activities.SimpleActivity
|
||||
import java.util.*
|
||||
|
||||
class ContactsAdapter(activity: SimpleActivity, var contacts: ArrayList<SimpleContact>, recyclerView: MyRecyclerView, fastScroller: FastScroller?,
|
||||
itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
||||
class ContactsAdapter(
|
||||
activity: SimpleActivity, var contacts: ArrayList<SimpleContact>, recyclerView: MyRecyclerView, fastScroller: FastScroller?,
|
||||
itemClick: (Any) -> Unit
|
||||
) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
||||
private var fontSize = activity.getTextSize()
|
||||
|
||||
override fun getActionMenuId() = 0
|
||||
@ -51,10 +53,12 @@ class ContactsAdapter(activity: SimpleActivity, var contacts: ArrayList<SimpleCo
|
||||
|
||||
override fun getItemCount() = contacts.size
|
||||
|
||||
override fun onViewRecycled(holder: ViewHolder) {
|
||||
super.onViewRecycled(holder)
|
||||
if (!activity.isDestroyed && !activity.isFinishing) {
|
||||
Glide.with(activity).clear(holder.itemView.findViewById<ImageView>(R.id.item_contact_image))
|
||||
fun updateContacts(newContacts: ArrayList<SimpleContact>) {
|
||||
val oldHashCode = contacts.hashCode()
|
||||
val newHashCode = newContacts.hashCode()
|
||||
if (newHashCode != oldHashCode) {
|
||||
contacts = newContacts
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,4 +79,11 @@ class ContactsAdapter(activity: SimpleActivity, var contacts: ArrayList<SimpleCo
|
||||
SimpleContactsHelper(context).loadContactImage(contact.photoUri, findViewById(R.id.item_contact_image), contact.name)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewRecycled(holder: ViewHolder) {
|
||||
super.onViewRecycled(holder)
|
||||
if (!activity.isDestroyed && !activity.isFinishing) {
|
||||
Glide.with(activity).clear(holder.itemView.findViewById<ImageView>(R.id.item_contact_image))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.simplemobiletools.smsmessenger.adapters
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
@ -26,8 +27,10 @@ import com.simplemobiletools.smsmessenger.helpers.refreshMessages
|
||||
import com.simplemobiletools.smsmessenger.models.Conversation
|
||||
import kotlinx.android.synthetic.main.item_conversation.view.*
|
||||
|
||||
class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayList<Conversation>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
|
||||
itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
||||
class ConversationsAdapter(
|
||||
activity: SimpleActivity, var conversations: ArrayList<Conversation>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
|
||||
itemClick: (Any) -> Unit
|
||||
) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
||||
private var fontSize = activity.getTextSize()
|
||||
|
||||
init {
|
||||
@ -120,11 +123,13 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis
|
||||
Intent(Intent.ACTION_DIAL).apply {
|
||||
data = Uri.fromParts("tel", conversation.phoneNumber, null)
|
||||
|
||||
if (resolveActivity(activity.packageManager) != null) {
|
||||
try {
|
||||
activity.startActivity(this)
|
||||
finishActMode()
|
||||
} else {
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
activity.toast(R.string.no_app_found)
|
||||
} catch (e: Exception) {
|
||||
activity.showErrorToast(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,12 +190,7 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis
|
||||
action = Intent.ACTION_INSERT_OR_EDIT
|
||||
type = "vnd.android.cursor.item/contact"
|
||||
putExtra(KEY_PHONE, conversation.phoneNumber)
|
||||
|
||||
if (resolveActivity(activity.packageManager) != null) {
|
||||
activity.startActivity(this)
|
||||
} else {
|
||||
activity.toast(R.string.no_app_found)
|
||||
}
|
||||
activity.launchActivityIntent(this)
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,10 +209,11 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis
|
||||
}
|
||||
|
||||
fun updateConversations(newConversations: ArrayList<Conversation>) {
|
||||
val latestConversations = newConversations.clone() as ArrayList<Conversation>
|
||||
val oldHashCode = conversations.hashCode()
|
||||
val newHashCode = newConversations.hashCode()
|
||||
val newHashCode = latestConversations.hashCode()
|
||||
if (newHashCode != oldHashCode) {
|
||||
conversations = newConversations
|
||||
conversations = latestConversations
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.simplemobiletools.smsmessenger.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
@ -200,10 +201,11 @@ class ThreadAdapter(
|
||||
private fun isThreadDateTime(position: Int) = messages.getOrNull(position) is ThreadDateTime
|
||||
|
||||
fun updateMessages(newMessages: ArrayList<ThreadItem>) {
|
||||
val latestMessages = newMessages.clone() as ArrayList<ThreadItem>
|
||||
val oldHashCode = messages.hashCode()
|
||||
val newHashCode = newMessages.hashCode()
|
||||
val newHashCode = latestMessages.hashCode()
|
||||
if (newHashCode != oldHashCode) {
|
||||
messages = newMessages
|
||||
messages = latestMessages
|
||||
notifyDataSetChanged()
|
||||
recyclerView.scrollToPosition(messages.size - 1)
|
||||
}
|
||||
@ -315,15 +317,17 @@ class ThreadAdapter(
|
||||
setDataAndType(uri, mimetype)
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
|
||||
if (resolveActivity(activity.packageManager) != null) {
|
||||
try {
|
||||
activity.startActivity(this)
|
||||
} else {
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
val newMimetype = filename.getMimeType()
|
||||
if (newMimetype.isNotEmpty() && mimetype != newMimetype) {
|
||||
launchViewIntent(uri, newMimetype, filename)
|
||||
} else {
|
||||
activity.toast(R.string.no_app_found)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
activity.showErrorToast(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -488,7 +488,6 @@ fun Context.getNameAndPhotoFromPhoneNumber(number: String): NamePhoto {
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
}
|
||||
|
||||
return NamePhoto(number, null)
|
||||
@ -507,8 +506,12 @@ fun Context.insertNewSMS(address: String, subject: String, body: String, date: L
|
||||
put(Sms.SUBSCRIPTION_ID, subscriptionId)
|
||||
}
|
||||
|
||||
val newUri = contentResolver.insert(uri, contentValues)
|
||||
return newUri?.lastPathSegment?.toLong() ?: 0L
|
||||
return try {
|
||||
val newUri = contentResolver.insert(uri, contentValues)
|
||||
newUri?.lastPathSegment?.toLong() ?: 0L
|
||||
} catch (e: Exception) {
|
||||
0L
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.deleteConversation(threadId: Long) {
|
||||
@ -633,7 +636,7 @@ fun Context.getThreadId(addresses: Set<String>): Long {
|
||||
}
|
||||
|
||||
fun Context.showReceivedMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?) {
|
||||
val privateCursor = getMyContactsCursor()?.loadInBackground()
|
||||
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
|
||||
ensureBackgroundThread {
|
||||
val senderName = getNameFromAddress(address, privateCursor)
|
||||
|
||||
|
@ -3,17 +3,14 @@ package com.simplemobiletools.smsmessenger.receivers
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.RemoteInput
|
||||
import com.klinker.android.send_message.Settings
|
||||
import com.klinker.android.send_message.Transaction
|
||||
import com.simplemobiletools.commons.extensions.notificationManager
|
||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.smsmessenger.R
|
||||
import com.simplemobiletools.smsmessenger.extensions.conversationsDB
|
||||
import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead
|
||||
import com.simplemobiletools.smsmessenger.helpers.NOTIFICATION_CHANNEL
|
||||
import com.simplemobiletools.smsmessenger.helpers.REPLY
|
||||
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
|
||||
import com.simplemobiletools.smsmessenger.helpers.THREAD_NUMBER
|
||||
@ -22,26 +19,28 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val address = intent.getStringExtra(THREAD_NUMBER)
|
||||
val threadId = intent.getLongExtra(THREAD_ID, 0L)
|
||||
val msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY).toString()
|
||||
val msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY)?.toString() ?: return
|
||||
|
||||
val settings = Settings()
|
||||
settings.useSystemSending = true
|
||||
settings.deliveryReports = true
|
||||
|
||||
val transaction = Transaction(context, settings)
|
||||
val message = com.klinker.android.send_message.Message(msg, address)
|
||||
|
||||
try {
|
||||
val smsSentIntent = Intent(context, SmsStatusSentReceiver::class.java)
|
||||
val deliveredIntent = Intent(context, SmsStatusDeliveredReceiver::class.java)
|
||||
|
||||
transaction.setExplicitBroadcastForSentSms(smsSentIntent)
|
||||
transaction.setExplicitBroadcastForDeliveredSms(deliveredIntent)
|
||||
|
||||
transaction.sendNewMessage(message, threadId)
|
||||
} catch (e: Exception) {
|
||||
context.showErrorToast(e)
|
||||
}
|
||||
|
||||
val repliedNotification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
|
||||
.setSmallIcon(R.drawable.ic_messenger)
|
||||
.setContentText(msg)
|
||||
.build()
|
||||
|
||||
context.notificationManager.notify(threadId.hashCode(), repliedNotification)
|
||||
context.notificationManager.cancel(threadId.hashCode())
|
||||
|
||||
ensureBackgroundThread {
|
||||
context.markThreadMessagesRead(threadId)
|
||||
|
@ -40,17 +40,21 @@ class SmsReceiver : BroadcastReceiver() {
|
||||
val newMessageId = context.insertNewSMS(address, subject, body, date, read, threadId, type, subscriptionId)
|
||||
|
||||
val conversation = context.getConversations(threadId).firstOrNull() ?: return@ensureBackgroundThread
|
||||
context.conversationsDB.insertOrUpdate(conversation)
|
||||
context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations())
|
||||
try {
|
||||
context.conversationsDB.insertOrUpdate(conversation)
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
|
||||
context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations())
|
||||
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 participants = arrayListOf(participant)
|
||||
val messageDate = (date / 1000).toInt()
|
||||
val message = Message(newMessageId, body, type, participants, messageDate, false, threadId, false, null, address, "", subscriptionId)
|
||||
context.messagesDB.insertOrUpdate(message)
|
||||
refreshMessages()
|
||||
}
|
||||
|
||||
context.showReceivedMessageNotification(address, body, threadId, null)
|
||||
refreshMessages()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ class SmsStatusSentReceiver : SentReceiver() {
|
||||
} else {
|
||||
Telephony.Sms.MESSAGE_TYPE_OUTBOX
|
||||
}
|
||||
|
||||
context.updateMessageType(messageId, type)
|
||||
context.messagesDB.updateType(messageId, type)
|
||||
refreshMessages()
|
||||
@ -50,7 +51,7 @@ class SmsStatusSentReceiver : SentReceiver() {
|
||||
|
||||
private fun showSendingFailedNotification(context: Context, messageId: Long) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
val privateCursor = context.getMyContactsCursor()?.loadInBackground()
|
||||
val privateCursor = context.getMyContactsCursor(false, true)?.loadInBackground()
|
||||
ensureBackgroundThread {
|
||||
val address = context.getMessageRecipientAddress(messageId)
|
||||
val threadId = context.getThreadId(address)
|
||||
|
@ -6,6 +6,8 @@ import android.net.Uri
|
||||
import com.klinker.android.send_message.Settings
|
||||
import com.klinker.android.send_message.Transaction
|
||||
import com.simplemobiletools.smsmessenger.extensions.getThreadId
|
||||
import com.simplemobiletools.smsmessenger.receivers.SmsStatusDeliveredReceiver
|
||||
import com.simplemobiletools.smsmessenger.receivers.SmsStatusSentReceiver
|
||||
|
||||
class HeadlessSmsSendService : Service() {
|
||||
override fun onBind(intent: Intent?) = null
|
||||
@ -20,8 +22,17 @@ class HeadlessSmsSendService : Service() {
|
||||
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||
val settings = Settings()
|
||||
settings.useSystemSending = true
|
||||
settings.deliveryReports = true
|
||||
|
||||
val transaction = Transaction(this, settings)
|
||||
val message = com.klinker.android.send_message.Message(text, number)
|
||||
|
||||
val smsSentIntent = Intent(this, SmsStatusSentReceiver::class.java)
|
||||
val deliveredIntent = Intent(this, SmsStatusDeliveredReceiver::class.java)
|
||||
|
||||
transaction.setExplicitBroadcastForSentSms(smsSentIntent)
|
||||
transaction.setExplicitBroadcastForDeliveredSms(deliveredIntent)
|
||||
|
||||
transaction.sendNewMessage(message, getThreadId(number))
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:layoutAnimation="@anim/layout_animation"
|
||||
android:overScrollMode="ifContentScrolls"
|
||||
android:scrollbars="none"
|
||||
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
||||
|
@ -101,6 +101,7 @@
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/suggestions_scrollview"
|
||||
android:clipToPadding="false"
|
||||
android:layoutAnimation="@anim/layout_animation"
|
||||
android:overScrollMode="ifContentScrolls"
|
||||
android:scrollbars="none"
|
||||
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
||||
|
@ -5,21 +5,21 @@
|
||||
android:id="@+id/cab_delete"
|
||||
android:icon="@drawable/ic_delete_vector"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="ifRoom" />
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/cab_add_number_to_contact"
|
||||
android:icon="@drawable/ic_add_person_vector"
|
||||
android:title="@string/add_number_to_contact"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/cab_block_number"
|
||||
android:icon="@drawable/ic_minus_circle_vector"
|
||||
android:title="@string/block_number"
|
||||
app:showAsAction="ifRoom" />
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/cab_dial_number"
|
||||
android:icon="@drawable/ic_phone_vector"
|
||||
android:title="@string/dial_number"
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/cab_block_number"
|
||||
android:icon="@drawable/ic_minus_circle_vector"
|
||||
android:title="@string/block_number"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/cab_copy_number"
|
||||
|
@ -5,21 +5,21 @@
|
||||
android:id="@+id/cab_copy_to_clipboard"
|
||||
android:icon="@drawable/ic_copy"
|
||||
android:title="@string/copy_to_clipboard"
|
||||
app:showAsAction="ifRoom" />
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/cab_share"
|
||||
android:icon="@drawable/ic_share_vector"
|
||||
android:title="@string/share"
|
||||
app:showAsAction="ifRoom" />
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/cab_delete"
|
||||
android:icon="@drawable/ic_delete_vector"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/cab_select_text"
|
||||
android:title="@string/select_text"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/cab_delete"
|
||||
android:icon="@drawable/ic_delete_vector"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/cab_select_all"
|
||||
android:title="@string/select_all"
|
||||
|
@ -13,7 +13,6 @@
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/block_number"
|
||||
android:icon="@drawable/ic_block_vector"
|
||||
android:title="@string/block_number"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
|
81
app/src/main/res/values-cs/strings.xml
Normal file
81
app/src/main/res/values-cs/strings.xml
Normal file
@ -0,0 +1,81 @@
|
||||
<resources>
|
||||
<string name="app_name">Simple SMS Messenger</string>
|
||||
<string name="app_launcher_name">SMS Messenger</string>
|
||||
<string name="type_a_message">Napište zprávu…</string>
|
||||
<string name="message_not_sent_short">Zpráva nebyla odeslána</string>
|
||||
<string name="message_not_sent_touch_retry">Nebylo odesláno. Klepnutím to zkuste znovu.</string>
|
||||
<string name="message_sending_error">Vaše zpráva pro \'%s\' nebyla odeslána</string>
|
||||
<string name="add_person">Přidat osobu</string>
|
||||
<string name="attachment">Příloha</string>
|
||||
<string name="no_conversations_found">Nebyly nalezeny žádné uložené konverzace</string>
|
||||
<string name="start_conversation">Zahajte konverzaci</string>
|
||||
<string name="reply">Odpověď</string>
|
||||
<string name="show_character_counter">Zobrazit počítadlo znaků při psaní zpráv</string>
|
||||
<string name="loading_messages">Načítání zpráv…</string>
|
||||
<string name="no_reply_support">Odesílatel nepodporuje odpovědi</string>
|
||||
<string name="draft">Návrh</string>
|
||||
<string name="sending">Odesílá se…</string>
|
||||
<string name="export_messages">Export zpráv</string>
|
||||
<string name="import_messages">Import zpráv</string>
|
||||
|
||||
<!-- New conversation -->
|
||||
<string name="new_conversation">Nová konverzace</string>
|
||||
<string name="add_contact_or_number">Přidejte kontakt nebo číslo…</string>
|
||||
<string name="suggestions">Návrhy</string>
|
||||
|
||||
<!-- Notifications -->
|
||||
<string name="channel_received_sms">Přijaté SMS</string>
|
||||
<string name="new_message">Nová zpráva</string>
|
||||
<string name="mark_as_read">Označit jako přečtené</string>
|
||||
<string name="mark_as_unread">Označit jako nepřečtené</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_whole_conversation_confirmation">Opravdu chcete smazat všechny zprávy z této konverzace?</string>
|
||||
|
||||
<!-- Are you sure you want to delete 5 conversations? -->
|
||||
<plurals name="delete_conversations">
|
||||
<item quantity="one">%d conversation</item>
|
||||
<item quantity="other">%d conversations</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Are you sure you want to delete 5 messages? -->
|
||||
<plurals name="delete_messages">
|
||||
<item quantity="one">%d message</item>
|
||||
<item quantity="other">%d messages</item>
|
||||
</plurals>
|
||||
|
||||
<!-- FAQ -->
|
||||
<string name="faq_1_title">Proč aplikace vyžaduje přístup k internetu?</string>
|
||||
<string name="faq_1_text">Je smutné, že je to nutné pro odesílání příloh MMS. Nebýt schopen posílat MMS by byla opravdu obrovská nevýhoda ve srovnání s jinými aplikacemi, proto jsme se rozhodli jít touto cestou.
|
||||
Jako obvykle však neexistují žádné reklamy, sledování ani analytika, internet se používá pouze k odesílání MMS.</string>
|
||||
|
||||
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
|
||||
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
|
||||
<string name="app_title">Simple SMS Messenger - Snadná správa zpráv</string>
|
||||
<!-- Short description has to have max 80 characters -->
|
||||
<string name="app_short_description">Snadný a rychlý způsob správy SMS a MMS zpráv bez reklam.</string>
|
||||
<string name="app_long_description">
|
||||
Skvělý způsob, jak zůstat v kontaktu se svými příbuznými, a to zasíláním zpráv SMS i MMS. Aplikace správně zpracovává i skupinové zprávy, stejně jako blokování čísel z Androidu 7+.
|
||||
|
||||
Nabízí mnoho formátů data, ze kterých si můžete vybrat, abyste se při jejich používání cítili pohodlně. Můžete také přepínat mezi 12 a 24 hodinovým formátem času.
|
||||
|
||||
Ve srovnání s konkurencí má opravdu malou velikost aplikace, takže je stahování opravdu rychlé.
|
||||
|
||||
Ve výchozím nastavení je dodáván s materiálovým designem a tmavým motivem a poskytuje skvělé uživatelské prostředí pro snadné použití. Nedostatek přístupu k internetu vám poskytuje více soukromí, zabezpečení a stability než jiné aplikace.
|
||||
|
||||
Neobsahuje žádné reklamy ani zbytečná oprávnění. Je plně opensource a poskytuje přizpůsobitelné barvy.
|
||||
<b>Check out the full suite of Simple Tools here:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
||||
</string>
|
||||
|
||||
<!--
|
||||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
@ -34,7 +34,7 @@
|
||||
|
||||
<!-- Are you sure you want to delete 5 conversations? -->
|
||||
<plurals name="delete_conversations">
|
||||
<item quantity="one">%d gesperk</item>
|
||||
<item quantity="one">%d gesprek</item>
|
||||
<item quantity="other">%d gesprekken</item>
|
||||
</plurals>
|
||||
|
||||
|
84
app/src/main/res/values-pl/strings.xml
Normal file
84
app/src/main/res/values-pl/strings.xml
Normal file
@ -0,0 +1,84 @@
|
||||
<resources>
|
||||
<string name="app_name">Proste wiadomości SMS</string>
|
||||
<string name="app_launcher_name">Wiadomości SMS</string>
|
||||
<string name="type_a_message">Napisz wiadomość…</string>
|
||||
<string name="message_not_sent_short">Wiadomość nie została wysłana</string>
|
||||
<string name="message_not_sent_touch_retry">Nie wysłano. Naciśnij, aby spróbować ponownie.</string>
|
||||
<string name="message_sending_error">Twoja wiadomość do \'%s\' nie została wysłana</string>
|
||||
<string name="add_person">Dodaj odbiorcę</string>
|
||||
<string name="attachment">Załącznik</string>
|
||||
<string name="no_conversations_found">Nie znaleziono żadnych zapisanych konwersacji</string>
|
||||
<string name="start_conversation">Rozpocznij konwersację</string>
|
||||
<string name="reply">Odpowiedz</string>
|
||||
<string name="show_character_counter">Pokazuj licznik znaków podczas pisania wiadomości</string>
|
||||
<string name="loading_messages">Ładowanie wiadomości…</string>
|
||||
<string name="no_reply_support">Nadawca nie obsługuje odpowiedzi</string>
|
||||
<string name="draft">Szkic</string>
|
||||
<string name="sending">Wysyłanie…</string>
|
||||
<string name="export_messages">Eksportuj wiadomości</string>
|
||||
<string name="import_messages">Importuj wiadomości</string>
|
||||
|
||||
<!-- New conversation -->
|
||||
<string name="new_conversation">Nowa konwersacja</string>
|
||||
<string name="add_contact_or_number">Dodaj kontakt lub numer…</string>
|
||||
<string name="suggestions">Propozycje</string>
|
||||
|
||||
<!-- Notifications -->
|
||||
<string name="channel_received_sms">Otrzymywanie SMS</string>
|
||||
<string name="new_message">Nowa wiadomość</string>
|
||||
<string name="mark_as_read">Oznacz jako przeczytane</string>
|
||||
<string name="mark_as_unread">Oznacz jako nieprzeczytane</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_whole_conversation_confirmation">Czy jesteś pewny/a, że chcesz usunąć wszystkie wiadomości z tej konwersacji?</string>
|
||||
|
||||
<!-- Are you sure you want to delete 5 conversations? -->
|
||||
<plurals name="delete_conversations">
|
||||
<item quantity="one">%d konwersację</item>
|
||||
<item quantity="few">%d konwersacje</item>
|
||||
<item quantity="other">%d konwersacji</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Are you sure you want to delete 5 messages? -->
|
||||
<plurals name="delete_messages">
|
||||
<item quantity="one">%d wiadomość</item>
|
||||
<item quantity="few">%d wiadomości</item>
|
||||
<item quantity="other">%d wiadomości</item>
|
||||
</plurals>
|
||||
|
||||
<!-- FAQ -->
|
||||
<string name="faq_1_title">Dlaczego aplikacja wymaga dostępu do Internetu?</string>
|
||||
<string name="faq_1_text">Niestety jest to konieczne do wysyłania załączników MMS. Brak możliwości wysyłania MMS-ów byłby naprawdę ogromną wadą w porównaniu z innymi aplikacjami, więc zdecydowaliśmy się pójść tą drogą.
|
||||
Jednak, jak zwykle, nie ma żadnych reklam, śledzenia ani analityki, Internet służy tylko do wysyłania MMS-ów.</string>
|
||||
|
||||
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
|
||||
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
|
||||
<string name="app_title">Proste wiadomości SMS - Łatwo zarządzaj SMS-ami</string>
|
||||
<!-- Short description has to have max 80 characters -->
|
||||
<string name="app_short_description">Łatwy i szybki sposób zarządzania wiadomościami SMS i MMS bez reklam.</string>
|
||||
<string name="app_long_description">
|
||||
Świetny sposób na utrzymywanie kontaktu z bliskimi poprzez wysyłanie zarówno wiadomości SMS, jak i MMS. Aplikacja poprawnie obsługuje również wiadomości grupowe, podobnie jak blokowanie numerów z Androida 7+.
|
||||
|
||||
Oferuje wiele formatów daty do wyboru, abyś czuł(a) się komfortowo podczas korzystania z niego. Możesz także przełączać się między 12- i 24-godzinnym formatem czasu.
|
||||
|
||||
Zajmuje naprawdę mało miejsca w porównaniu do konkurencji, dzięki czemu można go szybko pobrać.
|
||||
|
||||
Domyślnie jest wyposażony w Material Design i ciemny motyw, zapewniając doskonałe doświadczenie użytkownika dla łatwego użytkowania. Brak dostępu do Internetu zapewnia większą prywatność, bezpieczeństwo i stabilność niż inne aplikacje.
|
||||
|
||||
Nie zawiera reklam ani niepotrzebnych uprawnień. Jest w pełni otwartoźródłowy, zapewnia konfigurowalną kolorystykę.
|
||||
|
||||
<b>Sprawdź pełen zestaw od Simple Tools tutaj:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
||||
</string>
|
||||
|
||||
<!--
|
||||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
@ -1,14 +1,14 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.4.30'
|
||||
ext.kotlin_version = '1.5.21'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.2'
|
||||
classpath 'com.android.tools.build:gradle:4.2.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
3
fastlane/metadata/android/en-US/changelogs/30.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/30.txt
Normal file
@ -0,0 +1,3 @@
|
||||
* Improved search
|
||||
* Properly handle sending messages from notification Reply action
|
||||
* Some design, stability and translation improvements
|
2
fastlane/metadata/android/en-US/changelogs/31.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/31.txt
Normal file
@ -0,0 +1,2 @@
|
||||
* Fixed an error message wrongly popping up in some cases
|
||||
* Some stabiliy and translation improvements
|
2
fastlane/metadata/android/en-US/changelogs/33.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/33.txt
Normal file
@ -0,0 +1,2 @@
|
||||
* Fixed a glitch with current conversation not being updated correctly at incoming messages
|
||||
* Couple other stability, translation and bugfixes
|
1
fastlane/metadata/android/en-US/changelogs/34.txt
Normal file
1
fastlane/metadata/android/en-US/changelogs/34.txt
Normal file
@ -0,0 +1 @@
|
||||
* Adding some UX, stability and translation improvements
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||
|
Loading…
x
Reference in New Issue
Block a user