pass an OutputStream to exporter instead of a File
This commit is contained in:
parent
fbfe7133ca
commit
eb4be51f92
3 changed files with 133 additions and 135 deletions
|
@ -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
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Contact>) {
|
|||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Contact>, 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<Contact>, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) {
|
||||
try {
|
||||
if (outputStream == null) {
|
||||
callback(EXPORT_FAIL)
|
||||
return
|
||||
}
|
||||
|
||||
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) {
|
||||
activity.toast(R.string.exporting)
|
||||
if (contact.nickname.isNotEmpty()) {
|
||||
card.setNickname(contact.nickname)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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) {
|
||||
|
|
Loading…
Reference in a new issue