Merge branch 'master' into fix_108

This commit is contained in:
Tibor Kaputa 2021-08-18 12:40:27 +02:00 committed by GitHub
commit 88213f1c39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
79 changed files with 1317 additions and 238 deletions

View file

@ -1,9 +1,3 @@
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided this notice is
# preserved. This file is offered as-is, without any warranty.
# Names of contributors must not be used to endorse or promote products
# derived from this file without specific prior written permission.
# EditorConfig
# http://EditorConfig.org
@ -17,7 +11,12 @@ insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 4
continuation_indent_size = 8
continuation_indent_size = 4
max_line_length = 160
[*.xml]
continuation_indent_size = 4
[*.kt]
ij_kotlin_name_count_to_use_star_import = 5
ij_kotlin_name_count_to_use_star_import_for_members = 5

View file

@ -1,6 +1,56 @@
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)*
----------------------------
* Added Search
* Added a White theme with special handling
* Some stability and translation improvements
Version 5.8.3 *(2021-01-27)*
----------------------------
* Adding some stability and translation improvements
Version 5.8.2 *(2021-01-18)*
----------------------------
* Fixed a glitch with inability to send messages in empty conversations
* Adding a settings item for quickly getting into notification settings
* Some stability and translation improvements
Version 5.8.1 *(2021-01-11)*
----------------------------
* Fixed a glitch with "Sending..." stuck at messages
* Allow selecting a phone numbers at contacts with multiple ones
* Some translation and stability improvements
Version 5.8.0 *(2021-01-02)*
----------------------------

View file

@ -11,20 +11,21 @@ It comes with material design and dark theme by default, provides great user exp
Contains no ads or unnecessary permissions. It is fully opensource, provides customizable colors.
Check out the full suite of Simple Tools here:
Check out the full suite of Simple Tools here:
https://www.simplemobiletools.com
Facebook:
Facebook:
https://www.facebook.com/simplemobiletools
Reddit:
Reddit:
https://www.reddit.com/r/SimpleMobileTools
<a href='https://play.google.com/store/apps/details?id=com.simplemobiletools.smsmessenger'><img src='https://simplemobiletools.com/assets/images/google-play.png' alt='Get it on Google Play' height=45/></a>
<a href='https://f-droid.org/packages/com.simplemobiletools.smsmessenger'><img src='https://simplemobiletools.com/assets/images/f-droid.png' alt='Get it on F-Droid' height='45' /></a>
<div style="display:flex;">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/app_1.jpg" width="30%">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.jpg" width="30%">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/english/1.jpg" width="30%">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/english/2.jpg" width="30%">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/english/3.jpg" width="30%">
</div>

View file

@ -16,8 +16,8 @@ android {
applicationId "com.simplemobiletools.smsmessenger"
minSdkVersion 22
targetSdkVersion 30
versionCode 25
versionName "5.8.0"
versionCode 34
versionName "5.9.4"
setProperty("archivesBaseName", "sms-messenger")
}
@ -56,14 +56,14 @@ android {
}
dependencies {
implementation 'com.simplemobiletools:commons:5.32.20'
implementation 'com.github.SimpleMobileTools:Simple-Commons:203ed6018e'
implementation 'org.greenrobot:eventbus:3.2.0'
implementation 'com.klinkerapps:android-smsmms:5.2.6'
implementation 'com.github.tibbi:IndicatorFastScroll:08f512858a'
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"
}

View file

@ -13,11 +13,20 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission
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
@ -38,6 +47,21 @@
android:name=".activities.ThreadActivity"
android:parentActivityName=".activities.MainActivity" />
<activity
android:name=".activities.SearchActivity"
android:label=""
android:parentActivityName=".activities.MainActivity"
android:resizeableActivity="true">
<meta-data
android:name="android.app.default_searchable"
android:resource="@xml/searchable"/>
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
</activity>
<activity
android:name=".activities.NewConversationActivity"
android:parentActivityName=".activities.MainActivity">

View file

@ -100,11 +100,13 @@ class MainActivity : SimpleActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
updateMenuItemColors(menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.search -> launchSearch()
R.id.settings -> launchSettings()
R.id.about -> launchAbout()
else -> return super.onOptionsItemSelected(item)
@ -182,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)
@ -245,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 ?: "")
@ -295,6 +298,10 @@ class MainActivity : SimpleActivity() {
.build()
}
private fun launchSearch() {
startActivity(Intent(applicationContext, SearchActivity::class.java))
}
private fun launchSettings() {
startActivity(Intent(applicationContext, SettingsActivity::class.java))
}

View file

