From 08c1b21bad0e915fbb2ff116bbb955889d7b5699 Mon Sep 17 00:00:00 2001 From: Spitap Date: Thu, 3 Mar 2022 09:35:33 +0100 Subject: [PATCH 1/8] Securing export backup, started work on decrypting backups --- app/src/main/AndroidManifest.xml | 16 ++- .../smsmessenger/activities/MainActivity.kt | 57 +++++---- .../dialogs/ExportMessagesDialog.kt | 4 +- .../dialogs/ImportMessagesDialog.kt | 13 ++- .../smsmessenger/helpers/Config.kt | 8 ++ .../smsmessenger/helpers/Constants.kt | 8 ++ .../smsmessenger/helpers/MessagesExporter.kt | 108 ++++++++++++------ .../smsmessenger/helpers/MessagesImporter.kt | 83 ++++++++++++-- .../res/layout/dialog_export_messages.xml | 18 +++ .../res/layout/dialog_import_messages.xml | 19 +++ app/src/main/res/values/strings.xml | 2 + 11 files changed, 263 insertions(+), 73 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dcd106d78..6084a8f8e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,7 +41,21 @@ android:name=".activities.SplashActivity" android:theme="@style/SplashTheme" /> - + + + + + + + + + + + + + + + Intent(Intent.ACTION_CREATE_DOCUMENT).apply { - type = EXPORT_MIME_TYPE + type = if (config.exportBackupPassword != "") EXPORT_SECURE_MIME_TYPE else EXPORT_MIME_TYPE putExtra(Intent.EXTRA_TITLE, file.name) addCategory(Intent.CATEGORY_OPENABLE) startActivityForResult(this, PICK_EXPORT_FILE_INTENT) @@ -404,7 +403,7 @@ class MainActivity : SimpleActivity() { if (isQPlus()) { Intent(Intent.ACTION_GET_CONTENT).apply { addCategory(Intent.CATEGORY_OPENABLE) - type = EXPORT_MIME_TYPE + type = "*/*" startActivityForResult(this, PICK_IMPORT_SOURCE_INTENT) } } else { @@ -418,37 +417,37 @@ class MainActivity : SimpleActivity() { private fun importEvents() { FilePickerDialog(this) { - showImportEventsDialog(it) + showImportEventsDialog(it, null) } } - private fun showImportEventsDialog(path: String) { - ImportMessagesDialog(this, path) + private fun showImportEventsDialog(path: String?, file: DocumentFile?) { + ImportMessagesDialog(this, path, file) } - private fun tryImportMessagesFromFile(uri: Uri) { - when (uri.scheme) { - "file" -> showImportEventsDialog(uri.path!!) - "content" -> { - val tempFile = getTempFile("messages", "backup.json") - if (tempFile == null) { - toast(R.string.unknown_error_occurred) - return - } + private fun tryImportMessagesFromFile(intentData : Intent) { + val uri = intentData.data - try { - val inputStream = contentResolver.openInputStream(uri) - val out = FileOutputStream(tempFile) - inputStream!!.copyTo(out) - showImportEventsDialog(tempFile.absolutePath) - } catch (e: Exception) { - showErrorToast(e) + if (uri != null) + try { + val df = DocumentFile.fromSingleUri(this, uri) + if (df != null) { + val ext : String? = df.name?.substringAfterLast(".","") + if (ext == "sec" || ext == "json") { + showImportEventsDialog(null, df) + return + } + else + { + throw Exception("Wrong filetype") + } } - } - else -> toast(R.string.invalid_file_format) + } catch (ex: Exception) { + //TODO } } + @Subscribe(threadMode = ThreadMode.MAIN) fun refreshMessages(event: Events.RefreshMessages) { initMessenger() diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ExportMessagesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ExportMessagesDialog.kt index 672e09f43..6ed3d042e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ExportMessagesDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ExportMessagesDialog.kt @@ -8,6 +8,7 @@ import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.activities.SimpleActivity import com.simplemobiletools.smsmessenger.extensions.config import com.simplemobiletools.smsmessenger.helpers.EXPORT_FILE_EXT +import com.simplemobiletools.smsmessenger.helpers.EXPORT_SECURE_FILE_EXT import kotlinx.android.synthetic.main.dialog_export_messages.view.* import java.io.File @@ -51,7 +52,8 @@ class ExportMessagesDialog( when { filename.isEmpty() -> activity.toast(R.string.empty_name) filename.isAValidFilename() -> { - val file = File(realPath, "$filename$EXPORT_FILE_EXT") + config.exportBackupPassword = view.export_messages_password.value //We need to get this early to set proper extension + val file = if (config.exportBackupPassword == "") File(realPath, "$filename$EXPORT_FILE_EXT") else File(realPath, "$filename$EXPORT_SECURE_FILE_EXT") if (!hidePath && file.exists()) { activity.toast(R.string.name_taken) return@setOnClickListener diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ImportMessagesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ImportMessagesDialog.kt index 54df49be3..5f98e7116 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ImportMessagesDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ImportMessagesDialog.kt @@ -1,9 +1,13 @@ package com.simplemobiletools.smsmessenger.dialogs +import android.util.Log import android.view.ViewGroup import androidx.appcompat.app.AlertDialog +import androidx.documentfile.provider.DocumentFile +import com.simplemobiletools.commons.extensions.beGone import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.extensions.value import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.activities.SimpleActivity @@ -15,7 +19,8 @@ import kotlinx.android.synthetic.main.dialog_import_messages.view.* class ImportMessagesDialog( private val activity: SimpleActivity, - private val path: String, + private val path: String?, + private var file: DocumentFile?, ) { private val config = activity.config @@ -26,6 +31,11 @@ class ImportMessagesDialog( import_sms_checkbox.isChecked = config.importSms import_mms_checkbox.isChecked = config.importMms } + if (path?.substringAfterLast(".", "") != "sec" || file.name.replaceAfterLast(".","") != "sec") + { + view.import_messages_password.beGone() + view.import_messages_password_label.beGone() + } AlertDialog.Builder(activity) .setPositiveButton(R.string.ok, null) @@ -46,6 +56,7 @@ class ImportMessagesDialog( activity.toast(R.string.importing) config.importSms = view.import_sms_checkbox.isChecked config.importMms = view.import_mms_checkbox.isChecked + config.exportBackupPassword = view.import_messages_password.value ensureBackgroundThread { MessagesImporter(activity).importMessages(path) { handleParseResult(it) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt index 79d4c3983..9b3494a48 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt @@ -64,6 +64,10 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getString(LAST_EXPORT_PATH, "")!! set(lastExportPath) = prefs.edit().putString(LAST_EXPORT_PATH, lastExportPath).apply() + var exportBackupPassword: String + get() = prefs.getString(EXPORT_BACKUP_PASSWORD, "")!! + set(exportBackupPassword) = prefs.edit().putString(EXPORT_BACKUP_PASSWORD, exportBackupPassword).apply() + var exportSms: Boolean get() = prefs.getBoolean(EXPORT_SMS, true) set(exportSms) = prefs.edit().putBoolean(EXPORT_SMS, exportSms).apply() @@ -72,6 +76,10 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getBoolean(EXPORT_MMS, true) set(exportMms) = prefs.edit().putBoolean(EXPORT_MMS, exportMms).apply() + var importBackupPassword: String + get() = prefs.getString(IMPORT_BACKUP_PASSWORD, "")!! + set(importBackupPassword) = prefs.edit().putString(IMPORT_BACKUP_PASSWORD, importBackupPassword).apply() + var importSms: Boolean get() = prefs.getBoolean(IMPORT_SMS, true) set(importSms) = prefs.edit().putBoolean(IMPORT_SMS, importSms).apply() diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt index 8359b33b1..a26421386 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt @@ -20,14 +20,22 @@ const val SEND_LONG_MESSAGE_MMS = "send_long_message_mms" const val MMS_FILE_SIZE_LIMIT = "mms_file_size_limit" const val PINNED_CONVERSATIONS = "pinned_conversations" const val LAST_EXPORT_PATH = "last_export_path" +const val EXPORT_BACKUP_PASSWORD = "export_backup_password" const val EXPORT_SMS = "export_sms" const val EXPORT_MMS = "export_mms" const val EXPORT_MIME_TYPE = "application/json" +const val EXPORT_SECURE_MIME_TYPE = "application/sec" const val EXPORT_FILE_EXT = ".json" +const val EXPORT_SECURE_FILE_EXT = ".sec" +const val IMPORT_BACKUP_PASSWORD = "import_backup_password" const val IMPORT_SMS = "import_sms" const val IMPORT_MMS = "import_mms" const val WAS_DB_CLEARED = "was_db_cleared" +//Secure Backup Cipher Parameters +const val KEY_ITERATIONS = 65536 +const val KEY_LENGTH = 256 + private const val PATH = "com.simplemobiletools.smsmessenger.action." const val MARK_AS_READ = PATH + "mark_as_read" const val REPLY = PATH + "reply" diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt index 49c2d4b61..1cea5a228 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt @@ -1,12 +1,22 @@ package com.simplemobiletools.smsmessenger.helpers import android.content.Context +import android.util.Log import com.google.gson.Gson -import com.google.gson.stream.JsonWriter import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.smsmessenger.extensions.config import com.simplemobiletools.smsmessenger.extensions.getConversationIds +import org.json.JSONArray +import org.json.JSONObject import java.io.OutputStream +import java.security.SecureRandom +import java.security.spec.KeySpec +import javax.crypto.Cipher +import javax.crypto.CipherOutputStream +import javax.crypto.SecretKey +import javax.crypto.SecretKeyFactory +import javax.crypto.spec.PBEKeySpec + class MessagesExporter(private val context: Context) { enum class ExportResult { @@ -23,45 +33,75 @@ class MessagesExporter(private val context: Context) { callback.invoke(ExportResult.EXPORT_FAIL) return@ensureBackgroundThread } - val writer = JsonWriter(outputStream.bufferedWriter()) - writer.use { - try { - var written = 0 - writer.beginArray() - val conversationIds = context.getConversationIds() - val totalMessages = messageReader.getMessagesCount() - for (threadId in conversationIds) { - writer.beginObject() - if (config.exportSms && messageReader.getSmsCount() > 0) { - writer.name("sms") - writer.beginArray() - messageReader.forEachSms(threadId) { - writer.jsonValue(gson.toJson(it)) - written++ - onProgress.invoke(totalMessages, written) - } - writer.endArray() - } - if (config.exportMms && messageReader.getMmsCount() > 0) { - writer.name("mms") - writer.beginArray() - messageReader.forEachMms(threadId) { - writer.jsonValue(gson.toJson(it)) - written++ - onProgress.invoke(totalMessages, written) - } + //To keep same layout as previous version and avoid rewriting importer + val mainArray = JSONArray() + + //Main object containing Array of object jSMS & jMMS + val mainObject = JSONObject() + + val jSMS = JSONArray() + val jMMS = JSONArray() - writer.endArray() + try { + var written = 0 + val conversationIds = context.getConversationIds() + val totalMessages = messageReader.getMessagesCount() + for (threadId in conversationIds) { + + if (config.exportSms && messageReader.getSmsCount() > 0) { + messageReader.forEachSms(threadId) { + jSMS.put(JSONObject(gson.toJson(it))) + written++ + onProgress.invoke(totalMessages, written) } + } - writer.endObject() + if (config.exportMms && messageReader.getMmsCount() > 0) { + messageReader.forEachMms(threadId) { + jMMS.put(JSONObject(gson.toJson(it))) + written++ + onProgress.invoke(totalMessages, written) + } } - writer.endArray() - callback.invoke(ExportResult.EXPORT_OK) - } catch (e: Exception) { - callback.invoke(ExportResult.EXPORT_FAIL) } + if (jSMS.length() > 0) mainObject.put("sms", jSMS) + if (jMMS.length() > 0) mainObject.put("mms", jMMS) + + mainArray.put(mainObject) + Log.d("debugFilePath", config.lastExportPath) + if (config.exportBackupPassword == "") + { + //If user didn't set a password we simply save the json in plain + outputStream.write(mainArray.toString().encodeToByteArray()) + } + else + { + Log.d("debugFilePath", config.lastExportPath) + val salt = ByteArray(16) + val random = SecureRandom() + random.nextBytes(salt) + + //Taken from FairEmail project (setting export mechanism) + // https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Cipher + val keyFactory: SecretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1") + val keySpec: KeySpec = PBEKeySpec(config.exportBackupPassword.toCharArray(), salt, KEY_ITERATIONS, KEY_LENGTH) + val secret: SecretKey = keyFactory.generateSecret(keySpec) + val cipher: Cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") + cipher.init(Cipher.ENCRYPT_MODE, secret) + + outputStream.write(salt) + outputStream.write(cipher.iv) + + val cout: OutputStream = CipherOutputStream(outputStream, cipher) + cout.write(mainArray.toString().toByteArray()) + cout.flush() + outputStream.write(cipher.doFinal()) + + } + callback.invoke(ExportResult.EXPORT_OK) + } catch (e: Exception) { + callback.invoke(ExportResult.EXPORT_FAIL) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt index 4ff1f5b78..b62364688 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt @@ -1,7 +1,11 @@ package com.simplemobiletools.smsmessenger.helpers +import android.R.attr.password import android.content.Context import android.provider.Telephony.* +import android.text.TextUtils +import androidx.appcompat.widget.ThemedSpinnerAdapter.Helper +import androidx.documentfile.provider.DocumentFile import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.simplemobiletools.commons.extensions.showErrorToast @@ -9,11 +13,19 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.smsmessenger.extensions.* import com.simplemobiletools.smsmessenger.helpers.MessagesImporter.ImportResult.* import com.simplemobiletools.smsmessenger.models.ExportedMessage -import java.io.File +import java.io.* +import java.security.spec.KeySpec +import javax.crypto.Cipher +import javax.crypto.CipherInputStream +import javax.crypto.SecretKey +import javax.crypto.SecretKeyFactory +import javax.crypto.spec.IvParameterSpec +import javax.crypto.spec.PBEKeySpec + class MessagesImporter(private val context: Context) { enum class ImportResult { - IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW + IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW, NO_PASSWORD_PROVIDED } private val gson = Gson() @@ -21,17 +33,73 @@ class MessagesImporter(private val context: Context) { private val config = context.config private var messagesImported = 0 private var messagesFailed = 0 + private var errorPassword : Boolean = false + + fun readBuffer(inputStream: InputStream, buffer: ByteArray) + { + var left = buffer.size + + while(left > 0) + { + val count = inputStream.read(buffer, buffer.size - left, left) + if (count < 0) + throw Exception("Bad file encryption") + left -= count + } + } - fun importMessages(path: String, onProgress: (total: Int, current: Int) -> Unit = { _, _ -> }, callback: (result: ImportResult) -> Unit) { + fun importMessages(path: String?, file: DocumentFile?, onProgress: (total: Int, current: Int) -> Unit = { _, _ -> }, callback: (result: ImportResult) -> Unit) { ensureBackgroundThread { try { + //if extension is not "sec" then the file must be not encrypted + var inputStream: InputStream + + if(path != null) + { + val extension = path.substringAfterLast(".","") + inputStream = if (path.contains("/")) { + File(path).inputStream() + } else { + context.assets.open(path) + } + } + else if (file != null) + { + inputStream = File(file.uri) + } + + if (extension == "sec") + { + val password = config.importBackupPassword + if(password == "") + { + errorPassword = true + throw Exception("No password provided") + } - val inputStream = if (path.contains("/")) { - File(path).inputStream() - } else { - context.assets.open(path) + try { + BufferedInputStream(inputStream).use { raw -> + val salt = ByteArray(16) + val prefix = ByteArray(16) + readBuffer(raw, salt) + readBuffer(raw, prefix) + val keyFactory: SecretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1") + val keySpec: KeySpec = PBEKeySpec(password.toCharArray(), salt, KEY_ITERATIONS, KEY_LENGTH) + val secret: SecretKey = keyFactory.generateSecret(keySpec) + val cipher: Cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") + val iv = IvParameterSpec(prefix) + cipher.init(Cipher.DECRYPT_MODE, secret, iv) + inputStream = CipherInputStream(raw, cipher) + } + } + catch (e: Exception) + { + throw Exception("Error while decrypting backup, please check your password.") + } } + + inputStream.bufferedReader().use { reader -> val json = reader.readText() val type = object : TypeToken>() {}.type @@ -70,6 +138,7 @@ class MessagesImporter(private val context: Context) { when { messagesImported == 0 -> IMPORT_FAIL messagesFailed > 0 -> IMPORT_PARTIAL + errorPassword -> NO_PASSWORD_PROVIDED else -> IMPORT_OK } ) diff --git a/app/src/main/res/layout/dialog_export_messages.xml b/app/src/main/res/layout/dialog_export_messages.xml index 25bf1ca37..45e87f1e2 100644 --- a/app/src/main/res/layout/dialog_export_messages.xml +++ b/app/src/main/res/layout/dialog_export_messages.xml @@ -49,6 +49,24 @@ android:textSize="@dimen/normal_text_size" tools:text="Messages" /> + + + + @@ -13,6 +14,24 @@ android:paddingTop="@dimen/activity_margin" android:paddingEnd="@dimen/activity_margin"> + + + + Send long messages as MMS Messages + Password Export messages Export SMS Export MMS @@ -92,6 +93,7 @@ Reddit: https://www.reddit.com/r/SimpleMobileTools + Password (leave blank if not needed) + Password (leave blank if not needed) الرسائل + Password تصدير الرسائل تصدير الرسائل القصيرة تصدير رسائل الوسائط diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 4bfea0f5a..cc9f48121 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -53,7 +53,9 @@ Envia missatges de grup com a MMS Envia missatges llargs com a MMS + Password (leave blank if not needed) Missatges + Password Exporta els missatges Exporta SMS Exporta MMS @@ -76,4 +78,4 @@ --> La mida dels MMS està limitada pels operadors, podeu provar d\'establir un límit més petit a la configuració de l\'aplicació. L\'altre extrem no ha rebut el meu MMS, hi puc fer alguna cosa\? - \ No newline at end of file + diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index d633b8d79..d2e186c10 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -53,8 +53,10 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) Export zpráv Messages + Password Export SMS Export MMS Import zpráv diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index db0bc2074..6135fc005 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -53,7 +53,9 @@ Send gruppemeddelelser som MMS Send lange beskeder som MMS + Password (leave blank if not needed) Messages + Password Eksporter beskeder Export SMS Eksportér MMS @@ -77,4 +79,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 537d8f2e5..179e3ac4d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -53,7 +53,9 @@ Gruppennachrichten als MMS versenden Send long messages as MMS + Password (leave blank if not needed) Nachrichten + Password Nachrichten exportieren SMS exportieren MMS exportieren diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 025e891b2..62abf503d 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -59,7 +59,9 @@ Send long messages as MMS + Password (leave blank if not needed) Μηνύματα + Password Εξαγωγή μηνυμάτων Εξαγωγή SMS Εξαγωγή MMS diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 9028aa738..7c58fe69e 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -53,7 +53,9 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) Mesaĝoj + Password Export messages Export SMS Export MMS diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 1cc21590b..6b3b3a90d 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -59,7 +59,9 @@ Send long messages as MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Export MMS diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 0751da107..b0701f5cf 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -53,7 +53,9 @@ Saada rühmasõnumid MMS-sõnumitena Send long messages as MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Ekspordi MMS-sõnumid diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 3332edf5a..775587d15 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -53,7 +53,9 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Export MMS diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 860dcb4d7..d6ed2b0a2 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -53,7 +53,9 @@ Envoyer des messages de groupe en MMS Send long messages as MMS + Password (leave blank if not needed) Messages + Password Exporter des messages Exporter le SMS Exporter le MMS diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index a2294ebbb..cc0580265 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -59,7 +59,9 @@ Send long messages as MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Export MMS diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index aa7230d93..d61538c03 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -53,7 +53,9 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) Üzenetek + Password Üzenetek exportálása SMS exportálása MMS exportálása diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 23d0ce38d..6009220a0 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -53,7 +53,9 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Export MMS @@ -83,4 +85,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3489baca8..8fb4fce8e 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -53,7 +53,9 @@ Invia messaggi di gruppo come MMS Send long messages as MMS + Password (leave blank if not needed) Messaggi + Password Esporta messaggi Esporta SMS Esporta MMS diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 2fb0db9b9..0eb8edc14 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -59,7 +59,9 @@ Send long messages as MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Export MMS diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 1055f4514..b1abae4ef 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -53,7 +53,9 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Export MMS diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index b20b924e8..4d9a16d25 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -59,7 +59,9 @@ Send long messages as MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Export MMS diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 8b4f58a80..463df5f31 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -53,7 +53,9 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) Meldinger + Password Eksporter meldinger Eksporter SMS Eksporter MMS diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index e96bd0756..78a947636 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -53,7 +53,9 @@ Groepsberichten sturen als MMS Lange berichten als MMS versturen + Password (leave blank if not needed) Berichten + Password Berichten exporteren SMS-berichten exporteren MMS-berichten exporteren @@ -96,4 +98,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d80f51ad3..168495819 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -55,7 +55,9 @@ Wysyłaj wiadomości grupowe jako MMS-y Wysyłaj długie wiadomości jako MMS-y + Password (leave blank if not needed) Wiadomości + Password Eksportuj wiadomości Eksportuj SMS-y Eksportuj MMS-y diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 8a7746023..1544d7bc4 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -53,7 +53,9 @@ Enviar mensagens de grupo como MMS Send long messages as MMS + Password (leave blank if not needed) Mensagens + Password Exportar mensagens Exportar SMS Exportar MMS diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 6986a53a1..818e481bc 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -59,7 +59,9 @@ Send long messages as MMS + Password (leave blank if not needed) Mesajele + Password Exportă mesajele Exportă mesajele SMS Exportă mesajele MMS diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 7c9114cab..bf7e056a3 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -55,7 +55,9 @@ Отправлять групповые сообщения как MMS Отправлять длинные сообщения как MMS + Password (leave blank if not needed) Сообщения + Password Экспорт сообщений Экспорт SMS Экспорт MMS @@ -98,4 +100,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 61e88cc7d..a15cf8d5f 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -61,7 +61,9 @@ Odosielať dlhé správy ako MMS + Password (leave blank if not needed) Správy + Password Exportovať správy Exportovať SMS Exportovať MMS diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 664b67436..8e34491b8 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -53,7 +53,9 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) செய்திகளை + Password செய்திகளை ஏற்றுமதி செய்யவும் ஏற்றுமதி எஸ்எம்எஸ் ஏற்றுமதி MMS diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 414679e4e..80614ac88 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -53,7 +53,9 @@ Grup mesajlarını MMS olarak gönder Uzun mesajları MMS olarak gönder + Password (leave blank if not needed) Mesajlar + Password Mesajları dışa aktar SMS\'i dışa aktar MMS\'i dışa aktar @@ -77,4 +79,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 4f3e21455..da75f096c 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -57,7 +57,9 @@ Надсилати групові повідомлення як MMS Надсилати довгі повідомлення як MMS + Password (leave blank if not needed) Messages + Password Export messages Export SMS Експорт MMS @@ -81,4 +83,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 8494afa08..00adf8516 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -53,7 +53,9 @@ 将群组信息作为彩信发送 将长消息作为彩信发送 + Password (leave blank if not needed) 消息 + Password 导出消息 导出短信 导出彩信 @@ -96,4 +98,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 92b6c09ba..978ae3a8c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -53,6 +53,7 @@ Send group messages as MMS Send long messages as MMS + Password (leave blank if not needed) Messages Password Export messages @@ -93,7 +94,6 @@ Reddit: https://www.reddit.com/r/SimpleMobileTools - Password (leave blank if not needed) + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… هل أنت متأكد أنك تريد حذف كافة رسائل هذه المحادثة؟ diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index cc9f48121..1d1e573cc 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -29,6 +29,12 @@ Missatge nou Marca com a llegit Marcar com no llegit + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Confirmeu que voleu suprimir tots els missatges d\'aquesta conversa\? diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index d2e186c10..653e68a05 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -29,6 +29,12 @@ Nová zpráva Označit jako přečtené Označit jako nepřečtené + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Opravdu chcete smazat všechny zprávy z této konverzace? diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 6135fc005..2e0840a3b 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -29,6 +29,12 @@ Ny Besked Marker som læst Marker som ulæst + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Er du sikker på, at du vil slette alle beskeder i denne samtale\? diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 179e3ac4d..45f138640 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -29,6 +29,12 @@ Neue Nachricht Als gelesen markieren Als ungelesen markieren + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Möchtest du wirklich alle Nachrichten dieses Chats löschen\? diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 62abf503d..be2a727b0 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -30,6 +30,12 @@ Νέο μήνυμα Σήμανση ως αναγνωσμένο Σήμανση ως μη αναγνωσμένο + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Είστε βέβαιοι ότι θέλετε να διαγράψετε όλα τα μηνύματα αυτής της συνομιλίας; diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 7c58fe69e..1aa8c9c3b 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -29,6 +29,12 @@ Nova mesaĝo Marki kiel legitan Marki kiel nelegitan + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Are you sure you want to delete all messages of this conversation? diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6b3b3a90d..667a029bc 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -30,6 +30,12 @@ Nuevo mensaje Marcar como leído Marcar como no leído + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… ¿Estás seguro que quieres eliminar todos los mensajes en esta conversación? diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index b0701f5cf..fbc49e71f 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -29,6 +29,12 @@ Uus sõnum Märgi loetuks Märgi mitteloetuks + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Kas oled kindel, et soovid kustutada kõik selle vestluse sõnumid\? diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 775587d15..8d7defd0e 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -29,6 +29,12 @@ Uusi viesti Merkitse luetuksi Merkitse lukemattomaksi + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Haluatko varmasti poistaa kaikki tämän keskustelun viestit\? diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index d6ed2b0a2..6426497bd 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -29,6 +29,12 @@ Nouveau message Marquer comme lu Marquer comme non lu + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Voulez-vous vraiment supprimer tous les messages de cette conversation \? diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index cc0580265..b2648392e 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -30,6 +30,12 @@ Nova mensaxe Marcar como lida Marcar como non lida + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Ten a certeza de que desexa eliminar todas as mensaxes desta conversa? diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index d61538c03..54d1452e2 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -29,6 +29,12 @@ Új üzenet Megjelölés olvasottként Megjelölés olvasatlanként + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Biztos, hogy törli az összes üzenetet ebből a beszélgetésből\? diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 6009220a0..31302c456 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -29,6 +29,12 @@ Pesan baru Tandai sebagai Dibaca Tandai sebagai Belum dibaca + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Apakah Anda yakin ingin menghapus semua pesan dari percakapan ini? diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 8fb4fce8e..2a082a209 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -29,6 +29,12 @@ Nuovo messaggio Letto Non letto + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Vuoi davvero eliminare tutti i messaggi di questa conversazione\? diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 0eb8edc14..3234354c2 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -30,6 +30,12 @@ 新しいメッセージ 既読にする 未読にする + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… 本当にこの会話の全てのメッセージを削除しますか? diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index b1abae4ef..e5e690d29 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -29,6 +29,12 @@ Nauja žinutė Mark as Read Mark as Unread + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Ar tikrai norite ištrinti visas šio pokalbio žinutes? diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 4d9a16d25..a3e91d1a2 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -30,6 +30,12 @@ പുതിയ മെസ്സേജ് വായിച്ചതായി അടയാളപ്പെടുത്തുക വായിച്ചിട്ടില്ലെന്ന് അടയാളപ്പെടുത്തുക + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… ഈ സംഭാഷണത്തിന്റെ എല്ലാ സന്ദേശങ്ങൾ ഇല്ലാതാക്കാൻ നിങ്ങൾ ആഗ്രഹിക്കുന്നുണ്ടോ? diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 463df5f31..03bfdf9cd 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -29,6 +29,12 @@ Ny melding Marker som lest Marker som ulest + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Are you sure you want to delete all messages of this conversation? diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 78a947636..655963670 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -29,6 +29,12 @@ Nieuw bericht Als gelezen markeren Als ongelezen markeren + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Alle berichten in dit gesprek verwijderen\? diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 168495819..c528b81f3 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -29,6 +29,12 @@ Nowa wiadomość Oznacz jako przeczytane Oznacz jako nieprzeczytane + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Czy usunąć wszystkie wiadomości z tej rozmowy\? diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 1544d7bc4..7a6fa74fe 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -29,6 +29,12 @@ Nova mensagem Marcar como lida Marcar como não lida + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Tem a certeza de que pretende apagar todas as mensagens desta conversa\? diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 818e481bc..d8144d1ff 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -30,6 +30,12 @@ Mesaj nou Marchează ca citit Marchează ca necitit + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Eşti sigur că vrei să ştergi toate mesajele din această conversaţie? diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index bf7e056a3..0c7c67662 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -29,6 +29,12 @@ Новое сообщение Прочитано Не прочитано + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Удалить все сообщения в этой переписке\? diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index a15cf8d5f..825e45c20 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -30,6 +30,12 @@ Nová správa Označiť ako prečítané Označiť ako neprečítané + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Ste si istý, že chcete odstrániť všetky správy tejto konverzácie? diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 8e34491b8..defdde49b 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -29,6 +29,12 @@ புதிய செய்தி படித்ததாக குறியிடு படிக்காததாக குறியிடு + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… இந்த உரையாடலின் அனைத்து செய்திகளையும் நிச்சயமாக நீக்க விரும்புகிறீர்களா\? diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 80614ac88..65d560c21 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -29,6 +29,12 @@ Yeni mesaj Okundu olarak işaretle Okunmadı olarak işaretle + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Bu görüşmenin tüm mesajlarını silmek istediğinizden emin misiniz\? diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index da75f096c..d61e472ca 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -29,6 +29,12 @@ Нове повідомлення Прочитано Не прочитано + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Справді видалити всі повідомлення у цьому листуванні\? diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 00adf8516..19da86a6d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -29,6 +29,12 @@ 新消息 标记为已读 标记为未读 + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… 您确定要删除此对话的所有消息吗\? diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 978ae3a8c..b5658c1ac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -29,6 +29,12 @@ New message Mark as Read Mark as Unread + + Import/Export Progress + Importing messages… + Exporting messages… + Encrypting backup… + Decrypting backup… Are you sure you want to delete all messages of this conversation? From 6935f8b1aad40b7910e424aa74b8dcb6b1838a22 Mon Sep 17 00:00:00 2001 From: Spitap Date: Wed, 9 Mar 2022 21:18:18 +0100 Subject: [PATCH 7/8] follow more closely kotlin coding convention --- .../smsmessenger/activities/MainActivity.kt | 2 +- .../ImportExportProgressNotification.kt | 29 ++++++++----------- .../smsmessenger/helpers/MessagesExporter.kt | 4 +-- .../smsmessenger/helpers/MessagesImporter.kt | 9 ++---- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt index e75c4c128..202130f60 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt @@ -389,7 +389,7 @@ class MainActivity : SimpleActivity() { ensureBackgroundThread { exportNotification.spawnProgressNotification() smsExporter.exportMessages(outputStream, { - state: MessagesExporter.ExportState, total: Int, current: Int -> exportNotification.updateNotification(state, total, current) + state, total, current -> exportNotification.updateNotification(state, total, current) }) { val toastId = when (it) { MessagesExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImportExportProgressNotification.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImportExportProgressNotification.kt index 1e4bdf1ad..0a9c6d1de 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImportExportProgressNotification.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImportExportProgressNotification.kt @@ -36,19 +36,18 @@ class ImportExportProgressNotification( } fun setFinish(hasSucceed: Boolean) { - if (isInit) - { + if (isInit) { isInit = false - notification.setContentTitle(if(type == ImportOrExport.EXPORT) activity.getString(R.string.exporting_successful) else activity.getString(R.string.importing_successful)) - if(hasSucceed) - { + val contentTitle = if(type == ImportOrExport.EXPORT) activity.getString(R.string.exporting_successful) + else activity.getString(R.string.importing_successful) + notification.setContentTitle(contentTitle) + + if(hasSucceed) { notification.setContentText("Success") .setProgress(0,0, false) .setOngoing(false) .setAutoCancel(true) - } - else - { + } else { notification.setContentText("Something went wrong") .setProgress(0,0, false) .setOngoing(false) @@ -60,7 +59,8 @@ class ImportExportProgressNotification( fun spawnProgressNotification() { - val contentTitle = if(type == ImportOrExport.IMPORT) activity.getString(R.string.importing_messages) else activity.getString(R.string.exporting_messages) + val contentTitle = if(type == ImportOrExport.IMPORT) activity.getString(R.string.importing_messages) + else activity.getString(R.string.exporting_messages) //Creating a notification and setting its various attributes notification = NotificationCompat.Builder(activity, channelId) @@ -85,15 +85,12 @@ class ImportExportProgressNotification( .setProgress(progressMax, progress.toInt(), false) } - if (type == ImportOrExport.EXPORT) - { + if (type == ImportOrExport.EXPORT) { when(state) { MessagesExporter.ExportState.EXPORT -> notification.setContentTitle(activity.getString(R.string.exporting_messages)) MessagesExporter.ExportState.ENCRYPT -> notification.setContentTitle(activity.getString(R.string.encrypting_backup)) } - } - else - { + } else { when(state) { MessagesImporter.ImportState.DECRYPTING -> { notification.setContentTitle(activity.getString(R.string.decrypting_backup)) @@ -106,9 +103,7 @@ class ImportExportProgressNotification( notificationManager.notify(EXPORT_IMPORT_NOTIFICATION_ID, notification.build()) startTime = System.currentTimeMillis() waitTime = 0L - } - else - { + } else { waitTime = Date().time - startTime } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt index 8b70e252a..8070ccc42 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt @@ -37,6 +37,7 @@ class MessagesExporter(private val context: Context) { val totalMessages = messageReader.getMessagesCount(config.exportSms, config.exportMms) for (threadId in conversationIds) { writer.beginObject() + if (config.exportSms && messageReader.getSmsCount() > 0) { writer.name("sms") writer.beginArray() @@ -78,8 +79,7 @@ class MessagesExporter(private val context: Context) { if (config.exportBackupPassword == "") { jsonWriter(outputStream, onProgress, callback) - } - else { + } else { val outputFile = File(context.cacheDir, "output.json") jsonWriter(outputFile.outputStream(), onProgress, callback) val salt = ByteArray(16) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt index 516fa7ecc..f971da19e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt @@ -20,7 +20,7 @@ import javax.crypto.spec.PBEKeySpec class MessagesImporter(private val context: Context) { enum class ImportResult { - IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW, NO_PASSWORD_PROVIDED + IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW } enum class ImportState { DECRYPTING, RESTORING @@ -31,7 +31,6 @@ class MessagesImporter(private val context: Context) { private val config = context.config private var messagesImported = 0 private var messagesFailed = 0 - private var errorPassword : Boolean = false private fun readBuffer(inputStream: InputStream, buffer: ByteArray) { @@ -60,8 +59,7 @@ class MessagesImporter(private val context: Context) { val data: InputStream var rawInputStream: InputStream? = null - if (password != "") - { + if (password != "") { try { onProgress.invoke(ImportState.DECRYPTING, 0, 0) rawInputStream = BufferedInputStream(inputStream) @@ -79,7 +77,7 @@ class MessagesImporter(private val context: Context) { } catch (e: Exception) { throw Exception("Error while decrypting backup, please check your password.") - } + } } else { @@ -129,7 +127,6 @@ class MessagesImporter(private val context: Context) { when { messagesImported == 0 -> IMPORT_FAIL messagesFailed > 0 -> IMPORT_PARTIAL - errorPassword -> NO_PASSWORD_PROVIDED else -> IMPORT_OK } ) From 6090f78ac3420d1dacce00a34f5c1f4ccccaa08a Mon Sep 17 00:00:00 2001 From: Spitap Date: Wed, 9 Mar 2022 22:06:44 +0100 Subject: [PATCH 8/8] formated code --- .../smsmessenger/activities/MainActivity.kt | 4 +- .../dialogs/ImportMessagesDialog.kt | 2 +- .../ImportExportProgressNotification.kt | 37 +++++++++---------- .../smsmessenger/helpers/MessagesExporter.kt | 15 ++++++-- .../smsmessenger/helpers/MessagesImporter.kt | 17 +++++---- 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt index 202130f60..d6d6a5141 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt @@ -388,8 +388,8 @@ class MainActivity : SimpleActivity() { val exportNotification = ImportExportProgressNotification(this, ImportExportProgressNotification.ImportOrExport.EXPORT) ensureBackgroundThread { exportNotification.spawnProgressNotification() - smsExporter.exportMessages(outputStream, { - state, total, current -> exportNotification.updateNotification(state, total, current) + smsExporter.exportMessages(outputStream, { state, total, current -> + exportNotification.updateNotification(state, total, current) }) { val toastId = when (it) { MessagesExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ImportMessagesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ImportMessagesDialog.kt index 4209c0b97..6775fd6b5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ImportMessagesDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/ImportMessagesDialog.kt @@ -53,7 +53,7 @@ class ImportMessagesDialog( config.importBackupPassword = view.import_messages_password.value ensureBackgroundThread { MessagesImporter(activity).importMessages(path, - {state, total, current -> importNotification.updateNotification(state, total, current)}) { + { state, total, current -> importNotification.updateNotification(state, total, current) }) { handleParseResult(it) dismiss() } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImportExportProgressNotification.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImportExportProgressNotification.kt index 0a9c6d1de..c384f3b9f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImportExportProgressNotification.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImportExportProgressNotification.kt @@ -11,10 +11,11 @@ import java.util.* class ImportExportProgressNotification( private val activity: SimpleActivity, private val type: ImportOrExport -){ - enum class ImportOrExport{ +) { + enum class ImportOrExport { IMPORT, EXPORT } + private var isInit = false private lateinit var notification: NotificationCompat.Builder private lateinit var channelId: String @@ -38,18 +39,18 @@ class ImportExportProgressNotification( fun setFinish(hasSucceed: Boolean) { if (isInit) { isInit = false - val contentTitle = if(type == ImportOrExport.EXPORT) activity.getString(R.string.exporting_successful) - else activity.getString(R.string.importing_successful) + val contentTitle = + if (type == ImportOrExport.EXPORT) activity.getString(R.string.exporting_successful) else activity.getString(R.string.importing_successful) notification.setContentTitle(contentTitle) - if(hasSucceed) { + if (hasSucceed) { notification.setContentText("Success") - .setProgress(0,0, false) + .setProgress(0, 0, false) .setOngoing(false) .setAutoCancel(true) } else { notification.setContentText("Something went wrong") - .setProgress(0,0, false) + .setProgress(0, 0, false) .setOngoing(false) .setAutoCancel(true) } @@ -57,10 +58,9 @@ class ImportExportProgressNotification( } } - fun spawnProgressNotification() - { - val contentTitle = if(type == ImportOrExport.IMPORT) activity.getString(R.string.importing_messages) - else activity.getString(R.string.exporting_messages) + fun spawnProgressNotification() { + val contentTitle = + if (type == ImportOrExport.IMPORT) activity.getString(R.string.importing_messages) else activity.getString(R.string.exporting_messages) //Creating a notification and setting its various attributes notification = NotificationCompat.Builder(activity, channelId) @@ -73,28 +73,27 @@ class ImportExportProgressNotification( notificationManager.notify(EXPORT_IMPORT_NOTIFICATION_ID, notification.build()) isInit = true - } + } fun updateNotification(state: Any, total: Int, current: Int) { - if(isInit) { - if (waitTime > 500) - { + if (isInit) { + if (waitTime > 500) { if (total > 1 && current <= total && current > 0) { val progress = current.toDouble() / total * 100.00 notification.setContentText(progress.toInt().toString() + "%") - .setProgress(progressMax, progress.toInt(), false) + .setProgress(progressMax, progress.toInt(), false) } if (type == ImportOrExport.EXPORT) { - when(state) { + when (state) { MessagesExporter.ExportState.EXPORT -> notification.setContentTitle(activity.getString(R.string.exporting_messages)) MessagesExporter.ExportState.ENCRYPT -> notification.setContentTitle(activity.getString(R.string.encrypting_backup)) } } else { - when(state) { + when (state) { MessagesImporter.ImportState.DECRYPTING -> { notification.setContentTitle(activity.getString(R.string.decrypting_backup)) - .setProgress(100, 50, true) + .setProgress(100, 50, true) } MessagesImporter.ImportState.RESTORING -> notification.setContentTitle(activity.getString(R.string.importing_messages)) } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt index 8070ccc42..d738393a7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesExporter.kt @@ -19,6 +19,7 @@ class MessagesExporter(private val context: Context) { enum class ExportResult { EXPORT_FAIL, EXPORT_OK } + enum class ExportState { EXPORT, ENCRYPT } @@ -27,7 +28,11 @@ class MessagesExporter(private val context: Context) { private val messageReader = MessagesReader(context) private val gson = Gson() - private fun jsonWriter(workOutputStream: OutputStream, onProgress: (state: ExportState, total: Int, current: Int) -> Unit = {_, _, _ -> }, callback: (result: ExportResult) -> Unit) { + private fun jsonWriter( + workOutputStream: OutputStream, + onProgress: (state: ExportState, total: Int, current: Int) -> Unit = { _, _, _ -> }, + callback: (result: ExportResult) -> Unit + ) { val writer = JsonWriter(workOutputStream.bufferedWriter()) writer.use { try { @@ -70,7 +75,11 @@ class MessagesExporter(private val context: Context) { } } - fun exportMessages(outputStream: OutputStream?, onProgress: (state: ExportState, total: Int, current: Int) -> Unit = { _, _, _ -> }, callback: (result: ExportResult) -> Unit) { + fun exportMessages( + outputStream: OutputStream?, + onProgress: (state: ExportState, total: Int, current: Int) -> Unit = { _, _, _ -> }, + callback: (result: ExportResult) -> Unit + ) { ensureBackgroundThread { if (outputStream == null) { callback.invoke(ExportResult.EXPORT_FAIL) @@ -108,7 +117,7 @@ class MessagesExporter(private val context: Context) { val readBytes = cin.read(byteArray, 0, 8192) left -= readBytes cout.write(byteArray, 0, readBytes) - } while(left > 0) + } while (left > 0) cout.flush() diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt index f971da19e..d7dfa7dfa 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/MessagesImporter.kt @@ -22,6 +22,7 @@ class MessagesImporter(private val context: Context) { enum class ImportResult { IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW } + enum class ImportState { DECRYPTING, RESTORING } @@ -32,12 +33,10 @@ class MessagesImporter(private val context: Context) { private var messagesImported = 0 private var messagesFailed = 0 - private fun readBuffer(inputStream: InputStream, buffer: ByteArray) - { + private fun readBuffer(inputStream: InputStream, buffer: ByteArray) { var left = buffer.size - while(left > 0) - { + while (left > 0) { val count = inputStream.read(buffer, buffer.size - left, left) if (count < 0) throw Exception("Bad file encryption") @@ -45,7 +44,11 @@ class MessagesImporter(private val context: Context) { } } - fun importMessages(path: String, onProgress: (state: ImportState, total: Int, current: Int) -> Unit = { _, _, _ -> }, callback: (result: ImportResult) -> Unit) { + fun importMessages( + path: String, + onProgress: (state: ImportState, total: Int, current: Int) -> Unit = { _, _, _ -> }, + callback: (result: ImportResult) -> Unit + ) { ensureBackgroundThread { try { val inputStream = if (path.contains("/")) { @@ -78,9 +81,7 @@ class MessagesImporter(private val context: Context) { } catch (e: Exception) { throw Exception("Error while decrypting backup, please check your password.") } - } - else - { + } else { data = inputStream }