mirror of
https://github.com/SimpleMobileTools/Simple-Contacts.git
synced 2025-06-05 21:59:27 +02:00
pass an OutputStream to exporter instead of a File
This commit is contained in:
@ -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
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Reference in New Issue
Block a user