mirror of
https://github.com/SimpleMobileTools/Simple-SMS-Messenger.git
synced 2025-06-05 21:49:22 +02:00
Merge branch 'master' of https://github.com/SimpleMobileTools/Simple-SMS-Messenger
# Conflicts: # gradle/wrapper/gradle-wrapper.properties
This commit is contained in:
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,6 +1,30 @@
|
|||||||
Changelog
|
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)*
|
Version 5.9.0 *(2021-02-16)*
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
@@ -16,8 +16,8 @@ android {
|
|||||||
applicationId "com.simplemobiletools.smsmessenger"
|
applicationId "com.simplemobiletools.smsmessenger"
|
||||||
minSdkVersion 22
|
minSdkVersion 22
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 29
|
versionCode 34
|
||||||
versionName "5.9.0"
|
versionName "5.9.4"
|
||||||
setProperty("archivesBaseName", "sms-messenger")
|
setProperty("archivesBaseName", "sms-messenger")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,14 +56,14 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.simplemobiletools:commons:5.33.32'
|
implementation 'com.github.SimpleMobileTools:Simple-Commons:25daba7267'
|
||||||
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:c3de1d040a'
|
implementation 'com.github.tibbi:IndicatorFastScroll:c3de1d040a'
|
||||||
implementation "me.leolin:ShortcutBadger:1.1.22"
|
implementation "me.leolin:ShortcutBadger:1.1.22"
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
|
|
||||||
kapt "androidx.room:room-compiler:2.2.6"
|
kapt "androidx.room:room-compiler:2.3.0"
|
||||||
implementation "androidx.room:room-runtime:2.2.6"
|
implementation "androidx.room:room-runtime:2.3.0"
|
||||||
annotationProcessor "androidx.room:room-compiler:2.2.6"
|
annotationProcessor "androidx.room:room-compiler:2.3.0"
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,11 @@
|
|||||||
android:name="android.permission.USE_FINGERPRINT"
|
android:name="android.permission.USE_FINGERPRINT"
|
||||||
tools:node="remove" />
|
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" />
|
<uses-feature android:name="android.hardware.telephony" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
@@ -184,7 +184,7 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getNewConversations(cachedConversations: ArrayList<Conversation>) {
|
private fun getNewConversations(cachedConversations: ArrayList<Conversation>) {
|
||||||
val privateCursor = getMyContactsCursor()?.loadInBackground()
|
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
||||||
val conversations = getConversations(privateContacts = privateContacts)
|
val conversations = getConversations(privateContacts = privateContacts)
|
||||||
@@ -247,6 +247,7 @@ class MainActivity : SimpleActivity() {
|
|||||||
conversations_list.adapter = this
|
conversations_list.adapter = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conversations_list.scheduleLayoutAnimation()
|
||||||
conversations_fastscroller.setViews(conversations_list) {
|
conversations_fastscroller.setViews(conversations_list) {
|
||||||
val listItem = (conversations_list.adapter as? ConversationsAdapter)?.conversations?.getOrNull(it)
|
val listItem = (conversations_list.adapter as? ConversationsAdapter)?.conversations?.getOrNull(it)
|
||||||
conversations_fastscroller.updateBubbleText(listItem?.title ?: "")
|
conversations_fastscroller.updateBubbleText(listItem?.title ?: "")
|
||||||
|
@@ -64,7 +64,10 @@ class NewConversationActivity : SimpleActivity() {
|
|||||||
val searchString = it
|
val searchString = it
|
||||||
val filteredContacts = ArrayList<SimpleContact>()
|
val filteredContacts = ArrayList<SimpleContact>()
|
||||||
allContacts.forEach {
|
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)
|
filteredContacts.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,31 +138,38 @@ class NewConversationActivity : SimpleActivity() {
|
|||||||
no_contacts_placeholder.text = getString(placeholderText)
|
no_contacts_placeholder.text = getString(placeholderText)
|
||||||
}
|
}
|
||||||
|
|
||||||
ContactsAdapter(this, contacts, contacts_list, null) {
|
val currAdapter = contacts_list.adapter
|
||||||
hideKeyboard()
|
if (currAdapter == null) {
|
||||||
val contact = it as SimpleContact
|
ContactsAdapter(this, contacts, contacts_list, null) {
|
||||||
val phoneNumbers = contact.phoneNumbers
|
hideKeyboard()
|
||||||
if (phoneNumbers.size > 1) {
|
val contact = it as SimpleContact
|
||||||
val items = ArrayList<RadioItem>()
|
val phoneNumbers = contact.phoneNumbers
|
||||||
phoneNumbers.forEachIndexed { index, phoneNumber ->
|
if (phoneNumbers.size > 1) {
|
||||||
items.add(RadioItem(index, phoneNumber, phoneNumber))
|
val items = ArrayList<RadioItem>()
|
||||||
}
|
phoneNumbers.forEachIndexed { index, phoneNumber ->
|
||||||
|
items.add(RadioItem(index, phoneNumber, phoneNumber))
|
||||||
|
}
|
||||||
|
|
||||||
RadioGroupDialog(this, items) {
|
RadioGroupDialog(this, items) {
|
||||||
launchThreadActivity(it as String, contact.name)
|
launchThreadActivity(it as String, contact.name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
launchThreadActivity(phoneNumbers.first(), contact.name)
|
||||||
}
|
}
|
||||||
} else {
|
}.apply {
|
||||||
launchThreadActivity(phoneNumbers.first(), contact.name)
|
contacts_list.adapter = this
|
||||||
}
|
}
|
||||||
}.apply {
|
|
||||||
contacts_list.adapter = this
|
contacts_list.scheduleLayoutAnimation()
|
||||||
|
} else {
|
||||||
|
(currAdapter as ContactsAdapter).updateContacts(contacts)
|
||||||
}
|
}
|
||||||
|
|
||||||
setupLetterFastscroller(contacts)
|
setupLetterFastscroller(contacts)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillSuggestedContacts(callback: () -> Unit) {
|
private fun fillSuggestedContacts(callback: () -> Unit) {
|
||||||
val privateCursor = getMyContactsCursor()?.loadInBackground()
|
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
||||||
val suggestions = getSuggestedContacts(privateContacts)
|
val suggestions = getSuggestedContacts(privateContacts)
|
||||||
|
@@ -156,7 +156,12 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
|
|
||||||
private fun setupCachedMessages(callback: () -> Unit) {
|
private fun setupCachedMessages(callback: () -> Unit) {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
messages = messagesDB.getThreadMessages(threadId).toMutableList() as ArrayList<Message>
|
messages = try {
|
||||||
|
messagesDB.getThreadMessages(threadId).toMutableList() as ArrayList<Message>
|
||||||
|
} catch (e: Exception) {
|
||||||
|
ArrayList()
|
||||||
|
}
|
||||||
|
|
||||||
setupParticipants()
|
setupParticipants()
|
||||||
setupAdapter()
|
setupAdapter()
|
||||||
|
|
||||||
@@ -174,12 +179,20 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupThread() {
|
private fun setupThread() {
|
||||||
val privateCursor = getMyContactsCursor()?.loadInBackground()
|
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
val cachedMessagesCode = messages.hashCode()
|
val cachedMessagesCode = messages.clone().hashCode()
|
||||||
messages = getMessages(threadId)
|
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()
|
setupParticipants()
|
||||||
@@ -533,7 +546,7 @@ class ThreadActivity : SimpleActivity() {
|
|||||||
var hadUnreadItems = false
|
var hadUnreadItems = false
|
||||||
val cnt = messages.size
|
val cnt = messages.size
|
||||||
for (i in 0 until cnt) {
|
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
|
// 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) {
|
if (message.date - prevDateTime > MIN_DATE_TIME_DIFF_SECS) {
|
||||||
val simCardID = subscriptionIdToSimId[message.subscriptionId] ?: "?"
|
val simCardID = subscriptionIdToSimId[message.subscriptionId] ?: "?"
|
||||||
|
@@ -20,14 +20,14 @@ class AutoCompleteTextViewAdapter(val activity: SimpleActivity, val contacts: Ar
|
|||||||
var resultList = ArrayList<SimpleContact>()
|
var resultList = ArrayList<SimpleContact>()
|
||||||
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||||
val contact = resultList[position]
|
val contact = resultList.getOrNull(position)
|
||||||
var listItem = convertView
|
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 = LayoutInflater.from(activity).inflate(R.layout.item_contact_with_number, parent, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
listItem!!.apply {
|
listItem!!.apply {
|
||||||
tag = contact.name.isNotEmpty()
|
tag = contact?.name?.isNotEmpty()
|
||||||
// clickable and focusable properties seem to break Autocomplete clicking, so remove them
|
// clickable and focusable properties seem to break Autocomplete clicking, so remove them
|
||||||
findViewById<View>(R.id.item_contact_frame).apply {
|
findViewById<View>(R.id.item_contact_frame).apply {
|
||||||
isClickable = false
|
isClickable = false
|
||||||
@@ -35,14 +35,16 @@ class AutoCompleteTextViewAdapter(val activity: SimpleActivity, val contacts: Ar
|
|||||||
}
|
}
|
||||||
|
|
||||||
val backgroundColor = activity.config.backgroundColor
|
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<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_name).setTextColor(backgroundColor.getContrastColor())
|
||||||
findViewById<TextView>(R.id.item_contact_number).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
|
return listItem
|
||||||
|
@@ -17,8 +17,10 @@ import com.simplemobiletools.smsmessenger.R
|
|||||||
import com.simplemobiletools.smsmessenger.activities.SimpleActivity
|
import com.simplemobiletools.smsmessenger.activities.SimpleActivity
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ContactsAdapter(activity: SimpleActivity, var contacts: ArrayList<SimpleContact>, recyclerView: MyRecyclerView, fastScroller: FastScroller?,
|
class ContactsAdapter(
|
||||||
itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
activity: SimpleActivity, var contacts: ArrayList<SimpleContact>, recyclerView: MyRecyclerView, fastScroller: FastScroller?,
|
||||||
|
itemClick: (Any) -> Unit
|
||||||
|
) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
||||||
private var fontSize = activity.getTextSize()
|
private var fontSize = activity.getTextSize()
|
||||||
|
|
||||||
override fun getActionMenuId() = 0
|
override fun getActionMenuId() = 0
|
||||||
@@ -51,10 +53,12 @@ class ContactsAdapter(activity: SimpleActivity, var contacts: ArrayList<SimpleCo
|
|||||||
|
|
||||||
override fun getItemCount() = contacts.size
|
override fun getItemCount() = contacts.size
|
||||||
|
|
||||||
override fun onViewRecycled(holder: ViewHolder) {
|
fun updateContacts(newContacts: ArrayList<SimpleContact>) {
|
||||||
super.onViewRecycled(holder)
|
val oldHashCode = contacts.hashCode()
|
||||||
if (!activity.isDestroyed && !activity.isFinishing) {
|
val newHashCode = newContacts.hashCode()
|
||||||
Glide.with(activity).clear(holder.itemView.findViewById<ImageView>(R.id.item_contact_image))
|
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)
|
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
|
package com.simplemobiletools.smsmessenger.adapters
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@@ -26,8 +27,10 @@ import com.simplemobiletools.smsmessenger.helpers.refreshMessages
|
|||||||
import com.simplemobiletools.smsmessenger.models.Conversation
|
import com.simplemobiletools.smsmessenger.models.Conversation
|
||||||
import kotlinx.android.synthetic.main.item_conversation.view.*
|
import kotlinx.android.synthetic.main.item_conversation.view.*
|
||||||
|
|
||||||
class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayList<Conversation>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
|
class ConversationsAdapter(
|
||||||
itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
activity: SimpleActivity, var conversations: ArrayList<Conversation>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
|
||||||
|
itemClick: (Any) -> Unit
|
||||||
|
) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
|
||||||
private var fontSize = activity.getTextSize()
|
private var fontSize = activity.getTextSize()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -120,11 +123,13 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis
|
|||||||
Intent(Intent.ACTION_DIAL).apply {
|
Intent(Intent.ACTION_DIAL).apply {
|
||||||
data = Uri.fromParts("tel", conversation.phoneNumber, null)
|
data = Uri.fromParts("tel", conversation.phoneNumber, null)
|
||||||
|
|
||||||
if (resolveActivity(activity.packageManager) != null) {
|
try {
|
||||||
activity.startActivity(this)
|
activity.startActivity(this)
|
||||||
finishActMode()
|
finishActMode()
|
||||||
} else {
|
} catch (e: ActivityNotFoundException) {
|
||||||
activity.toast(R.string.no_app_found)
|
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
|
action = Intent.ACTION_INSERT_OR_EDIT
|
||||||
type = "vnd.android.cursor.item/contact"
|
type = "vnd.android.cursor.item/contact"
|
||||||
putExtra(KEY_PHONE, conversation.phoneNumber)
|
putExtra(KEY_PHONE, conversation.phoneNumber)
|
||||||
|
activity.launchActivityIntent(this)
|
||||||
if (resolveActivity(activity.packageManager) != null) {
|
|
||||||
activity.startActivity(this)
|
|
||||||
} else {
|
|
||||||
activity.toast(R.string.no_app_found)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,10 +209,11 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun updateConversations(newConversations: ArrayList<Conversation>) {
|
fun updateConversations(newConversations: ArrayList<Conversation>) {
|
||||||
|
val latestConversations = newConversations.clone() as ArrayList<Conversation>
|
||||||
val oldHashCode = conversations.hashCode()
|
val oldHashCode = conversations.hashCode()
|
||||||
val newHashCode = newConversations.hashCode()
|
val newHashCode = latestConversations.hashCode()
|
||||||
if (newHashCode != oldHashCode) {
|
if (newHashCode != oldHashCode) {
|
||||||
conversations = newConversations
|
conversations = latestConversations
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package com.simplemobiletools.smsmessenger.adapters
|
package com.simplemobiletools.smsmessenger.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@@ -200,10 +201,11 @@ class ThreadAdapter(
|
|||||||
private fun isThreadDateTime(position: Int) = messages.getOrNull(position) is ThreadDateTime
|
private fun isThreadDateTime(position: Int) = messages.getOrNull(position) is ThreadDateTime
|
||||||
|
|
||||||
fun updateMessages(newMessages: ArrayList<ThreadItem>) {
|
fun updateMessages(newMessages: ArrayList<ThreadItem>) {
|
||||||
|
val latestMessages = newMessages.clone() as ArrayList<ThreadItem>
|
||||||
val oldHashCode = messages.hashCode()
|
val oldHashCode = messages.hashCode()
|
||||||
val newHashCode = newMessages.hashCode()
|
val newHashCode = latestMessages.hashCode()
|
||||||
if (newHashCode != oldHashCode) {
|
if (newHashCode != oldHashCode) {
|
||||||
messages = newMessages
|
messages = latestMessages
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
recyclerView.scrollToPosition(messages.size - 1)
|
recyclerView.scrollToPosition(messages.size - 1)
|
||||||
}
|
}
|
||||||
@@ -315,15 +317,17 @@ class ThreadAdapter(
|
|||||||
setDataAndType(uri, mimetype)
|
setDataAndType(uri, mimetype)
|
||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
|
|
||||||
if (resolveActivity(activity.packageManager) != null) {
|
try {
|
||||||
activity.startActivity(this)
|
activity.startActivity(this)
|
||||||
} else {
|
} catch (e: ActivityNotFoundException) {
|
||||||
val newMimetype = filename.getMimeType()
|
val newMimetype = filename.getMimeType()
|
||||||
if (newMimetype.isNotEmpty() && mimetype != newMimetype) {
|
if (newMimetype.isNotEmpty() && mimetype != newMimetype) {
|
||||||
launchViewIntent(uri, newMimetype, filename)
|
launchViewIntent(uri, newMimetype, filename)
|
||||||
} else {
|
} else {
|
||||||
activity.toast(R.string.no_app_found)
|
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) {
|
} catch (e: Exception) {
|
||||||
showErrorToast(e)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NamePhoto(number, null)
|
return NamePhoto(number, null)
|
||||||
@@ -507,8 +506,12 @@ fun Context.insertNewSMS(address: String, subject: String, body: String, date: L
|
|||||||
put(Sms.SUBSCRIPTION_ID, subscriptionId)
|
put(Sms.SUBSCRIPTION_ID, subscriptionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
val newUri = contentResolver.insert(uri, contentValues)
|
return try {
|
||||||
return newUri?.lastPathSegment?.toLong() ?: 0L
|
val newUri = contentResolver.insert(uri, contentValues)
|
||||||
|
newUri?.lastPathSegment?.toLong() ?: 0L
|
||||||
|
} catch (e: Exception) {
|
||||||
|
0L
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.deleteConversation(threadId: Long) {
|
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?) {
|
fun Context.showReceivedMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?) {
|
||||||
val privateCursor = getMyContactsCursor()?.loadInBackground()
|
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
val senderName = getNameFromAddress(address, privateCursor)
|
val senderName = getNameFromAddress(address, privateCursor)
|
||||||
|
|
||||||
|
@@ -3,17 +3,14 @@ package com.simplemobiletools.smsmessenger.receivers
|
|||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import androidx.core.app.RemoteInput
|
import androidx.core.app.RemoteInput
|
||||||
import com.klinker.android.send_message.Settings
|
import com.klinker.android.send_message.Settings
|
||||||
import com.klinker.android.send_message.Transaction
|
import com.klinker.android.send_message.Transaction
|
||||||
import com.simplemobiletools.commons.extensions.notificationManager
|
import com.simplemobiletools.commons.extensions.notificationManager
|
||||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import com.simplemobiletools.smsmessenger.R
|
|
||||||
import com.simplemobiletools.smsmessenger.extensions.conversationsDB
|
import com.simplemobiletools.smsmessenger.extensions.conversationsDB
|
||||||
import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead
|
import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead
|
||||||
import com.simplemobiletools.smsmessenger.helpers.NOTIFICATION_CHANNEL
|
|
||||||
import com.simplemobiletools.smsmessenger.helpers.REPLY
|
import com.simplemobiletools.smsmessenger.helpers.REPLY
|
||||||
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
|
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
|
||||||
import com.simplemobiletools.smsmessenger.helpers.THREAD_NUMBER
|
import com.simplemobiletools.smsmessenger.helpers.THREAD_NUMBER
|
||||||
@@ -22,26 +19,28 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
|||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
val address = intent.getStringExtra(THREAD_NUMBER)
|
val address = intent.getStringExtra(THREAD_NUMBER)
|
||||||
val threadId = intent.getLongExtra(THREAD_ID, 0L)
|
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()
|
val settings = Settings()
|
||||||
settings.useSystemSending = true
|
settings.useSystemSending = true
|
||||||
|
settings.deliveryReports = true
|
||||||
|
|
||||||
val transaction = Transaction(context, settings)
|
val transaction = Transaction(context, settings)
|
||||||
val message = com.klinker.android.send_message.Message(msg, address)
|
val message = com.klinker.android.send_message.Message(msg, address)
|
||||||
|
|
||||||
try {
|
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)
|
transaction.sendNewMessage(message, threadId)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.showErrorToast(e)
|
context.showErrorToast(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
val repliedNotification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
|
context.notificationManager.cancel(threadId.hashCode())
|
||||||
.setSmallIcon(R.drawable.ic_messenger)
|
|
||||||
.setContentText(msg)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
context.notificationManager.notify(threadId.hashCode(), repliedNotification)
|
|
||||||
|
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
context.markThreadMessagesRead(threadId)
|
context.markThreadMessagesRead(threadId)
|
||||||
|
@@ -40,17 +40,21 @@ class SmsReceiver : BroadcastReceiver() {
|
|||||||
val newMessageId = context.insertNewSMS(address, subject, body, date, read, threadId, type, subscriptionId)
|
val newMessageId = context.insertNewSMS(address, subject, body, date, read, threadId, type, subscriptionId)
|
||||||
|
|
||||||
val conversation = context.getConversations(threadId).firstOrNull() ?: return@ensureBackgroundThread
|
val conversation = context.getConversations(threadId).firstOrNull() ?: return@ensureBackgroundThread
|
||||||
context.conversationsDB.insertOrUpdate(conversation)
|
try {
|
||||||
context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations())
|
context.conversationsDB.insertOrUpdate(conversation)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
val participants = arrayListOf(participant)
|
||||||
false, null, address, "", subscriptionId)
|
val messageDate = (date / 1000).toInt()
|
||||||
|
val message = Message(newMessageId, body, type, participants, messageDate, false, threadId, false, null, address, "", subscriptionId)
|
||||||
context.messagesDB.insertOrUpdate(message)
|
context.messagesDB.insertOrUpdate(message)
|
||||||
|
refreshMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
context.showReceivedMessageNotification(address, body, threadId, null)
|
context.showReceivedMessageNotification(address, body, threadId, null)
|
||||||
refreshMessages()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,7 @@ class SmsStatusSentReceiver : SentReceiver() {
|
|||||||
} else {
|
} else {
|
||||||
Telephony.Sms.MESSAGE_TYPE_OUTBOX
|
Telephony.Sms.MESSAGE_TYPE_OUTBOX
|
||||||
}
|
}
|
||||||
|
|
||||||
context.updateMessageType(messageId, type)
|
context.updateMessageType(messageId, type)
|
||||||
context.messagesDB.updateType(messageId, type)
|
context.messagesDB.updateType(messageId, type)
|
||||||
refreshMessages()
|
refreshMessages()
|
||||||
@@ -50,7 +51,7 @@ class SmsStatusSentReceiver : SentReceiver() {
|
|||||||
|
|
||||||
private fun showSendingFailedNotification(context: Context, messageId: Long) {
|
private fun showSendingFailedNotification(context: Context, messageId: Long) {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
val privateCursor = context.getMyContactsCursor()?.loadInBackground()
|
val privateCursor = context.getMyContactsCursor(false, true)?.loadInBackground()
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
val address = context.getMessageRecipientAddress(messageId)
|
val address = context.getMessageRecipientAddress(messageId)
|
||||||
val threadId = context.getThreadId(address)
|
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.Settings
|
||||||
import com.klinker.android.send_message.Transaction
|
import com.klinker.android.send_message.Transaction
|
||||||
import com.simplemobiletools.smsmessenger.extensions.getThreadId
|
import com.simplemobiletools.smsmessenger.extensions.getThreadId
|
||||||
|
import com.simplemobiletools.smsmessenger.receivers.SmsStatusDeliveredReceiver
|
||||||
|
import com.simplemobiletools.smsmessenger.receivers.SmsStatusSentReceiver
|
||||||
|
|
||||||
class HeadlessSmsSendService : Service() {
|
class HeadlessSmsSendService : Service() {
|
||||||
override fun onBind(intent: Intent?) = null
|
override fun onBind(intent: Intent?) = null
|
||||||
@@ -20,8 +22,17 @@ class HeadlessSmsSendService : Service() {
|
|||||||
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
|
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||||
val settings = Settings()
|
val settings = Settings()
|
||||||
settings.useSystemSending = true
|
settings.useSystemSending = true
|
||||||
|
settings.deliveryReports = true
|
||||||
|
|
||||||
val transaction = Transaction(this, settings)
|
val transaction = Transaction(this, settings)
|
||||||
val message = com.klinker.android.send_message.Message(text, number)
|
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))
|
transaction.sendNewMessage(message, getThreadId(number))
|
||||||
} catch (ignored: Exception) {
|
} catch (ignored: Exception) {
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
android:layoutAnimation="@anim/layout_animation"
|
||||||
android:overScrollMode="ifContentScrolls"
|
android:overScrollMode="ifContentScrolls"
|
||||||
android:scrollbars="none"
|
android:scrollbars="none"
|
||||||
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
||||||
|
@@ -101,6 +101,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_below="@+id/suggestions_scrollview"
|
android:layout_below="@+id/suggestions_scrollview"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
android:layoutAnimation="@anim/layout_animation"
|
||||||
android:overScrollMode="ifContentScrolls"
|
android:overScrollMode="ifContentScrolls"
|
||||||
android:scrollbars="none"
|
android:scrollbars="none"
|
||||||
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
||||||
|
@@ -5,21 +5,21 @@
|
|||||||
android:id="@+id/cab_delete"
|
android:id="@+id/cab_delete"
|
||||||
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="always" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/cab_add_number_to_contact"
|
android:id="@+id/cab_add_number_to_contact"
|
||||||
android:icon="@drawable/ic_add_person_vector"
|
android:icon="@drawable/ic_add_person_vector"
|
||||||
android:title="@string/add_number_to_contact"
|
android:title="@string/add_number_to_contact"
|
||||||
app:showAsAction="ifRoom" />
|
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
|
<item
|
||||||
android:id="@+id/cab_dial_number"
|
android:id="@+id/cab_dial_number"
|
||||||
android:icon="@drawable/ic_phone_vector"
|
android:icon="@drawable/ic_phone_vector"
|
||||||
android:title="@string/dial_number"
|
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" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/cab_copy_number"
|
android:id="@+id/cab_copy_number"
|
||||||
|
@@ -5,21 +5,21 @@
|
|||||||
android:id="@+id/cab_copy_to_clipboard"
|
android:id="@+id/cab_copy_to_clipboard"
|
||||||
android:icon="@drawable/ic_copy"
|
android:icon="@drawable/ic_copy"
|
||||||
android:title="@string/copy_to_clipboard"
|
android:title="@string/copy_to_clipboard"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="always" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/cab_share"
|
android:id="@+id/cab_share"
|
||||||
android:icon="@drawable/ic_share_vector"
|
android:icon="@drawable/ic_share_vector"
|
||||||
android:title="@string/share"
|
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
|
<item
|
||||||
android:id="@+id/cab_select_text"
|
android:id="@+id/cab_select_text"
|
||||||
android:title="@string/select_text"
|
android:title="@string/select_text"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
<item
|
|
||||||
android:id="@+id/cab_delete"
|
|
||||||
android:icon="@drawable/ic_delete_vector"
|
|
||||||
android:title="@string/delete"
|
|
||||||
app:showAsAction="ifRoom" />
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/cab_select_all"
|
android:id="@+id/cab_select_all"
|
||||||
android:title="@string/select_all"
|
android:title="@string/select_all"
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/block_number"
|
android:id="@+id/block_number"
|
||||||
android:icon="@drawable/ic_block_vector"
|
|
||||||
android:title="@string/block_number"
|
android:title="@string/block_number"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
<item
|
<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? -->
|
<!-- Are you sure you want to delete 5 conversations? -->
|
||||||
<plurals name="delete_conversations">
|
<plurals name="delete_conversations">
|
||||||
<item quantity="one">%d gesperk</item>
|
<item quantity="one">%d gesprek</item>
|
||||||
<item quantity="other">%d gesprekken</item>
|
<item quantity="other">%d gesprekken</item>
|
||||||
</plurals>
|
</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.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.4.30'
|
ext.kotlin_version = '1.5.21'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// 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
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
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
|
||||||
|
Reference in New Issue
Block a user