Add progress callbacks to importer and exporter, not used yet

This commit is contained in:
darthpaul 2021-09-18 21:54:44 +01:00
parent d78776e288
commit 24d9988ec1
6 changed files with 101 additions and 38 deletions

View File

@ -11,6 +11,7 @@ import android.graphics.drawable.LayerDrawable
import android.net.Uri
import android.os.Bundle
import android.provider.Telephony
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import com.simplemobiletools.commons.dialogs.FilePickerDialog
@ -361,10 +362,13 @@ class MainActivity : SimpleActivity() {
}
}
private val TAG = "MainActivity"
private fun exportMessagesTo(outputStream: OutputStream?) {
ensureBackgroundThread {
toast(R.string.exporting)
smsExporter.exportMessages(outputStream){
smsExporter.exportMessages(outputStream, { total, current ->
Log.d(TAG, "PERCENTAGE: ${current.toDouble() * 100 / total.toDouble()}%")
}) {
toast(
when (it) {
MessagesExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful

View File

@ -1,5 +1,6 @@
package com.simplemobiletools.smsmessenger.dialogs
import android.util.Log
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.extensions.setupDialogStuff
@ -9,6 +10,7 @@ import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.activities.SimpleActivity
import com.simplemobiletools.smsmessenger.extensions.config
import com.simplemobiletools.smsmessenger.helpers.MessagesImporter
import com.simplemobiletools.smsmessenger.helpers.MessagesImporter.ImportResult.*
import kotlinx.android.synthetic.main.dialog_import_messages.view.import_mms_checkbox
import kotlinx.android.synthetic.main.dialog_import_messages.view.import_sms_checkbox
@ -18,6 +20,7 @@ class ImportMessagesDialog(
private val callback: (refresh: Boolean) -> Unit,
) {
private val TAG = "ImportMessagesDialog"
private val config = activity.config
init {
@ -36,8 +39,10 @@ class ImportMessagesDialog(
config.importSms = view.import_sms_checkbox.isChecked
config.importMms = view.import_mms_checkbox.isChecked
ensureBackgroundThread {
MessagesImporter(activity).importMessages(path){
MessagesImporter(activity).importMessages(path, onProgress = { total: Int, current: Int ->
Log.d(TAG, "PERCENTAGE: ${current.toDouble() * 100 / total.toDouble()}%")
}) {
handleParseResult(it)
}
dismiss()
callback.invoke(true)
@ -46,4 +51,15 @@ class ImportMessagesDialog(
}
}
}
private fun handleParseResult(result: MessagesImporter.ImportResult) {
activity.toast(
when (result) {
IMPORT_OK -> R.string.importing_successful
IMPORT_PARTIAL -> R.string.importing_some_entries_failed
else -> R.string.no_items_found
}
)
callback(result != IMPORT_FAIL)
}
}

View File

@ -17,10 +17,7 @@ class MessagesExporter(private val context: Context) {
private val messageReader = MessagesReader(context)
private val gson = Gson()
fun exportMessages(
outputStream: OutputStream?,
callback: (result: ExportResult) -> Unit,
) {
fun exportMessages(outputStream: OutputStream?, onProgress: (total: Int, current: Int) -> Unit = { _, _ -> }, callback: (result: ExportResult) -> Unit) {
ensureBackgroundThread {
if (outputStream == null) {
callback.invoke(ExportResult.EXPORT_FAIL)
@ -57,6 +54,7 @@ class MessagesExporter(private val context: Context) {
messageReader.forEachSms(threadId) {
writer.jsonValue(gson.toJson(it))
written++
onProgress.invoke(totalMessages, written)
}
writer.endArray()
}
@ -68,6 +66,7 @@ class MessagesExporter(private val context: Context) {
messageReader.forEachMms(threadId) {
writer.jsonValue(gson.toJson(it))
written++
onProgress.invoke(totalMessages, written)
}
writer.endArray()

View File

@ -2,14 +2,15 @@ package com.simplemobiletools.smsmessenger.helpers
import android.content.Context
import android.net.Uri
import android.provider.Telephony
import android.provider.Telephony.*
import android.util.Log
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.simplemobiletools.commons.extensions.queryCursor
import com.simplemobiletools.commons.extensions.showErrorToast
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
@ -19,19 +20,18 @@ class MessagesImporter(private val context: Context) {
}
enum class ImportResult {
IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW
IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL
}
private val gson = Gson()
private val messageWriter = MessagesWriter(context)
private val config = context.config
private var messagesImported = 0
private var messagesFailed = 0
fun importMessages(path: String, callback: (result: ImportResult) -> Unit) {
fun importMessages(path: String, onProgress: (total: Int, current: Int) -> Unit = { _, _ -> }, callback: (result: ImportResult) -> Unit) {
ensureBackgroundThread {
if (path.isEmpty()) {
callback.invoke(ImportResult.IMPORT_FAIL)
return@ensureBackgroundThread
}
try {
val inputStream = if (path.contains("/")) {
File(path).inputStream()
@ -39,23 +39,30 @@ class MessagesImporter(private val context: Context) {
context.assets.open(path)
}
inputStream.bufferedReader().use {
try {
val json = it.readText()
inputStream.bufferedReader().use { reader ->
val json = reader.readText()
Log.d(TAG, "importMessages: json== $json")
val type = object : TypeToken<List<ExportedMessage>>() {}.type
val messages = gson.fromJson<List<ExportedMessage>>(json, type)
Log.d(TAG, "importMessages: ${messages.size}")
val totalMessages = messages.flatMap { it.sms }.size + messages.flatMap { it.mms }.size
onProgress.invoke(totalMessages, messagesImported)
for (message in messages) {
// add sms
if (config.importSms) {
message.sms.forEach(messageWriter::writeSmsMessage)
message.sms.forEach { backup ->
messageWriter.writeSmsMessage(backup)
messagesImported++
onProgress.invoke(totalMessages, messagesImported)
}
}
// add mms
if (config.importMms) {
message.mms.forEach(messageWriter::writeMmsMessage)
message.mms.forEach { backup ->
messageWriter.writeMmsMessage(backup)
messagesImported++
onProgress.invoke(totalMessages, messagesImported)
}
}
context.queryCursor(Threads.CONTENT_URI) { cursor ->
val json = cursor.rowsToJson()
@ -78,13 +85,22 @@ class MessagesImporter(private val context: Context) {
}
refreshMessages()
callback.invoke(ImportResult.IMPORT_OK)
}
}
} catch (e: Exception) {
Log.e(TAG, "importMessages: ", e)
callback.invoke(ImportResult.IMPORT_FAIL)
}
}
context.showErrorToast(e)
messagesFailed++
}
callback.invoke(
when {
messagesImported == 0 -> {
IMPORT_FAIL
}
messagesFailed > 0 -> IMPORT_PARTIAL
else -> IMPORT_OK
}
)
}
}
}

View File

@ -107,7 +107,29 @@ class MessagesReader(private val context: Context) {
val parts = getParts(mmsId)
val addresses = getMMSAddresses(mmsId)
block(MmsBackup(creator, contentType, deliveryReport, date, dateSent, locked, messageType, messageBox, read, readReport, seen, textOnly, status, subject, subjectCharSet, subscriptionId, transactionId, addresses, parts))
block(
MmsBackup(
creator,
contentType,
deliveryReport,
date,
dateSent,
locked,
messageType,
messageBox,
read,
readReport,
seen,
textOnly,
status,
subject,
subjectCharSet,
subscriptionId,
transactionId,
addresses,
parts
)
)
}
}
@ -216,7 +238,16 @@ class MessagesReader(private val context: Context) {
return addresses
}
fun getMessagesCount(): Long {
return 0
fun getMessagesCount(): Int {
return countRows(Sms.CONTENT_URI) + countRows(Mms.CONTENT_URI)
}
private fun countRows(uri: Uri): Int {
val cursor = context.contentResolver.query(
uri, null, null, null, null
) ?: return 0
cursor.use {
return cursor.count
}
}
}

View File

@ -42,8 +42,6 @@ class MessagesWriter(private val context: Context) {
} else {
Log.w(TAG, "SMS already exists")
}
// update conversation date
updateThreadDate(threadId, smsBackup.date)
}
private fun updateThreadDate(
@ -86,7 +84,6 @@ class MessagesWriter(private val context: Context) {
//write mms
if (!mmsExist(mmsBackup)) {
contentResolver.insert(Mms.CONTENT_URI, contentValues)
updateThreadDate(threadId, mmsBackup.date)
} else {
Log.w(TAG, "mms already exists")
}
@ -215,8 +212,8 @@ class MessagesWriter(private val context: Context) {
val uri = Uri.parse("content://mms/${messageId}/part")
val projection = arrayOf(Mms.Part._ID)
val selection =
"${Mms.Part.CONTENT_LOCATION} = ? AND ${Mms.Part.CT_TYPE} = ? AND ${Mms.Part.MSG_ID} = ? AND ${Mms.Part.CONTENT_ID} = ?"
val selectionArgs = arrayOf(mmsPart.contentLocation.toString(), mmsPart.contentType.toString(), messageId.toString(), mmsPart.contentId.toString())
"${Mms.Part.CONTENT_LOCATION} = ? AND ${Mms.Part.CONTENT_TYPE} = ? AND ${Mms.Part.MSG_ID} = ? AND ${Mms.Part.CONTENT_ID} = ?"
val selectionArgs = arrayOf(mmsPart.contentLocation.toString(), mmsPart.contentType, messageId.toString(), mmsPart.contentId.toString())
var exists = false
context.queryCursor(uri, projection, selection, selectionArgs) {
exists = it.count > 0