@ -7,8 +7,10 @@ import android.view.Menu
import android.view.WindowManager
import com.google.gson.Gson
import com.reddit.indicatorfastscroll.FastScrollItemIndicator
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.SimpleContact
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.adapters.ContactsAdapter
@ -62,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)
}
}
@ -87,9 +92,12 @@ class NewConversationActivity : SimpleActivity() {
}
}
val adjustedPrimaryColor = getAdjustedPrimaryColor()
contacts_letter_fastscroller.textColor = config.textColor.getColorStateList()
contacts_letter_fastscroller.pressedTextColor = adjustedPrimaryColor
contacts_letter_fastscroller_thumb.setupWithFastScroller(contacts_letter_fastscroller)
contacts_letter_fastscroller_thumb.textColor = config.primaryColor.getContrastColor()
contacts_letter_fastscroller_thumb?.textColor = adjustedPrimaryColor.getContrastColor()
contacts_letter_fastscroller_thumb?.thumbColor = adjustedPrimaryColor.getColorStateList()
}
private fun isThirdPartyIntent(): Boolean {
@ -130,18 +138,38 @@ class NewConversationActivity : SimpleActivity() {
no_contacts_placeholder.text = getString(placeholderText)
}
ContactsAdapter(this, contacts, contacts_list, null) {
hideKeyboard()
launchThreadActivity((it as SimpleContact).phoneNumbers.first(), it.name)
}.apply {
contacts_list.adapter = this
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)
}
} else {
launchThreadActivity(phoneNumbers.first(), contact.name)
}
}.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)
@ -179,7 +207,7 @@ class NewConversationActivity : SimpleActivity() {
try {
val name = contacts[position].name
val character = if (name.isNotEmpty()) name.substring(0, 1) else ""
FastScrollItemIndicator.Text(character.toUpperCase(Locale.getDefault()))
FastScrollItemIndicator.Text(character.toUpperCase(Locale.getDefault()).normalizeString())
} catch (e: Exception) {
FastScrollItemIndicator.Text("")
}

View file

@ -0,0 +1,146 @@
package com.simplemobiletools.smsmessenger.activities
import android.annotation.SuppressLint
import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.util.TypedValue
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.widget.SearchView
import androidx.core.view.MenuItemCompat
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.adapters.SearchResultsAdapter
import com.simplemobiletools.smsmessenger.extensions.conversationsDB
import com.simplemobiletools.smsmessenger.extensions.messagesDB
import com.simplemobiletools.smsmessenger.helpers.SEARCHED_MESSAGE_ID
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
import com.simplemobiletools.smsmessenger.helpers.THREAD_TITLE
import com.simplemobiletools.smsmessenger.models.Conversation
import com.simplemobiletools.smsmessenger.models.Message
import com.simplemobiletools.smsmessenger.models.SearchResult
import kotlinx.android.synthetic.main.activity_search.*
class SearchActivity : SimpleActivity() {
private var mIsSearchOpen = false
private var mLastSearchedText = ""
private var mSearchMenuItem: MenuItem? = null
@SuppressLint("InlinedApi")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
updateTextColors(search_holder)
search_placeholder.setTextSize(TypedValue.COMPLEX_UNIT_PX, getTextSize())
search_placeholder_2.setTextSize(TypedValue.COMPLEX_UNIT_PX, getTextSize())
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_search, menu)
setupSearch(menu)
return true
}
private fun setupSearch(menu: Menu) {
val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
mSearchMenuItem = menu.findItem(R.id.search)
MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, object : MenuItemCompat.OnActionExpandListener {
override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
mIsSearchOpen = true
return true
}
// this triggers on device rotation too, avoid doing anything
override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
if (mIsSearchOpen) {
mIsSearchOpen = false
mLastSearchedText = ""
finish()
}
return true
}
})
mSearchMenuItem?.expandActionView()
(mSearchMenuItem?.actionView as? SearchView)?.apply {
setSearchableInfo(searchManager.getSearchableInfo(componentName))
isSubmitButtonEnabled = false
setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String) = false
override fun onQueryTextChange(newText: String): Boolean {
if (mIsSearchOpen) {
mLastSearchedText = newText
textChanged(newText)
}
return true
}
})
}
}
private fun textChanged(text: String) {
search_placeholder_2.beGoneIf(text.length >= 2)
if (text.length >= 2) {
ensureBackgroundThread {
val searchQuery = "%$text%"
val messages = messagesDB.getMessagesWithText(searchQuery)
val conversations = conversationsDB.getConversationsWithText(searchQuery)
if (text == mLastSearchedText) {
showSearchResults(messages, conversations, text)
}
}
} else {
search_placeholder.beVisible()
search_results_list.beGone()
}
}
private fun showSearchResults(messages: List<Message>, conversations: List<Conversation>, searchedText: String) {
val searchResults = ArrayList<SearchResult>()
conversations.forEach { conversation ->
val date = conversation.date.formatDateOrTime(this, true, true)
val searchResult = SearchResult(-1, conversation.title, conversation.phoneNumber, date, conversation.threadId, conversation.photoUri)
searchResults.add(searchResult)
}
messages.forEach { message ->
var recipient = message.senderName
if (recipient.isEmpty() && message.participants.isNotEmpty()) {
val participantNames = message.participants.map { it.name }
recipient = TextUtils.join(", ", participantNames)
}
val date = message.date.formatDateOrTime(this, true, true)
val searchResult = SearchResult(message.id, recipient, message.body, date, message.threadId, message.senderPhotoUri)
searchResults.add(searchResult)
}
runOnUiThread {
search_results_list.beVisibleIf(searchResults.isNotEmpty())
search_placeholder.beVisibleIf(searchResults.isEmpty())
val currAdapter = search_results_list.adapter
if (currAdapter == null) {
SearchResultsAdapter(this, searchResults, search_results_list, searchedText) {
Intent(this, ThreadActivity::class.java).apply {
putExtra(THREAD_ID, (it as SearchResult).threadId)
putExtra(THREAD_TITLE, it.title)
putExtra(SEARCHED_MESSAGE_ID, it.messageId)
startActivity(this)
}
}.apply {
search_results_list.adapter = this
}
} else {
(currAdapter as SearchResultsAdapter).updateItems(searchResults, searchedText)
}
}
}
}

View file

