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()) {
 | 
			
		||||
                    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) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user