pass an OutputStream to exporter instead of a File

This commit is contained in:
tibbi
2020-03-16 23:09:25 +01:00
parent fbfe7133ca
commit eb4be51f92
3 changed files with 133 additions and 135 deletions

View File

@ -526,12 +526,14 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
if (contacts.isEmpty()) { if (contacts.isEmpty()) {
toast(R.string.no_entries_for_exporting) toast(R.string.no_entries_for_exporting)
} else { } else {
VcfExporter().exportContacts(this, file, contacts, true) { result -> getFileOutputStream(file.toFileDirItem(this), true) {
toast(when (result) { VcfExporter().exportContacts(this, it, contacts, true) { result ->
VcfExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful toast(when (result) {
VcfExporter.ExportResult.EXPORT_PARTIAL -> R.string.exporting_some_entries_failed VcfExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful
else -> R.string.exporting_failed VcfExporter.ExportResult.EXPORT_PARTIAL -> R.string.exporting_some_entries_failed
}) else -> R.string.exporting_failed
})
}
} }
} }
} }

View File

@ -4,9 +4,7 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.sharePathIntent import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.helpers.PERMISSION_CALL_PHONE import com.simplemobiletools.commons.helpers.PERMISSION_CALL_PHONE
import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.BuildConfig
@ -92,11 +90,13 @@ fun BaseSimpleActivity.shareContacts(contacts: ArrayList<Contact>) {
return return
} }
VcfExporter().exportContacts(this, file, contacts, false) { getFileOutputStream(file.toFileDirItem(this), true) {
if (it == VcfExporter.ExportResult.EXPORT_OK) { VcfExporter().exportContacts(this, it, contacts, false) {
sharePathIntent(file.absolutePath, BuildConfig.APPLICATION_ID) if (it == VcfExporter.ExportResult.EXPORT_OK) {
} else { sharePathIntent(file.absolutePath, BuildConfig.APPLICATION_ID)
showErrorToast("$it") } else {
showErrorToast("$it")
}
} }
} }
} }

View File

@ -4,9 +4,7 @@ import android.net.Uri
import android.provider.ContactsContract.CommonDataKinds import android.provider.ContactsContract.CommonDataKinds
import android.provider.MediaStore import android.provider.MediaStore
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.getFileOutputStream
import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.extensions.toFileDirItem
import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.extensions.getByteArray import com.simplemobiletools.contacts.pro.extensions.getByteArray
@ -18,7 +16,7 @@ import ezvcard.VCard
import ezvcard.parameter.ImageType import ezvcard.parameter.ImageType
import ezvcard.property.* import ezvcard.property.*
import ezvcard.util.PartialDate import ezvcard.util.PartialDate
import java.io.File import java.io.OutputStream
import java.util.* import java.util.*
class VcfExporter { class VcfExporter {
@ -29,140 +27,138 @@ class VcfExporter {
private var contactsExported = 0 private var contactsExported = 0
private var contactsFailed = 0 private var contactsFailed = 0
fun exportContacts(activity: BaseSimpleActivity, file: File, contacts: ArrayList<Contact>, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) { fun exportContacts(activity: BaseSimpleActivity, outputStream: OutputStream?, contacts: ArrayList<Contact>, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) {
activity.getFileOutputStream(file.toFileDirItem(activity), true) { try {
try { if (outputStream == null) {
if (it == null) { callback(EXPORT_FAIL)
callback(EXPORT_FAIL) return
return@getFileOutputStream }
if (showExportingToast) {
activity.toast(R.string.exporting)
}
val cards = ArrayList<VCard>()
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) { if (contact.nickname.isNotEmpty()) {
activity.toast(R.string.exporting) card.setNickname(contact.nickname)
} }
val cards = ArrayList<VCard>() contact.phoneNumbers.forEach {
for (contact in contacts) { val phoneNumber = Telephone(it.value)
val card = VCard() phoneNumber.parameters.addType(getPhoneNumberTypeLabel(it.type, it.label))
StructuredName().apply { card.addTelephoneNumber(phoneNumber)
prefixes.add(contact.prefix) }
given = contact.firstName
additionalNames.add(contact.middleName)
family = contact.surname
suffixes.add(contact.suffix)
card.structuredName = this
}
if (contact.nickname.isNotEmpty()) { contact.emails.forEach {
card.setNickname(contact.nickname) val email = Email(it.value)
} email.parameters.addType(getEmailTypeLabel(it.type, it.label))
card.addEmail(email)
}
contact.phoneNumbers.forEach { contact.events.forEach {
val phoneNumber = Telephone(it.value) if (it.type == CommonDataKinds.Event.TYPE_ANNIVERSARY || it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) {
phoneNumber.parameters.addType(getPhoneNumberTypeLabel(it.type, it.label)) val dateTime = it.value.getDateTimeFromDateString()
card.addTelephoneNumber(phoneNumber) if (it.value.startsWith("--")) {
} val partialDate = PartialDate.builder().year(null).month(dateTime.monthOfYear).date(dateTime.dayOfMonth).build()
if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) {
contact.emails.forEach { card.birthdays.add(Birthday(partialDate))
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))
}
} else { } else {
Calendar.getInstance().apply { card.anniversaries.add(Anniversary(partialDate))
clear() }
set(Calendar.YEAR, dateTime.year) } else {
set(Calendar.MONTH, dateTime.monthOfYear - 1) Calendar.getInstance().apply {
set(Calendar.DAY_OF_MONTH, dateTime.dayOfMonth) clear()
if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) { set(Calendar.YEAR, dateTime.year)
card.birthdays.add(Birthday(time)) set(Calendar.MONTH, dateTime.monthOfYear - 1)
} else { set(Calendar.DAY_OF_MONTH, dateTime.dayOfMonth)
card.anniversaries.add(Anniversary(time)) 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) contact.addresses.forEach {
} catch (e: Exception) { val address = Address()
activity.showErrorToast(e) 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 { Ezvcard.write(cards).go(outputStream)
contactsExported == 0 -> EXPORT_FAIL } catch (e: Exception) {
contactsFailed > 0 -> ExportResult.EXPORT_PARTIAL activity.showErrorToast(e)
else -> ExportResult.EXPORT_OK
})
} }
callback(when {
contactsExported == 0 -> EXPORT_FAIL
contactsFailed > 0 -> ExportResult.EXPORT_PARTIAL
else -> ExportResult.EXPORT_OK
})
} }
private fun getPhoneNumberTypeLabel(type: Int, label: String) = when (type) { private fun getPhoneNumberTypeLabel(type: Int, label: String) = when (type) {