From 84be33dbbf8adf6c33c04dc143dc50837a7fa3cf Mon Sep 17 00:00:00 2001 From: tibbi Date: Mon, 25 Dec 2017 23:06:20 +0100 Subject: [PATCH] handle the contact photo at inserting too --- .../contacts/activities/ContactActivity.kt | 19 ++- .../contacts/helpers/ContactsHelper.kt | 111 +++++++++++++++--- app/src/main/res/values-de/strings.xml | 2 + app/src/main/res/values-ko-rKR/strings.xml | 2 + app/src/main/res/values-pt/strings.xml | 2 + app/src/main/res/values-ru/strings.xml | 2 + app/src/main/res/values-sk/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 8 files changed, 122 insertions(+), 20 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ContactActivity.kt index c60c6942..5ec04f0d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ContactActivity.kt @@ -60,6 +60,7 @@ class ContactActivity : SimpleActivity() { private var currentContactPhotoPath = "" private var lastPhotoIntentUri: Uri? = null private var contact: Contact? = null + private var isSaving = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -321,6 +322,10 @@ class ContactActivity : SimpleActivity() { } private fun saveContact() { + if (isSaving) { + return + } + contact!!.apply { firstName = contact_first_name.value middleName = contact_middle_name.value @@ -330,11 +335,13 @@ class ContactActivity : SimpleActivity() { emails = getFilledEmails() source = contact_source.value - if (id == 0) { - insertNewContact() - } else { - updateContact() - } + Thread { + if (id == 0) { + insertNewContact() + } else { + updateContact() + } + }.start() } } @@ -369,6 +376,7 @@ class ContactActivity : SimpleActivity() { } private fun insertNewContact() { + isSaving = true if (ContactsHelper(this@ContactActivity).insertContact(contact!!)) { finish() } else { @@ -377,6 +385,7 @@ class ContactActivity : SimpleActivity() { } private fun updateContact() { + isSaving = true if (ContactsHelper(this@ContactActivity).updateContact(contact!!)) { finish() } else { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index 4d990507..73b145dc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -1,24 +1,33 @@ package com.simplemobiletools.contacts.helpers import android.content.ContentProviderOperation +import android.content.ContentProviderResult +import android.content.ContentUris import android.database.Cursor +import android.graphics.Bitmap +import android.net.Uri import android.provider.ContactsContract +import android.provider.MediaStore import android.util.SparseArray import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.getIntValue import com.simplemobiletools.commons.extensions.getStringValue import com.simplemobiletools.commons.extensions.showErrorToast +import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.commons.helpers.SORT_BY_FIRST_NAME import com.simplemobiletools.commons.helpers.SORT_BY_MIDDLE_NAME import com.simplemobiletools.commons.helpers.SORT_BY_SURNAME import com.simplemobiletools.commons.helpers.SORT_DESCENDING +import com.simplemobiletools.contacts.R import com.simplemobiletools.contacts.extensions.config import com.simplemobiletools.contacts.models.Contact import com.simplemobiletools.contacts.models.Email import com.simplemobiletools.contacts.models.PhoneNumber import com.simplemobiletools.contacts.overloads.times +import java.io.ByteArrayOutputStream import java.util.* + class ContactsHelper(val activity: BaseSimpleActivity) { fun getContactSources(callback: (ArrayList) -> Unit) { val accounts = HashSet() @@ -107,20 +116,6 @@ class ContactsHelper(val activity: BaseSimpleActivity) { }.start() } - fun doesSourceContainContacts(source: String): Boolean { - val uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI - val projection = arrayOf(ContactsContract.CommonDataKinds.Email.CONTACT_ID) - val selection = "${ContactsContract.RawContacts.ACCOUNT_NAME} = ?" - val selectionArgs = arrayOf(source) - var cursor: Cursor? = null - try { - cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) - return (cursor?.moveToFirst() == true) - } finally { - cursor?.close() - } - } - private fun getEmails(contactId: Int? = null): SparseArray> { val emails = SparseArray>() val uri = ContactsContract.CommonDataKinds.Email.CONTENT_URI @@ -304,6 +299,7 @@ class ContactsHelper(val activity: BaseSimpleActivity) { fun insertContact(contact: Contact): Boolean { return try { + activity.toast(R.string.inserting) val operations = ArrayList() ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI).apply { withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null) @@ -343,7 +339,52 @@ class ContactsHelper(val activity: BaseSimpleActivity) { } } - activity.contentResolver.applyBatch(ContactsContract.AUTHORITY, operations) + // photo (inspired by https://gist.github.com/slightfoot/5985900) + var fullSizePhotoData: ByteArray? = null + var scaledSizePhotoData: ByteArray? + if (contact.photoUri.isNotEmpty()) { + val photoUri = Uri.parse(contact.photoUri) + val bitmap = MediaStore.Images.Media.getBitmap(activity.contentResolver, photoUri) + + val thumbnailSize = getThumbnailSize() + val scaledPhoto = Bitmap.createScaledBitmap(bitmap, thumbnailSize, thumbnailSize, false) + scaledSizePhotoData = bitmapToByteArray(scaledPhoto) + scaledPhoto.recycle() + + fullSizePhotoData = bitmapToByteArray(bitmap) + bitmap.recycle() + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply { + withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE) + withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, scaledSizePhotoData) + operations.add(this.build()) + } + } + + val results: Array + try { + results = activity.contentResolver.applyBatch(ContactsContract.AUTHORITY, operations) + } finally { + scaledSizePhotoData = null + } + + // fullsize photo + if (contact.photoUri.isNotEmpty() && fullSizePhotoData != null) { + val rawContactId = ContentUris.parseId(results[0].uri) + val baseUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId) + val displayPhotoUri = Uri.withAppendedPath(baseUri, ContactsContract.RawContacts.DisplayPhoto.CONTENT_DIRECTORY) + val photoStream = activity.contentResolver.openAssetFileDescriptor(displayPhotoUri, "rw").createOutputStream() + photoStream.use { + var bufferSize = 16 * 1024 + var offset = 0 + while (offset < fullSizePhotoData.size) { + bufferSize = Math.min(bufferSize, fullSizePhotoData.size - offset) + photoStream.write(fullSizePhotoData, offset, bufferSize) + offset += bufferSize + } + } + } + true } catch (e: Exception) { activity.showErrorToast(e) @@ -351,6 +392,17 @@ class ContactsHelper(val activity: BaseSimpleActivity) { } } + private fun bitmapToByteArray(bitmap: Bitmap): ByteArray { + var baos: ByteArrayOutputStream? = null + try { + baos = ByteArrayOutputStream() + bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos) + return baos.toByteArray() + } finally { + baos?.close() + } + } + fun deleteContact(contact: Contact) = deleteContacts(arrayListOf(contact)) fun deleteContacts(contacts: ArrayList) { @@ -366,4 +418,33 @@ class ContactsHelper(val activity: BaseSimpleActivity) { activity.showErrorToast(e) } } + + fun doesSourceContainContacts(source: String): Boolean { + val uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI + val projection = arrayOf(ContactsContract.CommonDataKinds.Email.CONTACT_ID) + val selection = "${ContactsContract.RawContacts.ACCOUNT_NAME} = ?" + val selectionArgs = arrayOf(source) + var cursor: Cursor? = null + try { + cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) + return (cursor?.moveToFirst() == true) + } finally { + cursor?.close() + } + } + + private fun getThumbnailSize(): Int { + var cursor: Cursor? = null + try { + val uri = ContactsContract.DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI + val projection = arrayOf(ContactsContract.DisplayPhoto.THUMBNAIL_MAX_DIM) + cursor = activity.contentResolver.query(uri, projection, null, null, null) + if (cursor?.moveToFirst() == true) { + return cursor.getIntValue(ContactsContract.DisplayPhoto.THUMBNAIL_MAX_DIM) + } + } finally { + cursor?.close() + } + return 0 + } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index bfbfb253..6b50fa45 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -2,6 +2,8 @@ Schlichte Kontakte Kontakte Adresse + Inserting… + Updating… Neuer Kontakt Kontakt bearbeiten diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 67373348..6ae63e44 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -2,6 +2,8 @@ 심플 연락처 연락처 주소 + Inserting… + Updating… 새로운 연락처 연락처 수정 diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 4be2d8d8..a2312cba 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -2,6 +2,8 @@ Simple Contacts Contactos Address + Inserting… + Updating… Novo contacto Editar contacto diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index a5b7b54d..d7198011 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -2,6 +2,8 @@ Simple Contacts Контакты Адрес + Inserting… + Updating… Новый контакт Редактировать контакт diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 168621e3..ef41a4cb 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -2,6 +2,8 @@ Jednoduché kontakty Kontakty Adresa + Vytvára sa… + Upravuje sa… Nový kontakt Upraviť kontakt diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d52c7d2e..be2f078b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,6 +2,8 @@ Simple Contacts Contacts Address + Inserting… + Updating… New contact Edit contact