mirror of
https://github.com/SimpleMobileTools/Simple-SMS-Messenger.git
synced 2025-06-05 21:49:22 +02:00
Add progress callbacks to importer and exporter, not used yet
This commit is contained in:
@@ -11,6 +11,7 @@ import android.graphics.drawable.LayerDrawable
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.Telephony
|
import android.provider.Telephony
|
||||||
|
import android.util.Log
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
||||||
@@ -361,10 +362,13 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val TAG = "MainActivity"
|
||||||
private fun exportMessagesTo(outputStream: OutputStream?) {
|
private fun exportMessagesTo(outputStream: OutputStream?) {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
toast(R.string.exporting)
|
toast(R.string.exporting)
|
||||||
smsExporter.exportMessages(outputStream){
|
smsExporter.exportMessages(outputStream, { total, current ->
|
||||||
|
Log.d(TAG, "PERCENTAGE: ${current.toDouble() * 100 / total.toDouble()}%")
|
||||||
|
}) {
|
||||||
toast(
|
toast(
|
||||||
when (it) {
|
when (it) {
|
||||||
MessagesExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful
|
MessagesExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package com.simplemobiletools.smsmessenger.dialogs
|
package com.simplemobiletools.smsmessenger.dialogs
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
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.activities.SimpleActivity
|
||||||
import com.simplemobiletools.smsmessenger.extensions.config
|
import com.simplemobiletools.smsmessenger.extensions.config
|
||||||
import com.simplemobiletools.smsmessenger.helpers.MessagesImporter
|
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_mms_checkbox
|
||||||
import kotlinx.android.synthetic.main.dialog_import_messages.view.import_sms_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 callback: (refresh: Boolean) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
private val TAG = "ImportMessagesDialog"
|
||||||
private val config = activity.config
|
private val config = activity.config
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -36,8 +39,10 @@ class ImportMessagesDialog(
|
|||||||
config.importSms = view.import_sms_checkbox.isChecked
|
config.importSms = view.import_sms_checkbox.isChecked
|
||||||
config.importMms = view.import_mms_checkbox.isChecked
|
config.importMms = view.import_mms_checkbox.isChecked
|
||||||
ensureBackgroundThread {
|
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()
|
dismiss()
|
||||||
callback.invoke(true)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,10 +17,7 @@ class MessagesExporter(private val context: Context) {
|
|||||||
private val messageReader = MessagesReader(context)
|
private val messageReader = MessagesReader(context)
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
|
||||||
fun exportMessages(
|
fun exportMessages(outputStream: OutputStream?, onProgress: (total: Int, current: Int) -> Unit = { _, _ -> }, callback: (result: ExportResult) -> Unit) {
|
||||||
outputStream: OutputStream?,
|
|
||||||
callback: (result: ExportResult) -> Unit,
|
|
||||||
) {
|
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
if (outputStream == null) {
|
if (outputStream == null) {
|
||||||
callback.invoke(ExportResult.EXPORT_FAIL)
|
callback.invoke(ExportResult.EXPORT_FAIL)
|
||||||
@@ -57,6 +54,7 @@ class MessagesExporter(private val context: Context) {
|
|||||||
messageReader.forEachSms(threadId) {
|
messageReader.forEachSms(threadId) {
|
||||||
writer.jsonValue(gson.toJson(it))
|
writer.jsonValue(gson.toJson(it))
|
||||||
written++
|
written++
|
||||||
|
onProgress.invoke(totalMessages, written)
|
||||||
}
|
}
|
||||||
writer.endArray()
|
writer.endArray()
|
||||||
}
|
}
|
||||||
@@ -68,6 +66,7 @@ class MessagesExporter(private val context: Context) {
|
|||||||
messageReader.forEachMms(threadId) {
|
messageReader.forEachMms(threadId) {
|
||||||
writer.jsonValue(gson.toJson(it))
|
writer.jsonValue(gson.toJson(it))
|
||||||
written++
|
written++
|
||||||
|
onProgress.invoke(totalMessages, written)
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.endArray()
|
writer.endArray()
|
||||||
|
@@ -2,14 +2,15 @@ package com.simplemobiletools.smsmessenger.helpers
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.Telephony
|
|
||||||
import android.provider.Telephony.*
|
import android.provider.Telephony.*
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
import com.simplemobiletools.commons.extensions.queryCursor
|
import com.simplemobiletools.commons.extensions.queryCursor
|
||||||
|
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import com.simplemobiletools.smsmessenger.extensions.*
|
import com.simplemobiletools.smsmessenger.extensions.*
|
||||||
|
import com.simplemobiletools.smsmessenger.helpers.MessagesImporter.ImportResult.*
|
||||||
import com.simplemobiletools.smsmessenger.models.ExportedMessage
|
import com.simplemobiletools.smsmessenger.models.ExportedMessage
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -19,44 +20,50 @@ class MessagesImporter(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class ImportResult {
|
enum class ImportResult {
|
||||||
IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW
|
IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL
|
||||||
}
|
}
|
||||||
|
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
private val messageWriter = MessagesWriter(context)
|
private val messageWriter = MessagesWriter(context)
|
||||||
private val config = context.config
|
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 {
|
ensureBackgroundThread {
|
||||||
if (path.isEmpty()) {
|
try {
|
||||||
callback.invoke(ImportResult.IMPORT_FAIL)
|
|
||||||
return@ensureBackgroundThread
|
|
||||||
}
|
|
||||||
|
|
||||||
val inputStream = if (path.contains("/")) {
|
val inputStream = if (path.contains("/")) {
|
||||||
File(path).inputStream()
|
File(path).inputStream()
|
||||||
} else {
|
} else {
|
||||||
context.assets.open(path)
|
context.assets.open(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
inputStream.bufferedReader().use {
|
inputStream.bufferedReader().use { reader ->
|
||||||
try {
|
val json = reader.readText()
|
||||||
val json = it.readText()
|
|
||||||
Log.d(TAG, "importMessages: json== $json")
|
Log.d(TAG, "importMessages: json== $json")
|
||||||
val type = object : TypeToken<List<ExportedMessage>>() {}.type
|
val type = object : TypeToken<List<ExportedMessage>>() {}.type
|
||||||
val messages = gson.fromJson<List<ExportedMessage>>(json, 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) {
|
for (message in messages) {
|
||||||
// add sms
|
// add sms
|
||||||
if (config.importSms) {
|
if (config.importSms) {
|
||||||
message.sms.forEach(messageWriter::writeSmsMessage)
|
message.sms.forEach { backup ->
|
||||||
|
messageWriter.writeSmsMessage(backup)
|
||||||
|
messagesImported++
|
||||||
|
onProgress.invoke(totalMessages, messagesImported)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// add mms
|
// add mms
|
||||||
if (config.importMms) {
|
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 ->
|
context.queryCursor(Threads.CONTENT_URI) { cursor ->
|
||||||
val json = cursor.rowsToJson()
|
val json = cursor.rowsToJson()
|
||||||
Log.w(TAG, "converations = $json")
|
Log.w(TAG, "converations = $json")
|
||||||
@@ -78,13 +85,22 @@ class MessagesImporter(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refreshMessages()
|
refreshMessages()
|
||||||
callback.invoke(ImportResult.IMPORT_OK)
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(TAG, "importMessages: ", e)
|
|
||||||
callback.invoke(ImportResult.IMPORT_FAIL)
|
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
context.showErrorToast(e)
|
||||||
|
messagesFailed++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback.invoke(
|
||||||
|
when {
|
||||||
|
messagesImported == 0 -> {
|
||||||
|
IMPORT_FAIL
|
||||||
|
}
|
||||||
|
messagesFailed > 0 -> IMPORT_PARTIAL
|
||||||
|
else -> IMPORT_OK
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -107,7 +107,29 @@ class MessagesReader(private val context: Context) {
|
|||||||
|
|
||||||
val parts = getParts(mmsId)
|
val parts = getParts(mmsId)
|
||||||
val addresses = getMMSAddresses(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
|
return addresses
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMessagesCount(): Long {
|
fun getMessagesCount(): Int {
|
||||||
return 0
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,8 +42,6 @@ class MessagesWriter(private val context: Context) {
|
|||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "SMS already exists")
|
Log.w(TAG, "SMS already exists")
|
||||||
}
|
}
|
||||||
// update conversation date
|
|
||||||
updateThreadDate(threadId, smsBackup.date)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateThreadDate(
|
private fun updateThreadDate(
|
||||||
@@ -86,7 +84,6 @@ class MessagesWriter(private val context: Context) {
|
|||||||
//write mms
|
//write mms
|
||||||
if (!mmsExist(mmsBackup)) {
|
if (!mmsExist(mmsBackup)) {
|
||||||
contentResolver.insert(Mms.CONTENT_URI, contentValues)
|
contentResolver.insert(Mms.CONTENT_URI, contentValues)
|
||||||
updateThreadDate(threadId, mmsBackup.date)
|
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "mms already exists")
|
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 uri = Uri.parse("content://mms/${messageId}/part")
|
||||||
val projection = arrayOf(Mms.Part._ID)
|
val projection = arrayOf(Mms.Part._ID)
|
||||||
val selection =
|
val selection =
|
||||||
"${Mms.Part.CONTENT_LOCATION} = ? AND ${Mms.Part.CT_TYPE} = ? AND ${Mms.Part.MSG_ID} = ? AND ${Mms.Part.CONTENT_ID} = ?"
|
"${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.toString(), messageId.toString(), mmsPart.contentId.toString())
|
val selectionArgs = arrayOf(mmsPart.contentLocation.toString(), mmsPart.contentType, messageId.toString(), mmsPart.contentId.toString())
|
||||||
var exists = false
|
var exists = false
|
||||||
context.queryCursor(uri, projection, selection, selectionArgs) {
|
context.queryCursor(uri, projection, selection, selectionArgs) {
|
||||||
exists = it.count > 0
|
exists = it.count > 0
|
||||||
|
Reference in New Issue
Block a user