From eb4be51f927b957cb61eae40906decd6cb3551ee Mon Sep 17 00:00:00 2001 From: tibbi Date: Mon, 16 Mar 2020 23:09:25 +0100 Subject: [PATCH] pass an OutputStream to exporter instead of a File --- .../contacts/pro/activities/MainActivity.kt | 14 +- .../contacts/pro/extensions/Activity.kt | 16 +- .../contacts/pro/helpers/VcfExporter.kt | 238 +++++++++--------- 3 files changed, 133 insertions(+), 135 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt index 61095ba2..388a6088 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt @@ -526,12 +526,14 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { if (contacts.isEmpty()) { toast(R.string.no_entries_for_exporting) } else { - VcfExporter().exportContacts(this, file, contacts, true) { result -> - toast(when (result) { - VcfExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful - VcfExporter.ExportResult.EXPORT_PARTIAL -> R.string.exporting_some_entries_failed - else -> R.string.exporting_failed - }) + getFileOutputStream(file.toFileDirItem(this), true) { + VcfExporter().exportContacts(this, it, contacts, true) { result -> + toast(when (result) { + VcfExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful + VcfExporter.ExportResult.EXPORT_PARTIAL -> R.string.exporting_some_entries_failed + else -> R.string.exporting_failed + }) + } } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt index 9995e35c..b2962b87 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt @@ -4,9 +4,7 @@ import android.content.Intent import android.net.Uri import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.dialogs.RadioGroupDialog -import com.simplemobiletools.commons.extensions.sharePathIntent -import com.simplemobiletools.commons.extensions.showErrorToast -import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.PERMISSION_CALL_PHONE import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.contacts.pro.BuildConfig @@ -92,11 +90,13 @@ fun BaseSimpleActivity.shareContacts(contacts: ArrayList) { return } - VcfExporter().exportContacts(this, file, contacts, false) { - if (it == VcfExporter.ExportResult.EXPORT_OK) { - sharePathIntent(file.absolutePath, BuildConfig.APPLICATION_ID) - } else { - showErrorToast("$it") + getFileOutputStream(file.toFileDirItem(this), true) { + VcfExporter().exportContacts(this, it, contacts, false) { + if (it == VcfExporter.ExportResult.EXPORT_OK) { + sharePathIntent(file.absolutePath, BuildConfig.APPLICATION_ID) + } else { + showErrorToast("$it") + } } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfExporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfExporter.kt index 50ee8763..c9633926 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfExporter.kt @@ -4,9 +4,7 @@ import android.net.Uri import android.provider.ContactsContract.CommonDataKinds import android.provider.MediaStore import com.simplemobiletools.commons.activities.BaseSimpleActivity -import com.simplemobiletools.commons.extensions.getFileOutputStream import com.simplemobiletools.commons.extensions.showErrorToast -import com.simplemobiletools.commons.extensions.toFileDirItem import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.extensions.getByteArray @@ -18,7 +16,7 @@ import ezvcard.VCard import ezvcard.parameter.ImageType import ezvcard.property.* import ezvcard.util.PartialDate -import java.io.File +import java.io.OutputStream import java.util.* class VcfExporter { @@ -29,140 +27,138 @@ class VcfExporter { private var contactsExported = 0 private var contactsFailed = 0 - fun exportContacts(activity: BaseSimpleActivity, file: File, contacts: ArrayList, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) { - activity.getFileOutputStream(file.toFileDirItem(activity), true) { - try { - if (it == null) { - callback(EXPORT_FAIL) - return@getFileOutputStream + fun exportContacts(activity: BaseSimpleActivity, outputStream: OutputStream?, contacts: ArrayList, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) { + try { + if (outputStream == null) { + callback(EXPORT_FAIL) + return + } + + if (showExportingToast) { + activity.toast(R.string.exporting) + } + + val cards = ArrayList() + for (contact in contacts) { + val card = VCard() + StructuredName().apply { + prefixes.add(contact.prefix) + given = contact.firstName + additionalNames.add(contact.middleName) + family = contact.surname + suffixes.add(contact.suffix) + card.structuredName = this } - if (showExportingToast) { - activity.toast(R.string.exporting) + if (contact.nickname.isNotEmpty()) { + card.setNickname(contact.nickname) } - val cards = ArrayList() - for (contact in contacts) { - val card = VCard() - StructuredName().apply { - prefixes.add(contact.prefix) - given = contact.firstName - additionalNames.add(contact.middleName) - family = contact.surname - suffixes.add(contact.suffix) - card.structuredName = this - } + contact.phoneNumbers.forEach { + val phoneNumber = Telephone(it.value) + phoneNumber.parameters.addType(getPhoneNumberTypeLabel(it.type, it.label)) + card.addTelephoneNumber(phoneNumber) + } - if (contact.nickname.isNotEmpty()) { - card.setNickname(contact.nickname) - } + contact.emails.forEach { + val email = Email(it.value) + email.parameters.addType(getEmailTypeLabel(it.type, it.label)) + card.addEmail(email) + } - contact.phoneNumbers.forEach { - val phoneNumber = Telephone(it.value) - phoneNumber.parameters.addType(getPhoneNumberTypeLabel(it.type, it.label)) - card.addTelephoneNumber(phoneNumber) - } - - contact.emails.forEach { - val email = Email(it.value) - email.parameters.addType(getEmailTypeLabel(it.type, it.label)) - card.addEmail(email) - } - - contact.events.forEach { - if (it.type == CommonDataKinds.Event.TYPE_ANNIVERSARY || it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) { - val dateTime = it.value.getDateTimeFromDateString() - if (it.value.startsWith("--")) { - val partialDate = PartialDate.builder().year(null).month(dateTime.monthOfYear).date(dateTime.dayOfMonth).build() - if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) { - card.birthdays.add(Birthday(partialDate)) - } else { - card.anniversaries.add(Anniversary(partialDate)) - } + contact.events.forEach { + if (it.type == CommonDataKinds.Event.TYPE_ANNIVERSARY || it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) { + val dateTime = it.value.getDateTimeFromDateString() + if (it.value.startsWith("--")) { + val partialDate = PartialDate.builder().year(null).month(dateTime.monthOfYear).date(dateTime.dayOfMonth).build() + if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) { + card.birthdays.add(Birthday(partialDate)) } else { - Calendar.getInstance().apply { - clear() - set(Calendar.YEAR, dateTime.year) - set(Calendar.MONTH, dateTime.monthOfYear - 1) - set(Calendar.DAY_OF_MONTH, dateTime.dayOfMonth) - if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) { - card.birthdays.add(Birthday(time)) - } else { - card.anniversaries.add(Anniversary(time)) - } + card.anniversaries.add(Anniversary(partialDate)) + } + } else { + Calendar.getInstance().apply { + clear() + set(Calendar.YEAR, dateTime.year) + set(Calendar.MONTH, dateTime.monthOfYear - 1) + set(Calendar.DAY_OF_MONTH, dateTime.dayOfMonth) + if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) { + card.birthdays.add(Birthday(time)) + } else { + card.anniversaries.add(Anniversary(time)) } } } } - - contact.addresses.forEach { - val address = Address() - address.streetAddress = it.value - address.parameters.addType(getAddressTypeLabel(it.type, it.label)) - card.addAddress(address) - } - - contact.IMs.forEach { - val impp = when (it.type) { - CommonDataKinds.Im.PROTOCOL_AIM -> Impp.aim(it.value) - CommonDataKinds.Im.PROTOCOL_YAHOO -> Impp.yahoo(it.value) - CommonDataKinds.Im.PROTOCOL_MSN -> Impp.msn(it.value) - CommonDataKinds.Im.PROTOCOL_ICQ -> Impp.icq(it.value) - CommonDataKinds.Im.PROTOCOL_SKYPE -> Impp.skype(it.value) - CommonDataKinds.Im.PROTOCOL_GOOGLE_TALK -> Impp(HANGOUTS, it.value) - CommonDataKinds.Im.PROTOCOL_QQ -> Impp(QQ, it.value) - CommonDataKinds.Im.PROTOCOL_JABBER -> Impp(JABBER, it.value) - else -> Impp(it.label, it.value) - } - - card.addImpp(impp) - } - - if (contact.notes.isNotEmpty()) { - card.addNote(contact.notes) - } - - if (contact.organization.isNotEmpty()) { - val organization = Organization() - organization.values.add(contact.organization.company) - card.organization = organization - card.titles.add(Title(contact.organization.jobPosition)) - } - - contact.websites.forEach { - card.addUrl(it) - } - - if (contact.thumbnailUri.isNotEmpty()) { - val photoByteArray = MediaStore.Images.Media.getBitmap(activity.contentResolver, Uri.parse(contact.thumbnailUri)).getByteArray() - val photo = Photo(photoByteArray, ImageType.JPEG) - card.addPhoto(photo) - } - - if (contact.groups.isNotEmpty()) { - val groupList = Categories() - contact.groups.forEach { - groupList.values.add(it.title) - } - - card.categories = groupList - } - - cards.add(card) - contactsExported++ } - Ezvcard.write(cards).go(it) - } catch (e: Exception) { - activity.showErrorToast(e) + contact.addresses.forEach { + val address = Address() + address.streetAddress = it.value + address.parameters.addType(getAddressTypeLabel(it.type, it.label)) + card.addAddress(address) + } + + contact.IMs.forEach { + val impp = when (it.type) { + CommonDataKinds.Im.PROTOCOL_AIM -> Impp.aim(it.value) + CommonDataKinds.Im.PROTOCOL_YAHOO -> Impp.yahoo(it.value) + CommonDataKinds.Im.PROTOCOL_MSN -> Impp.msn(it.value) + CommonDataKinds.Im.PROTOCOL_ICQ -> Impp.icq(it.value) + CommonDataKinds.Im.PROTOCOL_SKYPE -> Impp.skype(it.value) + CommonDataKinds.Im.PROTOCOL_GOOGLE_TALK -> Impp(HANGOUTS, it.value) + CommonDataKinds.Im.PROTOCOL_QQ -> Impp(QQ, it.value) + CommonDataKinds.Im.PROTOCOL_JABBER -> Impp(JABBER, it.value) + else -> Impp(it.label, it.value) + } + + card.addImpp(impp) + } + + if (contact.notes.isNotEmpty()) { + card.addNote(contact.notes) + } + + if (contact.organization.isNotEmpty()) { + val organization = Organization() + organization.values.add(contact.organization.company) + card.organization = organization + card.titles.add(Title(contact.organization.jobPosition)) + } + + contact.websites.forEach { + card.addUrl(it) + } + + if (contact.thumbnailUri.isNotEmpty()) { + val photoByteArray = MediaStore.Images.Media.getBitmap(activity.contentResolver, Uri.parse(contact.thumbnailUri)).getByteArray() + val photo = Photo(photoByteArray, ImageType.JPEG) + card.addPhoto(photo) + } + + if (contact.groups.isNotEmpty()) { + val groupList = Categories() + contact.groups.forEach { + groupList.values.add(it.title) + } + + card.categories = groupList + } + + cards.add(card) + contactsExported++ } - callback(when { - contactsExported == 0 -> EXPORT_FAIL - contactsFailed > 0 -> ExportResult.EXPORT_PARTIAL - else -> ExportResult.EXPORT_OK - }) + Ezvcard.write(cards).go(outputStream) + } catch (e: Exception) { + activity.showErrorToast(e) } + + callback(when { + contactsExported == 0 -> EXPORT_FAIL + contactsFailed > 0 -> ExportResult.EXPORT_PARTIAL + else -> ExportResult.EXPORT_OK + }) } private fun getPhoneNumberTypeLabel(type: Int, label: String) = when (type) {