@ -34,6 +34,7 @@ class SettingsActivity : SimpleActivity() {
setupPurchaseThankYou()
setupCustomizeColors()
setupCustomizeNotifications()
setupUseEnglish()
setupManageBlockedNumbers()
setupChangeDateTimeFormat()
@ -71,6 +72,13 @@ class SettingsActivity : SimpleActivity() {
}
}
private fun setupCustomizeNotifications() {
settings_customize_notifications_holder.beVisibleIf(isOreoPlus())
settings_customize_notifications_holder.setOnClickListener {
launchCustomizeNotificationsIntent()
}
}
private fun setupUseEnglish() {
settings_use_english_holder.beVisibleIf(config.wasUseEnglishToggled || Locale.getDefault().language != "en")
settings_use_english.isChecked = config.useEnglish

View file

@ -5,6 +5,7 @@ import android.app.Activity
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.Bundle
@ -88,6 +89,15 @@ class ThreadActivity : SimpleActivity() {
if (it) {
setupButtons()
setupCachedMessages {
val searchedMessageId = intent.getLongExtra(SEARCHED_MESSAGE_ID, -1L)
intent.removeExtra(SEARCHED_MESSAGE_ID)
if (searchedMessageId != -1L) {
val index = threadItems.indexOfFirst { (it as? Message)?.id == searchedMessageId }
if (index != -1) {
thread_messages_list.smoothScrollToPosition(index)
}
}
setupThread()
}
} else {
@ -106,13 +116,83 @@ class ThreadActivity : SimpleActivity() {
isActivityVisible = false
}
private fun setupThread() {
val privateCursor = getMyContactsCursor()?.loadInBackground()
override fun onDestroy() {
super.onDestroy()
bus?.unregister(this)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_thread, menu)
menu.apply {
findItem(R.id.delete).isVisible = threadItems.isNotEmpty()
findItem(R.id.block_number).isVisible = isNougatPlus()
}
updateMenuItemColors(menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (participants.isEmpty()) {
return true
}
when (item.itemId) {
R.id.block_number -> blockNumber()
R.id.delete -> askConfirmDelete()
R.id.manage_people -> managePeople()
R.id.mark_as_unread -> markAsUnread()
else -> return super.onOptionsItemSelected(item)
}
return true
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if (requestCode == PICK_ATTACHMENT_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
addAttachment(resultData.data!!)
}
}
private fun setupCachedMessages(callback: () -> Unit) {
ensureBackgroundThread {
val cachedMessagesCode = messages.hashCode()
messages = try {
messagesDB.getThreadMessages(threadId).toMutableList() as ArrayList<Message>
} catch (e: Exception) {
ArrayList()
}
setupParticipants()
setupAdapter()
runOnUiThread {
if (messages.isEmpty()) {
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
thread_type_message.requestFocus()
}
setupThreadTitle()
setupSIMSelector()
callback()
}
}
}
private fun setupThread() {
val privateCursor = getMyContactsCursor(false, true)?.loadInBackground()
ensureBackgroundThread {
val cachedMessagesCode = messages.clone().hashCode()
messages = getMessages(threadId)
if (messages.hashCode() == cachedMessagesCode) {
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()
@ -162,63 +242,6 @@ class ThreadActivity : SimpleActivity() {
}
}
override fun onDestroy() {
super.onDestroy()
bus?.unregister(this)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_thread, menu)
menu.apply {
findItem(R.id.delete).isVisible = threadItems.isNotEmpty()
findItem(R.id.block_number).isVisible = isNougatPlus()
}
updateMenuItemColors(menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (participants.isEmpty()) {
return true
}
when (item.itemId) {
R.id.block_number -> blockNumber()
R.id.delete -> askConfirmDelete()
R.id.manage_people -> managePeople()
R.id.mark_as_unread -> markAsUnread()
else -> return super.onOptionsItemSelected(item)
}
return true
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if (requestCode == PICK_ATTACHMENT_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
addAttachment(resultData.data!!)
}
}
private fun setupCachedMessages(callback: () -> Unit) {
ensureBackgroundThread {
messages = messagesDB.getThreadMessages(threadId).toMutableList() as ArrayList<Message>
setupParticipants()
setupAdapter()
runOnUiThread {
if (messages.isEmpty()) {
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
thread_type_message.requestFocus()
}
setupThreadTitle()
setupSIMSelector()
callback()
}
}
}
private fun setupAdapter() {
threadItems = getThreadItems()
invalidateOptionsMenu()
@ -458,11 +481,20 @@ class ThreadActivity : SimpleActivity() {
}
private fun showSelectedContacts() {
val adjustedColor = getAdjustedPrimaryColor()
val views = ArrayList<View>()
participants.forEach {
val contact = it
layoutInflater.inflate(R.layout.item_selected_contact, null).apply {
val selectedContactBg = resources.getDrawable(R.drawable.item_selected_contact_background)
(selectedContactBg as LayerDrawable).findDrawableByLayerId(R.id.selected_contact_bg).applyColorFilter(adjustedColor)
selected_contact_holder.background = selectedContactBg
selected_contact_name.text = contact.name
selected_contact_name.setTextColor(adjustedColor.getContrastColor())
selected_contact_remove.applyColorFilter(adjustedColor.getContrastColor())
selected_contact_remove.setOnClickListener {
if (contact.rawId != participants.first().rawId) {
removeSelectedContact(contact.rawId)
@ -514,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] ?: "?"

View file

@ -5,35 +5,46 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Filter
import android.widget.RelativeLayout
import android.widget.TextView
import com.simplemobiletools.commons.extensions.darkenColor
import com.simplemobiletools.commons.extensions.getContrastColor
import com.simplemobiletools.commons.extensions.normalizeString
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.models.SimpleContact
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.activities.SimpleActivity
import com.simplemobiletools.smsmessenger.extensions.config
class AutoCompleteTextViewAdapter(val activity: SimpleActivity, val contacts: ArrayList<SimpleContact>) : ArrayAdapter<SimpleContact>(activity, 0, contacts) {
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
isFocusable = false
}
findViewById<TextView>(R.id.item_contact_name).text = contact.name
findViewById<TextView>(R.id.item_contact_number).text = contact.phoneNumbers.first()
val backgroundColor = activity.config.backgroundColor
findViewById<RelativeLayout>(R.id.item_contact_holder).setBackgroundColor(backgroundColor.darkenColor())
SimpleContactsHelper(context).loadContactImage(contact.photoUri, findViewById(R.id.item_contact_image), contact.name)
findViewById<TextView>(R.id.item_contact_name).setTextColor(backgroundColor.getContrastColor())
findViewById<TextView>(R.id.item_contact_number).setTextColor(backgroundColor.getContrastColor())
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

View file

@ -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))
}
}
}

View file

@ -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()
}
}
@ -232,7 +233,7 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis
}
conversation_date.apply {
text = conversation.date.formatDateOrTime(context, true)
text = conversation.date.formatDateOrTime(context, true, false)
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 0.8f)
}

View file

@ -0,0 +1,96 @@
package com.simplemobiletools.smsmessenger.adapters
import android.util.TypedValue
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.Glide
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.extensions.getTextSize
import com.simplemobiletools.commons.extensions.highlightTextPart
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.activities.SimpleActivity
import com.simplemobiletools.smsmessenger.models.SearchResult
import kotlinx.android.synthetic.main.item_search_result.view.*
import java.util.*
class SearchResultsAdapter(
activity: SimpleActivity, var searchResults: ArrayList<SearchResult>, recyclerView: MyRecyclerView, highlightText: String, itemClick: (Any) -> Unit
) : MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) {
private var fontSize = activity.getTextSize()
private var textToHighlight = highlightText
override fun getActionMenuId() = 0
override fun prepareActionMode(menu: Menu) {}
override fun actionItemPressed(id: Int) {}
override fun getSelectableItemCount() = searchResults.size
override fun getIsItemSelectable(position: Int) = false
override fun getItemSelectionKey(position: Int) = searchResults.getOrNull(position)?.hashCode()
override fun getItemKeyPosition(key: Int) = searchResults.indexOfFirst { it.hashCode() == key }
override fun onActionModeCreated() {}
override fun onActionModeDestroyed() {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_search_result, parent)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val searchResult = searchResults[position]
holder.bindView(searchResult, true, false) { itemView, layoutPosition ->
setupView(itemView, searchResult)
}
bindViewHolder(holder)
}
override fun getItemCount() = searchResults.size
fun updateItems(newItems: ArrayList<SearchResult>, highlightText: String = "") {
if (newItems.hashCode() != searchResults.hashCode()) {
searchResults = newItems.clone() as ArrayList<SearchResult>
textToHighlight = highlightText
notifyDataSetChanged()
} else if (textToHighlight != highlightText) {
textToHighlight = highlightText
notifyDataSetChanged()
}
}
private fun setupView(view: View, searchResult: SearchResult) {
view.apply {
search_result_title.apply {
text = searchResult.title.highlightTextPart(textToHighlight, adjustedPrimaryColor)
setTextColor(textColor)
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 1.2f)
}
search_result_snippet.apply {
text = searchResult.snippet.highlightTextPart(textToHighlight, adjustedPrimaryColor)
setTextColor(textColor)
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 0.9f)
}
search_result_date.apply {
text = searchResult.date
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 0.8f)
}
SimpleContactsHelper(context).loadContactImage(searchResult.photoUri, search_result_image, searchResult.title)
}
}
override fun onViewRecycled(holder: ViewHolder) {
super.onViewRecycled(holder)
if (!activity.isDestroyed && !activity.isFinishing && holder.itemView.search_result_image != null) {
Glide.with(activity).clear(holder.itemView.search_result_image)
}
}
}

View file

@ -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
@ -42,8 +43,10 @@ import kotlinx.android.synthetic.main.item_thread_error.view.*
import kotlinx.android.synthetic.main.item_thread_sending.view.*
import kotlinx.android.synthetic.main.item_thread_success.view.*
class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
class ThreadAdapter(
activity: SimpleActivity, var messages: ArrayList<ThreadItem>, recyclerView: MyRecyclerView, fastScroller: FastScroller,
itemClick: (Any) -> Unit
) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
private val roundedCornersRadius = resources.getDimension(R.dimen.normal_margin).toInt()
private var fontSize = activity.getTextSize()
@ -134,17 +137,17 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
}
private fun copyToClipboard() {
val firstItem = getSelectedItems().first() as? Message ?: return
val firstItem = getSelectedItems().firstOrNull() as? Message ?: return
activity.copyToClipboard(firstItem.body)
}
private fun shareText() {
val firstItem = getSelectedItems().first() as? Message ?: return
val firstItem = getSelectedItems().firstOrNull() as? Message ?: return
activity.shareTextIntent(firstItem.body)
}
private fun selectText() {
val firstItem = getSelectedItems().first() as? Message ?: return
val firstItem = getSelectedItems().firstOrNull() as? Message ?: return
if (firstItem.body.trim().isNotEmpty()) {
SelectTextDialog(activity, firstItem.body)
}
@ -198,10 +201,11 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
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)
}
@ -224,7 +228,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
} else {
thread_message_sender_photo?.beGone()
val background = context.getAdjustedPrimaryColor()
thread_message_body.background.applyColorFilter(background.adjustAlpha(0.8f))
thread_message_body.background.applyColorFilter(background)
val contrastColor = background.getContrastColor()
thread_message_body.setTextColor(contrastColor)
@ -287,7 +291,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
val background = context.getAdjustedPrimaryColor()
val attachmentView = layoutInflater.inflate(R.layout.item_sent_unknown_attachment, null).apply {
thread_sent_attachment_label.apply {
this.background.applyColorFilter(background.adjustAlpha(0.8f))
this.background.applyColorFilter(background)
setTextColor(background.getContrastColor())
if (attachment.filename.isNotEmpty()) {
thread_sent_attachment_label.text = attachment.filename
@ -310,18 +314,20 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
private fun launchViewIntent(uri: Uri, mimetype: String, filename: String) {
Intent().apply {
action = Intent.ACTION_VIEW
setDataAndType(uri, mimetype)
setDataAndType(uri, mimetype.toLowerCase())
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)
}
}
}
@ -329,7 +335,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList<ThreadItem
private fun setupDateTime(view: View, dateTime: ThreadDateTime) {
view.apply {
thread_date_time.apply {
text = dateTime.date.formatDateOrTime(context, false)
text = dateTime.date.formatDateOrTime(context, false, false)
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
}
thread_date_time.setTextColor(textColor)

View file

@ -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)
@ -709,37 +712,41 @@ fun Context.showMessageNotification(address: String, body: String, threadId: Lon
val builder = NotificationCompat.Builder(this, NOTIFICATION_CHANNEL).apply {
when (config.notificationSetting) {
CONFIGURE_NAME_AND_MESSAGE -> {
this.setContentTitle(sender)
this.setLargeIcon(largeIcon)
this.setContentText(body)
setContentTitle(sender)
setLargeIcon(largeIcon)
setContentText(body)
}
CONFIGURE_NAME -> {
this.setContentTitle(sender)
this.setLargeIcon(largeIcon)
setContentTitle(sender)
setLargeIcon(largeIcon)
}
}
this.color = config.primaryColor
this.setSmallIcon(R.drawable.ic_messenger)
this.setStyle(NotificationCompat.BigTextStyle().setSummaryText(summaryText).bigText(body))
this.setContentIntent(pendingIntent)
this.priority = NotificationCompat.PRIORITY_MAX
this.setDefaults(Notification.DEFAULT_LIGHTS)
this.setCategory(Notification.CATEGORY_MESSAGE)
this.setAutoCancel(true)
this.setSound(soundUri, AudioManager.STREAM_NOTIFICATION)
color = getAdjustedPrimaryColor()
setSmallIcon(R.drawable.ic_messenger)
setStyle(NotificationCompat.BigTextStyle().setSummaryText(summaryText).bigText(body))
setContentIntent(pendingIntent)
priority = NotificationCompat.PRIORITY_MAX
setDefaults(Notification.DEFAULT_LIGHTS)
setCategory(Notification.CATEGORY_MESSAGE)
setAutoCancel(true)
setSound(soundUri, AudioManager.STREAM_NOTIFICATION)
}
if (replyAction != null && config.notificationSetting == CONFIGURE_NAME_AND_MESSAGE) {
builder.addAction(replyAction)
}
builder.addAction(R.drawable.ic_check_vector, getString(R.string.mark_as_read), markAsReadPendingIntent)
.setChannelId(NOTIFICATION_CHANNEL)
notificationManager.notify(threadId.hashCode(), builder.build())
}
fun Context.getConfigurationText(type: Int) = getString(when (type) {
CONFIGURE_NAME_AND_MESSAGE -> R.string.configure_name_and_message
CONFIGURE_NAME -> R.string.configure_name
else -> R.string.configure_no_details
})
fun Context.getConfigurationText(type: Int) = getString(
when (type) {
CONFIGURE_NAME_AND_MESSAGE -> R.string.sender_and_message
CONFIGURE_NAME -> R.string.sender_only
else -> R.string.nothing
}
)

View file

@ -9,6 +9,7 @@ const val THREAD_TEXT = "thread_text"
const val THREAD_NUMBER = "thread_number"
const val THREAD_ATTACHMENT_URI = "thread_attachment_uri"
const val THREAD_ATTACHMENT_URIS = "thread_attachment_uris"
const val SEARCHED_MESSAGE_ID = "searched_message_id"
const val USE_SIM_ID_PREFIX = "use_sim_id_"
const val NOTIFICATION_CHANNEL = "simple_sms_messenger"
const val SHOW_CHARACTER_COUNTER = "show_character_counter"

View file

@ -17,6 +17,9 @@ interface ConversationsDao {
@Query("SELECT * FROM conversations WHERE read = 0")
fun getUnreadConversations(): List<Conversation>
@Query("SELECT * FROM conversations WHERE title LIKE :text")
fun getConversationsWithText(text: String): List<Conversation>
@Query("UPDATE conversations SET read = 1 WHERE thread_id = :threadId")
fun markRead(threadId: Long)

View file

@ -23,6 +23,9 @@ interface MessagesDao {
@Query("SELECT * FROM messages WHERE thread_id = :threadId")
fun getThreadMessages(threadId: Long): List<Message>
@Query("SELECT * FROM messages WHERE body LIKE :text")
fun getMessagesWithText(text: String): List<Message>
@Query("UPDATE messages SET read = 1 WHERE id = :id")
fun markRead(id: Long)

View file

@ -0,0 +1,3 @@
package com.simplemobiletools.smsmessenger.models
data class SearchResult(val messageId: Long, val title: String, val snippet: String, val date: String, val threadId: Long, var photoUri: String)

View file

@ -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)

View file

@ -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()
}
}
}

View file

@ -1,20 +1,20 @@
package com.simplemobiletools.smsmessenger.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import com.klinker.android.send_message.DeliveredReceiver
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.smsmessenger.extensions.messagesDB
import com.simplemobiletools.smsmessenger.extensions.updateMessageType
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
class SmsStatusDeliveredReceiver : BroadcastReceiver() {
class SmsStatusDeliveredReceiver : DeliveredReceiver() {
override fun onReceive(context: Context, intent: Intent) {
override fun onMessageStatusUpdated(context: Context, intent: Intent, receiverResultCode: Int) {
if (intent.extras?.containsKey("message_uri") == true) {
val uri = Uri.parse(intent.getStringExtra("message_uri"))
val messageId = uri?.lastPathSegment?.toLong() ?: 0L

View file

@ -5,7 +5,6 @@ import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
@ -16,6 +15,8 @@ import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import androidx.core.app.NotificationCompat
import com.klinker.android.send_message.SentReceiver
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
import com.simplemobiletools.commons.extensions.getMyContactsCursor
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
@ -27,9 +28,9 @@ import com.simplemobiletools.smsmessenger.helpers.NOTIFICATION_CHANNEL
import com.simplemobiletools.smsmessenger.helpers.THREAD_ID
import com.simplemobiletools.smsmessenger.helpers.refreshMessages
class SmsStatusSentReceiver : BroadcastReceiver() {
class SmsStatusSentReceiver : SentReceiver() {
override fun onReceive(context: Context, intent: Intent) {
override fun onMessageStatusUpdated(context: Context, intent: Intent, receiverResultCode: Int) {
if (intent.extras?.containsKey("message_uri") == true) {
val uri = Uri.parse(intent.getStringExtra("message_uri"))
val messageId = uri?.lastPathSegment?.toLong() ?: 0L
@ -40,6 +41,7 @@ class SmsStatusSentReceiver : BroadcastReceiver() {
} else {
Telephony.Sms.MESSAGE_TYPE_OUTBOX
}
context.updateMessageType(messageId, type)
context.messagesDB.updateType(messageId, type)
refreshMessages()
@ -49,7 +51,7 @@ class SmsStatusSentReceiver : BroadcastReceiver() {
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)
@ -92,7 +94,7 @@ class SmsStatusSentReceiver : BroadcastReceiver() {
val builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
.setContentTitle(context.getString(R.string.message_not_sent_short))
.setContentText(summaryText)
.setColor(context.config.primaryColor)
.setColor(context.getAdjustedPrimaryColor())
.setSmallIcon(R.drawable.ic_messenger)
.setLargeIcon(largeIcon)
.setStyle(NotificationCompat.BigTextStyle().bigText(summaryText))

View file

@ -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) {
}

View file

@ -1,9 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/selected_contact_bg">
<shape android:shape="rectangle">
<corners android:radius="@dimen/normal_margin" />
<corners android:radius="@dimen/normal_margin" />
<solid android:color="@color/activated_item_foreground" />
<solid android:color="@color/md_grey_white" />
</shape>
</shape>
</item>
</layer-list>

View file

@ -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" />

View file

@ -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" />

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/search_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/search_placeholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/activity_margin"
android:alpha="0.8"
android:gravity="center"
android:paddingStart="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"
android:text="@string/no_items_found"
android:textSize="@dimen/bigger_text_size"
android:textStyle="italic" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/search_placeholder_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/search_placeholder"
android:layout_centerHorizontal="true"
android:alpha="0.8"
android:gravity="center"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/medium_margin"
android:text="@string/type_2_characters"
android:textSize="@dimen/bigger_text_size"
android:textStyle="italic" />
<com.simplemobiletools.commons.views.MyRecyclerView
android:id="@+id/search_results_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbars="vertical"
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
</RelativeLayout>

View file

@ -53,6 +53,27 @@
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_customize_notifications_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:paddingLeft="@dimen/normal_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
android:paddingBottom="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_customize_notifications_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingStart="@dimen/medium_margin"
android:text="@string/customize_notifications" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_manage_blocked_numbers_holder"
android:layout_width="match_parent"

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/search_result_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/small_margin"
android:layout_marginBottom="@dimen/small_margin"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/normal_margin">
<ImageView
android:id="@+id/search_result_image"
android:layout_width="@dimen/normal_icon_size"
android:layout_height="@dimen/normal_icon_size"
android:layout_marginEnd="@dimen/normal_margin" />
<TextView
android:id="@+id/search_result_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toStartOf="@+id/search_result_date"
android:layout_toEndOf="@+id/search_result_image"
android:ellipsize="end"
android:maxLines="1"
android:paddingEnd="@dimen/activity_margin"
android:textSize="@dimen/big_text_size"
tools:text="John" />
<TextView
android:id="@+id/search_result_snippet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/search_result_title"
android:layout_toEndOf="@+id/search_result_image"
android:alpha="0.7"
android:ellipsize="end"
android:maxLines="1"
android:paddingEnd="@dimen/activity_margin"
android:textSize="@dimen/big_text_size"
tools:text="Hey buddy!" />
<TextView
android:id="@+id/search_result_date"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignTop="@+id/search_result_title"
android:layout_alignBottom="@+id/search_result_title"
android:layout_alignParentEnd="true"
android:layout_marginTop="@dimen/tiny_margin"
android:alpha="0.7"
android:gravity="center_vertical"
android:textSize="@dimen/smaller_text_size"
tools:text="08/02/2021" />
</RelativeLayout>

View file

@ -3,8 +3,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/suggested_contact_holder"
android:layout_width="wrap_content"
android:background="?selectableItemBackground"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="?selectableItemBackground">
<ImageView
android:id="@+id/suggested_contact_image"

View file

@ -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"

View file

@ -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"

View file

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/ic_search_vector"
android:title="@string/search"
app:showAsAction="always" />
<item
android:id="@+id/settings"
android:title="@string/settings"

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/ic_search_vector"
android:title="@string/search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|always" />
</menu>

View file

@ -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

View 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>

View file

@ -0,0 +1,82 @@
<resources>
<string name="app_name">Enkel SMS Beskeder</string>
<string name="app_launcher_name">Beskeder</string>
<string name="type_a_message">Skriv en besked…</string>
<string name="message_not_sent_short">Beskeden blev ikke sendt</string>
<string name="message_not_sent_touch_retry">Blev ikke sendt, tryk for at gensende</string>
<string name="message_sending_error">Din besked til \'%s\' blev ikke sendt</string>
<string name="add_person">Tilføj Person</string>
<string name="attachment">Vedhæftning</string>
<string name="no_conversations_found">Ingen gemte samtaler er fundet</string>
<string name="start_conversation">Start en samtale</string>
<string name="reply">Svar</string>
<string name="show_character_counter">Vis en karaktertæller ved skrivning af beskeder</string>
<string name="loading_messages">Henter beskeder…</string>
<string name="no_reply_support">Afsender understøtter ikke svar</string>
<string name="draft">Udkast</string>
<string name="sending">Sender…</string>
<string name="export_messages">Eksporter beskeder</string>
<string name="import_messages">Importer beskeder</string>
<!-- New conversation -->
<string name="new_conversation">Ny Samtale</string>
<string name="add_contact_or_number">Tilføj kontakt eller nummer…</string>
<string name="suggestions">Forslag</string>
<!-- Notifications -->
<string name="channel_received_sms">Modtag SMS</string>
<string name="new_message">Ny Besked</string>
<string name="mark_as_read">Marker som læst</string>
<string name="mark_as_unread">Marker som ulæst</string>
<!-- Confirmation dialog -->
<string name="delete_whole_conversation_confirmation">Er du sikker på, at du vil slette alle beskeder i denne samtale?</string>
<!-- Are you sure you want to delete 5 conversations? -->
<plurals name="delete_conversations">
<item quantity="one">%d samtale</item>
<item quantity="other">%d samtaler</item>
</plurals>
<!-- Are you sure you want to delete 5 messages? -->
<plurals name="delete_messages">
<item quantity="one">%d besked</item>
<item quantity="other">%d beskeder</item>
</plurals>
<!-- FAQ -->
<string name="faq_1_title">Hvorfor kræver appen adgang til internettet?</string>
<string name="faq_1_text">Desværre er det nødvendigt for at sende MMS-vedhæftede filer. Ikke at kunne være i stand til at sende MMS ville være en virkelig stor ulempe i forhold til andre apps, så vi besluttede at gå denne vej.
Men som normalt er der ingen annoncer, sporing eller analyse overhovedet, internettet bruges kun til at sende 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 beskeder - Administrer dine smser nemt</string>
<!-- Short description has to have max 80 characters -->
<string name="app_short_description">En nem og hurtig måde at administrere SMS og MMS-beskeder uden annoncer på.</string>
<string name="app_long_description">
En fantastisk måde at holde kontakten med dine pårørende på, ved at sende både SMS- og MMS-beskeder. Appen håndterer også gruppemeddelelser korrekt, ligesom at blokere numre fra Android 7+.
Appen tilbyder mange datoformater at vælge imellem, så du kan føle dig godt tilpas ved at bruge den. Du kan også skifte mellem 12 og 24 timers tidsformat.
Det har en virkelig lille appstørrelse sammenlignet med konkurrencen, hvilket gør det virkelig hurtigt at downloade.
Den leveres med materialedesign og mørkt tema som standard og giver god brugeroplevelse til nem brug. Manglen på internetadgang giver dig mere privatliv, sikkerhed og stabilitet end andre apps.
Indeholder ingen annoncer eller unødvendige tilladelser. Det er fuldstændig opensource, giver farver, der kan tilpasses.
<b>Se hele pakken med enkle værktøjer her:</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>

View file

@ -2,19 +2,21 @@
<string name="app_name">Schlichter SMS Messenger</string>
<string name="app_launcher_name">SMS Messenger</string>
<string name="type_a_message">Schreibe eine Nachricht…</string>
<string name="message_not_sent_short">Message not sent</string>
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
<string name="message_not_sent_short">Nachricht nicht versendet.</string>
<string name="message_not_sent_touch_retry">Nachricht nicht versendet. Berühre, um es erneut zu versuchen.</string>
<string name="message_sending_error">Deine Nachricht am \'%s\' wurde nicht gesendet.</string>
<string name="add_person">Person hinzufügen</string>
<string name="attachment">Anhang</string>
<string name="no_conversations_found">Keine gespeicherten Chats gefunden</string>
<string name="start_conversation">Neuen Chat beginnen</string>
<string name="reply">Antworten</string>
<string name="show_character_counter">Show a character counter at writing messages</string>
<string name="loading_messages">Loading messages…</string>
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="show_character_counter">Zeige einen Zeichenzähler während dem Schreiben von Nachrichten.</string>
<string name="loading_messages">Lade Nachrichten…</string>
<string name="no_reply_support">Der Absender unterstützt keine Antworten.</string>
<string name="draft">Entwurf</string>
<string name="sending">Sende…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Neuer Chat</string>
@ -49,21 +51,21 @@
<!-- 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 - Manage messages easily</string>
<string name="app_title">Simple SMS Messenger-Nachrichten simple verwalten</string>
<!-- Short description has to have max 80 characters -->
<string name="app_short_description">An easy and quick way of managing SMS and MMS messages without ads.</string>
<string name="app_short_description">Eine einfache und schnelle Art SMS &amp; MMS ohne Werbung zu verwalten.</string>
<string name="app_long_description">
A great way to stay in touch with your relatives, by sending both SMS and MMS messages. The app properly handles group messaging too, just like blocking numbers from Android 7+.
In tolle Möglichkeit mit deinen Verwandten in Kontakt zu bleiben, indem sowohl SMS als auch MMS Nachrichten gesendet werden. Die App handhabt auch Gruppennachrichten gut, genauso wie das Blockieren von Nummern ab Android 7+.
It offers many date formats to choose from, to make you feel comfortable at using it. You can toggle between 12 and 24 hours time format too.
Damit die Nutzung sich vertrauter und komfortabler anfühlt, kannst du das Datumsformat in verschiedenen Arten anpassen. Zudem kannst du zwischen 12 und 24 Stunden Format auswählen.
Im Vergleich zur Konkurrenz ist die Appgröße sehr klein, wodurch es sehr schnell heruntergeladen ist.
It has a really tiny app size compared to the competition, making it really fast to download.
Es kommt standardmäßig mit einem material design und Dunkelmodus, was für ein großartiges Nutzererlebnis und leichte Nutzbarkeit sorgt. Da es keine Internetverbindung verwendet, bietet diese App mehr Datenschutz, Sicherheit und Stabilität als andere Apps.
It comes with material design and dark theme by default, provides great user experience for easy usage. The lack of internet access gives you more privacy, security and stability than other apps.
Beinhaltet keine Werbung oder unnötige Berechtigungen. Es ist komplett opensource, und bietet anpassbare Farben.
Contains no ads or unnecessary permissions. It is fully opensource, provides customizable colors.
<b>Check out the full suite of Simple Tools here:</b>
<b>Entdecke alle Simple Tools hier:</b>
https://www.simplemobiletools.com
<b>Facebook:</b>

View file

@ -2,9 +2,9 @@
<string name="app_name">Απλός SMS Messenger</string>
<string name="app_launcher_name">SMS Messenger</string>
<string name="type_a_message">Πληκτρολογήστε ένα μήνυμα…</string>
<string name="message_not_sent_short">Message not sent</string>
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
<string name="message_not_sent_short">Το μήνυμα δεν εστάλη</string>
<string name="message_not_sent_touch_retry">Δεν εστάλη. Αγγίξτε για επανάληψη.</string>
<string name="message_sending_error">Το μήνυμά σας προς το \'%s\' δεν έχει αποσταλεί</string>
<string name="add_person">Προσθήκη ατόμου</string>
<string name="attachment">Συνημμένο</string>
<string name="no_conversations_found">Δεν βρέθηκαν αποθηκευμένες συνομιλίες</string>
@ -12,9 +12,11 @@
<string name="reply">Απάντηση</string>
<string name="show_character_counter">Εμφάνιση μετρητή χαρακτήρων κατά την πληκτρολόγηση μηνυμάτων</string>
<string name="loading_messages">Φόρτωση μηνυμάτων…</string>
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="no_reply_support">Ο αποστολέας δεν υποστηρίζει απαντήσεις</string>
<string name="draft">Πρόχειρο</string>
<string name="sending">Γίνεται αποστολή…</string>
<string name="export_messages">Εξαγωγή μηνυμάτων</string>
<string name="import_messages">Εισαγωγή μηνυμάτων</string>
<!-- New conversation -->
<string name="new_conversation">Νέα συνομιλία</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Nueva conversación</string>

View file

@ -0,0 +1,82 @@
<resources>
<string name="app_name">Simple SMS Messenger</string>
<string name="app_launcher_name">Viestit</string>
<string name="type_a_message">Lähetä viesti…</string>
<string name="message_not_sent_short">Viestiä ei lähetetty</string>
<string name="message_not_sent_touch_retry">Ei lähetetty. Yritä uudelleen koskemalla.</string>
<string name="message_sending_error">Viestiäsi henkilölle \'%s\' ei lähetetty.</string>
<string name="add_person">Lisää henkilö</string>
<string name="attachment">Liite</string>
<string name="no_conversations_found">Tallennettuja keskusteluja ei löytyny</string>
<string name="start_conversation">Aloita keskustelu</string>
<string name="reply">Vastaa</string>
<string name="show_character_counter">Näytä merkkimäärä kirjoittaessasi viestejä</string>
<string name="loading_messages">Ladataan viestejä…</string>
<string name="no_reply_support">Lähettäjä ei tue vastauksia</string>
<string name="draft">Luonnos</string>
<string name="sending">Lähetetään…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Uusi keskustelu</string>
<string name="add_contact_or_number">Lisää yhteystieto tai numero…</string>
<string name="suggestions">Ehdotuksia</string>
<!-- Notifications -->
<string name="channel_received_sms">Vastaanotettu tekstiviesti</string>
<string name="new_message">Uusi viesti</string>
<string name="mark_as_read">Merkitse luetuksi</string>
<string name="mark_as_unread">Merkitse lukemattomaksi</string>
<!-- Confirmation dialog -->
<string name="delete_whole_conversation_confirmation">Haluatko varmasti poistaa kaikki tämän keskustelun viestit?</string>
<!-- Are you sure you want to delete 5 conversations? -->
<plurals name="delete_conversations">
<item quantity="one">yhden keskustelun</item>
<item quantity="other">%d keskustelua</item>
</plurals>
<!-- Are you sure you want to delete 5 messages? -->
<plurals name="delete_messages">
<item quantity="one">yhden viestin</item>
<item quantity="other">%d viestiä</item>
</plurals>
<!-- FAQ -->
<string name="faq_1_title">Miksi sovellus vaatii Internet-yhteyden?</string>
<string name="faq_1_text">Valitettavasti sitä tarvitaan multimediaviestin-liitteiden lähettämiseen. Multimediaviestien lähettämättä jättäminen olisi todella valtava haitta muihin sovelluksiin verrattuna, joten päätimme mennä tällä tavalla.
Kuten yleensä, mainoksia, seurantaa tai analytiikkaa ei kuitenkaan ole, iternetiä käytetään vain multimediaviestien lähettämiseen.</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 - Manage messages easily</string>
<!-- Short description has to have max 80 characters -->
<string name="app_short_description">An easy and quick way of managing SMS and MMS messages without ads.</string>
<string name="app_long_description">
A great way to stay in touch with your relatives, by sending both SMS and MMS messages. The app properly handles group messaging too, just like blocking numbers from Android 7+.
It offers many date formats to choose from, to make you feel comfortable at using it. You can toggle between 12 and 24 hours time format too.
It has a really tiny app size compared to the competition, making it really fast to download.
It comes with material design and dark theme by default, provides great user experience for easy usage. The lack of internet access gives you more privacy, security and stability than other apps.
Contains no ads or unnecessary permissions. It is fully opensource, provides customizable colors.
<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>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Nouvelle conversation</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Percakapan baru</string>

View file

@ -0,0 +1,81 @@
<resources>
<string name="app_name">SMS Messenger</string>
<string name="app_launcher_name">SMS Messenger</string>
<string name="type_a_message">Componi messaggio</string>
<string name="message_not_sent_short">Messaggio non inviato</string>
<string name="message_not_sent_touch_retry">Non inviato. Tocca per riprovare</string>
<string name="message_sending_error">Il tuo messaggio a \'%s\' non è stato inviato</string>
<string name="add_person">Aggiungi persona</string>
<string name="attachment">Allegato</string>
<string name="no_conversations_found">Nessuna conversazione trovata</string>
<string name="start_conversation">Inizia conversazione</string>
<string name="reply">Rispondi</string>
<string name="show_character_counter">Mostra contatore caratteri</string>
<string name="loading_messages">Caricamento messaggi…</string>
<string name="no_reply_support">Il mittente non accetta risposte</string>
<string name="draft">Bozza</string>
<string name="sending">Invio…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Nuova conversazione</string>
<string name="add_contact_or_number">Inserisci contatto o numero…</string>
<string name="suggestions">Suggerimenti</string>
<!-- Notifications -->
<string name="channel_received_sms">SMS ricevuto</string>
<string name="new_message">Nuovo messaggio</string>
<string name="mark_as_read">Letto</string>
<string name="mark_as_unread">Non letto</string>
<!-- Confirmation dialog -->
<string name="delete_whole_conversation_confirmation">Vuoi cancellare l\'intera conversazione?</string>
<!-- Are you sure you want to delete 5 conversations? -->
<plurals name="delete_conversations">
<item quantity="one">%d conversazione</item>
<item quantity="other">%d conversazioni</item>
</plurals>
<!-- Are you sure you want to delete 5 messages? -->
<plurals name="delete_messages">
<item quantity="one">%d messaggio</item>
<item quantity="other">%d messaggi</item>
</plurals>
<!-- FAQ -->
<string name="faq_1_title">Perché l\'applicazione richiede l\'accesso ad internet?</string>
<string name="faq_1_text">Purtroppo è necessario per poter inviare gli allegati degli MMS. Non essere in grado di inviare gli MMS sarebbe un grosso svantaggio in confronto ad altre applicazioni, quindi abbiamo deciso di intraprendere questa strada.
Ad ogni modo, come sempre, non ci sono pubblicità o tracciamenti, internet è utilizzato soltanto per l\'invio degli 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 - Manage messages easily</string>
<!-- Short description has to have max 80 characters -->
<string name="app_short_description">An easy and quick way of managing SMS and MMS messages without ads.</string>
<string name="app_long_description">
A great way to stay in touch with your relatives, by sending both SMS and MMS messages. The app properly handles group messaging too, just like blocking numbers from Android 7+.
It offers many date formats to choose from, to make you feel comfortable at using it. You can toggle between 12 and 24 hours time format too.
It has a really tiny app size compared to the competition, making it really fast to download.
It comes with material design and dark theme by default, provides great user experience for easy usage. The lack of internet access gives you more privacy, security and stability than other apps.
Neturi reklamų ar nereikalingų leidimų. Programėlė visiškai atviro kodo, yra galimybė keisti spalvas.
<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>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">新しい会話</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Naujas pokalbis</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">പുതിയ സംഭാഷണം</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Afzender ondersteunt geen antwoorden</string>
<string name="draft">Concept</string>
<string name="sending">Versturen…</string>
<string name="export_messages">Berichten exporteren</string>
<string name="import_messages">Berichten importeren</string>
<!-- New conversation -->
<string name="new_conversation">Nieuw gesprek</string>
@ -32,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>

View 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>

View file

@ -2,19 +2,21 @@
<string name="app_name">Simple SMS Messenger</string>
<string name="app_launcher_name">SMS Messenger</string>
<string name="type_a_message">Escrever uma mensagem…</string>
<string name="message_not_sent_short">Message not sent</string>
<string name="message_not_sent_touch_retry">Not sent. Touch to retry.</string>
<string name="message_sending_error">Your message to \'%s\' has not been sent</string>
<string name="message_not_sent_short">Mensagem não enviada</string>
<string name="message_not_sent_touch_retry">Não enviada. Toque para tentar novamente.</string>
<string name="message_sending_error">A mensagem enviada para \'%s\' não foi enviada.</string>
<string name="add_person">Adicionar pessoa</string>
<string name="attachment">Anexo</string>
<string name="no_conversations_found">Não foram encontradas conversas</string>
<string name="start_conversation">Iniciar uma conversa</string>
<string name="reply">Responder</string>
<string name="show_character_counter">Mostrar número de caracteres ao escrever a mensagem</string>
<string name="loading_messages">Loading messages…</string>
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="loading_messages">A carregar mensagens…</string>
<string name="no_reply_support">O remetente não aceita respostas</string>
<string name="draft">Rascunho</string>
<string name="sending">A enviar…</string>
<string name="export_messages">Exportar mensagens</string>
<string name="import_messages">Importar mensagens</string>
<!-- New conversation -->
<string name="new_conversation">Nova conversa</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Отправитель не поддерживает ответы</string>
<string name="draft">Черновик</string>
<string name="sending">Отправка…</string>
<string name="export_messages">Экспорт сообщений</string>
<string name="import_messages">Импорт сообщений</string>
<!-- New conversation -->
<string name="new_conversation">Новая переписка</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Koncept</string>
<string name="sending">Odosiela sa…</string>
<string name="export_messages">Exportovať správy</string>
<string name="import_messages">Importovať správy</string>
<!-- New conversation -->
<string name="new_conversation">Nová konverzácia</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Yeni görüşme</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">Нове листування</string>

View file

@ -15,6 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">新的对话</string>

View file

@ -15,12 +15,8 @@
<string name="no_reply_support">Sender doesn\'t support replies</string>
<string name="draft">Draft</string>
<string name="sending">Sending…</string>
<string name="configure_notification">Configure Notification</string>
<!-- Configuration Settings -->
<string name="configure_name_and_message">Name and Message</string>
<string name="configure_name">Name</string>
<string name="configure_no_details">No Details</string>
<string name="export_messages">Export messages</string>
<string name="import_messages">Import messages</string>
<!-- New conversation -->
<string name="new_conversation">New conversation</string>
@ -48,6 +44,11 @@
<item quantity="other">%d messages</item>
</plurals>
<!-- Settings -->
<string name="lock_screen_visibility">Lock screen notification visibility</string>
<string name="sender_and_message">Sender and message</string>
<string name="sender_only">Sender only</string>
<!-- FAQ -->
<string name="faq_1_title">Why does the app require access to the internet?</string>
<string name="faq_1_text">Sadly it is needed for sending MMS attachments. Not being able to send MMS would be a really huge disadvantage compared to other apps, so we decided to go this way.

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<searchable
xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search"
android:label="@string/app_name"/>

View file

@ -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.21'
ext.kotlin_version = '1.5.21'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.1'
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

View file

@ -0,0 +1,3 @@
* Fixed a glitch with "Sending..." stuck at messages
* Allow selecting a phone numbers at contacts with multiple ones
* Some translation and stability improvements

View file

@ -0,0 +1,3 @@
* Fixed a glitch with inability to send messages in empty conversations
* Adding a settings item for quickly getting into notification settings
* Some stability and translation improvements

View file

@ -0,0 +1 @@
* Adding some stability and translation improvements

View file

@ -0,0 +1,3 @@
* Added Search
* Added a White theme with special handling
* Some stability and translation improvements

View file

@ -0,0 +1,3 @@
* Improved search
* Properly handle sending messages from notification Reply action
* Some design, stability and translation improvements

View file

@ -0,0 +1,2 @@
* Fixed an error message wrongly popping up in some cases
* Some stabiliy and translation improvements

View file

@ -0,0 +1,2 @@
* Fixed a glitch with current conversation not being updated correctly at incoming messages
* Couple other stability, translation and bugfixes

View file

@ -0,0 +1 @@
* Adding some UX, stability and translation improvements

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View file

@ -0,0 +1,18 @@
Świetny sposób na utrzymywanie kontaktu z bliskimi przez 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

View file

@ -0,0 +1 @@
Łatwy i szybki sposób zarządzania wiadomościami SMS i MMS bez reklam.

View file

@ -0,0 +1 @@
Proste wiadomości SMS - Łatwo zarządzaj SMS-ami

View file

@ -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