Merge pull request #4 from SimpleMobileTools/master

update
This commit is contained in:
solokot 2018-02-01 20:16:11 +03:00 committed by GitHub
commit d8c4c340b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 227 additions and 174 deletions

View File

@ -1,6 +1,12 @@
Changelog
==========
Version 3.1.3 *(2018-01-29)*
----------------------------
* Allow hiding contact thumbnails
* Fix displaying and adding contacts on some devices
Version 3.1.2 *(2018-01-23)*
----------------------------

View File

@ -10,8 +10,8 @@ android {
applicationId "com.simplemobiletools.contacts"
minSdkVersion 16
targetSdkVersion 27
versionCode 7
versionName "3.1.2"
versionCode 8
versionName "3.1.3"
setProperty("archivesBaseName", "contacts")
}
@ -42,7 +42,7 @@ ext {
}
dependencies {
implementation 'com.simplemobiletools:commons:3.8.2'
implementation 'com.simplemobiletools:commons:3.9.5'
implementation 'joda-time:joda-time:2.9.9'
debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakCanaryVersion"

View File

@ -75,7 +75,7 @@
android:parentActivityName=".activities.MainActivity"/>
<activity
android:name=".activities.ContactActivity"
android:name=".activities.EditContactActivity"
android:parentActivityName=".activities.MainActivity">
<intent-filter>

View File

@ -38,7 +38,7 @@ import com.simplemobiletools.contacts.models.Contact
import com.simplemobiletools.contacts.models.Email
import com.simplemobiletools.contacts.models.Event
import com.simplemobiletools.contacts.models.PhoneNumber
import kotlinx.android.synthetic.main.activity_contact.*
import kotlinx.android.synthetic.main.activity_edit_contact.*
import kotlinx.android.synthetic.main.item_email.view.*
import kotlinx.android.synthetic.main.item_event.view.*
import kotlinx.android.synthetic.main.item_phone_number.view.*
@ -48,7 +48,7 @@ import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
class ContactActivity : SimpleActivity() {
class EditContactActivity : SimpleActivity() {
private val INTENT_TAKE_PHOTO = 1
private val INTENT_CHOOSE_PHOTO = 2
private val INTENT_CROP_PHOTO = 3
@ -67,7 +67,7 @@ class ContactActivity : SimpleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_contact)
setContentView(R.layout.activity_edit_contact)
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_cross)
handlePermission(PERMISSION_READ_CONTACTS) {
@ -120,8 +120,8 @@ class ContactActivity : SimpleActivity() {
var contactId = intent.getIntExtra(CONTACT_ID, 0)
val action = intent.action
if (contactId == 0 && (action == ContactsContract.QuickContact.ACTION_QUICK_CONTACT ||
action == Intent.ACTION_VIEW ||
action == Intent.ACTION_EDIT)) {
action == Intent.ACTION_VIEW ||
action == Intent.ACTION_EDIT)) {
val data = intent.data
if (data != null) {
val rawId = if (data.path.contains("lookup")) {
@ -505,11 +505,6 @@ class ContactActivity : SimpleActivity() {
return
}
if (contact_source.value.isEmpty()) {
toast(R.string.missing_contact_account)
return
}
contact!!.apply {
val oldPhotoUri = photoUri
@ -584,7 +579,7 @@ class ContactActivity : SimpleActivity() {
private fun insertNewContact() {
isSaving = true
toast(R.string.inserting)
if (ContactsHelper(this@ContactActivity).insertContact(contact!!)) {
if (ContactsHelper(this@EditContactActivity).insertContact(contact!!)) {
finish()
} else {
toast(R.string.unknown_error_occurred)
@ -593,7 +588,7 @@ class ContactActivity : SimpleActivity() {
private fun updateContact(photoUpdateStatus: Int) {
isSaving = true
if (ContactsHelper(this@ContactActivity).updateContact(contact!!, photoUpdateStatus)) {
if (ContactsHelper(this@EditContactActivity).updateContact(contact!!, photoUpdateStatus)) {
finish()
} else {
toast(R.string.unknown_error_occurred)

View File

@ -77,14 +77,15 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
return
}
if (storedShowContactThumbnails != config.showContactThumbnails) {
if (storedShowPhoneNumbers != config.showPhoneNumbers) {
restartActivity()
return
}
if (storedShowPhoneNumbers != config.showPhoneNumbers) {
restartActivity()
return
val configShowContactThumbnails = config.showContactThumbnails
if (storedShowContactThumbnails != configShowContactThumbnails) {
contacts_fragment.showContactThumbnailsChanged(configShowContactThumbnails)
favorites_fragment.showContactThumbnailsChanged(configShowContactThumbnails)
}
val configTextColor = config.textColor
@ -217,13 +218,11 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
private fun initFragments() {
viewpager.adapter = ViewPagerAdapter(this)
viewpager.setOnPageChangeListener(object : ViewPager.OnPageChangeListener {
viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
if (isSearchOpen) {
getCurrentFragment().onSearchQueryChanged("")
if (searchMenuItem != null) {
MenuItemCompat.collapseActionView(searchMenuItem)
}
searchMenuItem?.collapseActionView()
}
}

View File

@ -27,16 +27,19 @@ import com.simplemobiletools.contacts.models.Contact
import kotlinx.android.synthetic.main.item_contact_with_number.view.*
import java.util.*
class ContactsAdapter(activity: SimpleActivity, var contactItems: MutableList<Contact>, val listener: RefreshContactsListener?,
val isFavoritesFragment: Boolean, recyclerView: MyRecyclerView, fastScroller: FastScroller, itemClick: (Any) -> Unit) :
class ContactsAdapter(activity: SimpleActivity, var contactItems: MutableList<Contact>, private val listener: RefreshContactsListener?,
private val isFavoritesFragment: Boolean, recyclerView: MyRecyclerView, fastScroller: FastScroller, itemClick: (Any) -> Unit) :
MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
lateinit private var contactDrawable: Drawable
private lateinit var contactDrawable: Drawable
var config = activity.config
var startNameWithSurname: Boolean
var showContactThumbnails: Boolean
var showPhoneNumbers: Boolean
private var smallPadding = activity.resources.getDimension(R.dimen.small_margin).toInt()
private var bigPadding = activity.resources.getDimension(R.dimen.normal_margin).toInt()
init {
initDrawables()
showContactThumbnails = config.showContactThumbnails
@ -190,8 +193,12 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: MutableList<Co
view.apply {
contact_name.text = contact.getFullName(startNameWithSurname)
contact_name.setTextColor(textColor)
contact_name.setPadding(if (showContactThumbnails) smallPadding else bigPadding, smallPadding, smallPadding, 0)
contact_number?.text = contact.phoneNumbers.firstOrNull()?.value ?: ""
contact_number?.setTextColor(textColor)
contact_number?.setPadding(if (showContactThumbnails) smallPadding else bigPadding, 0, smallPadding, 0)
contact_tmb.beVisibleIf(showContactThumbnails)
if (showContactThumbnails) {

View File

@ -12,7 +12,7 @@ import com.simplemobiletools.contacts.extensions.config
import kotlinx.android.synthetic.main.item_filter_contact_source.view.*
import java.util.*
class FilterContactSourcesAdapter(val activity: SimpleActivity, val contactSources: List<String>, val displayContactSources: Set<String>) :
class FilterContactSourcesAdapter(val activity: SimpleActivity, private val contactSources: List<String>, private val displayContactSources: Set<String>) :
RecyclerView.Adapter<FilterContactSourcesAdapter.ViewHolder>() {
private val itemViews = SparseArray<View>()
private val selectedPositions = HashSet<Int>()
@ -66,7 +66,7 @@ class FilterContactSourcesAdapter(val activity: SimpleActivity, val contactSourc
override fun getItemCount() = contactSources.size
class ViewHolder(view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity) : RecyclerView.ViewHolder(view) {
class ViewHolder(view: View, private val adapterListener: MyAdapterListener, val activity: SimpleActivity) : RecyclerView.ViewHolder(view) {
fun bindView(contactSource: String): View {
itemView.apply {
filter_contact_source_checkbox.setColors(activity.config.textColor, activity.getAdjustedPrimaryColor(), activity.config.backgroundColor)

View File

@ -13,6 +13,7 @@ import com.bumptech.glide.signature.ObjectKey
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
import com.simplemobiletools.commons.extensions.getColoredDrawableWithColor
import com.simplemobiletools.commons.extensions.isActivityDestroyed
import com.simplemobiletools.commons.interfaces.MyAdapterListener
import com.simplemobiletools.contacts.R
import com.simplemobiletools.contacts.activities.SimpleActivity
@ -22,16 +23,20 @@ import com.simplemobiletools.contacts.models.Contact
import kotlinx.android.synthetic.main.item_add_favorite_with_number.view.*
import java.util.*
class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List<Contact>, val selectedContacts: ArrayList<String>, val allowPickMultiple: Boolean,
val itemClick: ((Contact) -> Unit)? = null) : RecyclerView.Adapter<SelectContactsAdapter.ViewHolder>() {
class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List<Contact>, private val selectedContacts: ArrayList<String>, private val allowPickMultiple: Boolean,
private val itemClick: ((Contact) -> Unit)? = null) : RecyclerView.Adapter<SelectContactsAdapter.ViewHolder>() {
private val itemViews = SparseArray<View>()
private val selectedPositions = HashSet<Int>()
private val config = activity.config
private val textColor = config.textColor
private val contactDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_person, textColor)
private val startNameWithSurname = config.startNameWithSurname
private val showContactThumbnails = config.showContactThumbnails
private val itemLayout = if (config.showPhoneNumbers) R.layout.item_add_favorite_with_number else R.layout.item_add_favorite_without_number
private var smallPadding = activity.resources.getDimension(R.dimen.small_margin).toInt()
private var bigPadding = activity.resources.getDimension(R.dimen.normal_margin).toInt()
init {
contacts.forEachIndexed { index, contact ->
if (selectedContacts.contains(contact.id.toString())) {
@ -75,15 +80,16 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List<Con
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val eventType = contacts[position]
itemViews.put(position, holder.bindView(eventType, startNameWithSurname, contactDrawable, config))
itemViews.put(position, holder.bindView(eventType, startNameWithSurname, contactDrawable, config, showContactThumbnails, smallPadding, bigPadding))
toggleItemSelection(selectedPositions.contains(position), position)
}
override fun getItemCount() = contacts.size
class ViewHolder(view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val showCheckbox: Boolean,
val itemClick: ((Contact) -> Unit)?) : RecyclerView.ViewHolder(view) {
fun bindView(contact: Contact, startNameWithSurname: Boolean, contactDrawable: Drawable, config: Config): View {
class ViewHolder(view: View, private val adapterListener: MyAdapterListener, val activity: SimpleActivity, private val showCheckbox: Boolean,
private val itemClick: ((Contact) -> Unit)?) : RecyclerView.ViewHolder(view) {
fun bindView(contact: Contact, startNameWithSurname: Boolean, contactDrawable: Drawable, config: Config, showContactThumbnails: Boolean,
smallPadding: Int, bigPadding: Int): View {
itemView.apply {
contact_checkbox.beVisibleIf(showCheckbox)
contact_checkbox.setColors(config.textColor, context.getAdjustedPrimaryColor(), config.backgroundColor)
@ -91,8 +97,12 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List<Con
contact_name.text = contact.getFullName(startNameWithSurname)
contact_name.setTextColor(textColor)
contact_name.setPadding(if (showContactThumbnails) smallPadding else bigPadding, smallPadding, smallPadding, 0)
contact_number?.text = contact.phoneNumbers.firstOrNull()?.value ?: ""
contact_number?.setTextColor(textColor)
contact_number?.setPadding(if (showContactThumbnails) smallPadding else bigPadding, 0, smallPadding, 0)
contact_frame.setOnClickListener {
if (itemClick != null) {
itemClick.invoke(contact)
@ -101,16 +111,19 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List<Con
}
}
if (contact.photoUri.isNotEmpty()) {
val options = RequestOptions()
.signature(ObjectKey(contact.photoUri))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.error(contactDrawable)
.centerCrop()
contact_tmb.beVisibleIf(showContactThumbnails)
if (showContactThumbnails) {
if (contact.photoUri.isNotEmpty()) {
val options = RequestOptions()
.signature(ObjectKey(contact.photoUri))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.error(contactDrawable)
.centerCrop()
Glide.with(activity).load(contact.photoUri).transition(DrawableTransitionOptions.withCrossFade()).apply(options).into(contact_tmb)
} else {
contact_tmb.setImageDrawable(contactDrawable)
Glide.with(activity).load(contact.photoUri).transition(DrawableTransitionOptions.withCrossFade()).apply(options).into(contact_tmb)
} else {
contact_tmb.setImageDrawable(contactDrawable)
}
}
}
@ -124,6 +137,8 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List<Con
override fun onViewRecycled(holder: ViewHolder?) {
super.onViewRecycled(holder)
Glide.with(activity).clear(holder?.itemView?.contact_tmb!!)
if (!activity.isActivityDestroyed()) {
Glide.with(activity).clear(holder?.itemView?.contact_tmb!!)
}
}
}

View File

@ -11,7 +11,7 @@ import com.simplemobiletools.contacts.helpers.ContactsHelper
import com.simplemobiletools.contacts.models.Contact
import kotlinx.android.synthetic.main.layout_select_contact.view.*
class AddFavoritesDialog(val activity: SimpleActivity, val callback: () -> Unit) {
class AddFavoritesDialog(val activity: SimpleActivity, private val callback: () -> Unit) {
private var dialog: AlertDialog? = null
private var view = activity.layoutInflater.inflate(R.layout.layout_select_contact, null)
private val config = activity.config

View File

@ -11,7 +11,7 @@ import com.simplemobiletools.contacts.R
import com.simplemobiletools.contacts.extensions.config
import kotlinx.android.synthetic.main.dialog_change_sorting.view.*
class ChangeSortingDialog(val activity: BaseSimpleActivity, val callback: () -> Unit) {
class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback: () -> Unit) {
private var currSorting = 0
private var config = activity.config
private var view = activity.layoutInflater.inflate(R.layout.dialog_change_sorting, null)

View File

@ -11,7 +11,7 @@ import com.simplemobiletools.contacts.helpers.ContactsHelper
import kotlinx.android.synthetic.main.dialog_export_contacts.view.*
import java.io.File
class ExportContactsDialog(val activity: SimpleActivity, val path: String, val callback: (file: File, contactSources: HashSet<String>) -> Unit) {
class ExportContactsDialog(val activity: SimpleActivity, val path: String, private val callback: (file: File, contactSources: HashSet<String>) -> Unit) {
init {
val view = (activity.layoutInflater.inflate(R.layout.dialog_export_contacts, null) as ViewGroup).apply {

View File

@ -9,7 +9,7 @@ import com.simplemobiletools.contacts.extensions.config
import com.simplemobiletools.contacts.helpers.ContactsHelper
import kotlinx.android.synthetic.main.dialog_filter_contact_sources.view.*
class FilterContactSourcesDialog(val activity: SimpleActivity, val callback: () -> Unit) {
class FilterContactSourcesDialog(val activity: SimpleActivity, private val callback: () -> Unit) {
private var dialog: AlertDialog? = null
private val view = activity.layoutInflater.inflate(R.layout.dialog_filter_contact_sources, null)

View File

@ -13,7 +13,7 @@ import com.simplemobiletools.contacts.helpers.VcfImporter
import com.simplemobiletools.contacts.helpers.VcfImporter.ImportResult.IMPORT_FAIL
import kotlinx.android.synthetic.main.dialog_import_contacts.view.*
class ImportContactsDialog(val activity: SimpleActivity, val path: String, val callback: (refreshView: Boolean) -> Unit) {
class ImportContactsDialog(val activity: SimpleActivity, val path: String, private val callback: (refreshView: Boolean) -> Unit) {
init {
val view = (activity.layoutInflater.inflate(R.layout.dialog_import_contacts, null) as ViewGroup).apply {
import_contacts_title.text = activity.config.lastUsedContactSource

View File

@ -13,7 +13,7 @@ import com.simplemobiletools.commons.extensions.getIntValue
import com.simplemobiletools.commons.extensions.isLollipopPlus
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.contacts.BuildConfig
import com.simplemobiletools.contacts.activities.ContactActivity
import com.simplemobiletools.contacts.activities.EditContactActivity
import com.simplemobiletools.contacts.helpers.CONTACT_ID
import com.simplemobiletools.contacts.helpers.Config
import com.simplemobiletools.contacts.models.Contact
@ -22,7 +22,7 @@ import java.io.File
val Context.config: Config get() = Config.newInstance(applicationContext)
fun Context.openContact(contact: Contact) {
Intent(applicationContext, ContactActivity::class.java).apply {
Intent(applicationContext, EditContactActivity::class.java).apply {
putExtra(CONTACT_ID, contact.id)
startActivity(this)
}
@ -69,6 +69,7 @@ fun Context.getContactUriRawId(uri: Uri): Int {
if (cursor.moveToFirst()) {
return cursor.getIntValue(ContactsContract.Contacts.NAME_RAW_CONTACT_ID)
}
} catch (ignored: Exception) {
} finally {
cursor?.close()
}

View File

@ -3,11 +3,11 @@ package com.simplemobiletools.contacts.fragments
import android.content.Context
import android.content.Intent
import android.util.AttributeSet
import com.simplemobiletools.contacts.activities.ContactActivity
import com.simplemobiletools.contacts.activities.EditContactActivity
class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
override fun fabClicked() {
Intent(context, ContactActivity::class.java).apply {
Intent(context, EditContactActivity::class.java).apply {
context.startActivity(this)
}
}

View File

@ -24,7 +24,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
protected var activity: MainActivity? = null
private var lastHashCode = 0
private var contactsIgnoringSearch = ArrayList<Contact>()
lateinit private var config: Config
private lateinit var config: Config
var forceListRedraw = false
@ -144,11 +144,19 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
(currAdapter as ContactsAdapter).apply {
startNameWithSurname = config.startNameWithSurname
showPhoneNumbers = config.showPhoneNumbers
showContactThumbnails = config.showContactThumbnails
updateItems(contacts)
}
}
}
fun showContactThumbnailsChanged(showThumbnails: Boolean) {
(fragment_list.adapter as? ContactsAdapter)?.apply {
showContactThumbnails = showThumbnails
notifyDataSetChanged()
}
}
fun onActivityResume() {
updateViewStuff()
}
@ -179,7 +187,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
}
fun onSearchOpened() {
contactsIgnoringSearch = (fragment_list.adapter as? ContactsAdapter)?.contactItems as ArrayList
contactsIgnoringSearch = (fragment_list?.adapter as? ContactsAdapter)?.contactItems as? ArrayList ?: ArrayList()
}
fun onSearchClosed() {

View File

@ -3,50 +3,50 @@ package com.simplemobiletools.contacts.helpers
import android.provider.ContactsContract.CommonDataKinds
// shared prefs
val CALL_CONTACT_ON_CLICK = "call_contact_on_click"
val SHOW_CONTACT_THUMBNAILS = "show_contact_thumbnails"
val SHOW_PHONE_NUMBERS = "show_phone_numbers"
val DISPLAY_CONTACT_SOURCES = "display_contact_sources"
val START_NAME_WITH_SURNAME = "start_name_with_surname"
val LAST_USED_CONTACT_SOURCE = "last_used_contact_source"
val LAST_USED_VIEW_PAGER_PAGE = "last_used_view_pager_page"
const val CALL_CONTACT_ON_CLICK = "call_contact_on_click"
const val SHOW_CONTACT_THUMBNAILS = "show_contact_thumbnails"
const val SHOW_PHONE_NUMBERS = "show_phone_numbers"
const val DISPLAY_CONTACT_SOURCES = "display_contact_sources"
const val START_NAME_WITH_SURNAME = "start_name_with_surname"
const val LAST_USED_CONTACT_SOURCE = "last_used_contact_source"
const val LAST_USED_VIEW_PAGER_PAGE = "last_used_view_pager_page"
val CONTACT_ID = "contact_id"
const val CONTACT_ID = "contact_id"
// contact photo changes
val PHOTO_ADDED = 1
val PHOTO_REMOVED = 2
val PHOTO_CHANGED = 3
val PHOTO_UNCHANGED = 4
const val PHOTO_ADDED = 1
const val PHOTO_REMOVED = 2
const val PHOTO_CHANGED = 3
const val PHOTO_UNCHANGED = 4
// default contact values
val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME
val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE
val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY
const val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME
const val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE
const val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY
// export/import
val BEGIN_VCARD = "BEGIN:VCARD"
val END_VCARD = "END:VCARD"
val N = "N:"
val TEL = "TEL"
val BDAY = "BDAY:"
val ANNIVERSARY = "ANNIVERSARY:"
val PHOTO = "PHOTO"
val EMAIL = "EMAIL"
val ENCODING = "ENCODING"
val BASE64 = "BASE64"
val JPEG = "JPEG"
val VERSION_2_1 = "VERSION:2.1"
const val BEGIN_VCARD = "BEGIN:VCARD"
const val END_VCARD = "END:VCARD"
const val N = "N:"
const val TEL = "TEL"
const val BDAY = "BDAY:"
const val ANNIVERSARY = "ANNIVERSARY:"
const val PHOTO = "PHOTO"
const val EMAIL = "EMAIL"
const val ENCODING = "ENCODING"
const val BASE64 = "BASE64"
const val JPEG = "JPEG"
const val VERSION_2_1 = "VERSION:2.1"
// phone number/email types
val CELL = "CELL"
val WORK = "WORK"
val HOME = "HOME"
val PREF = "PREF"
val MAIN = "MAIN"
val FAX = "FAX"
val WORK_FAX = "WORK;FAX"
val HOME_FAX = "HOME;FAX"
val PAGER = "PAGER"
val MOBILE = "MOBILE"
val VOICE = "VOICE"
const val CELL = "CELL"
const val WORK = "WORK"
const val HOME = "HOME"
const val PREF = "PREF"
const val MAIN = "MAIN"
const val FAX = "FAX"
const val WORK_FAX = "WORK;FAX"
const val HOME_FAX = "HOME;FAX"
const val PAGER = "PAGER"
const val MOBILE = "MOBILE"
const val VOICE = "VOICE"

View File

@ -253,6 +253,10 @@ class ContactsHelper(val activity: BaseSimpleActivity) {
}
private fun getContactSourceType(accountName: String): String {
if (accountName.isEmpty()) {
return ""
}
val uri = ContactsContract.RawContacts.CONTENT_URI
val projection = arrayOf(ContactsContract.RawContacts.ACCOUNT_TYPE)
val selection = "${ContactsContract.RawContacts.ACCOUNT_NAME} = ?"

View File

@ -7,6 +7,7 @@ import android.provider.MediaStore
import android.util.Base64
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.getFileOutputStream
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.extensions.writeLn
import com.simplemobiletools.contacts.helpers.VcfExporter.ExportResult.*
import com.simplemobiletools.contacts.models.Contact
@ -24,59 +25,63 @@ class VcfExporter {
private var contactsFailed = 0
fun exportContacts(activity: BaseSimpleActivity, file: File, contacts: ArrayList<Contact>, callback: (result: ExportResult) -> Unit) {
activity.getFileOutputStream(file) {
if (it == null) {
callback(EXPORT_FAIL)
return@getFileOutputStream
}
try {
activity.getFileOutputStream(file) {
if (it == null) {
callback(EXPORT_FAIL)
return@getFileOutputStream
}
it.bufferedWriter().use { out ->
for (contact in contacts) {
out.writeLn(BEGIN_VCARD)
out.writeLn(VERSION_2_1)
out.writeLn("$N${contact.surname};${contact.firstName};${contact.middleName};;")
it.bufferedWriter().use { out ->
for (contact in contacts) {
out.writeLn(BEGIN_VCARD)
out.writeLn(VERSION_2_1)
out.writeLn("$N${contact.surname};${contact.firstName};${contact.middleName};;")
contact.phoneNumbers.forEach {
out.writeLn("$TEL;${getPhoneNumberLabel(it.type)}:${it.value}")
}
contact.emails.forEach {
val type = getEmailTypeLabel(it.type)
val delimiterType = if (type.isEmpty()) "" else ";$type"
out.writeLn("$EMAIL$delimiterType:${it.value}")
}
contact.events.forEach {
if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) {
out.writeLn("$BDAY${it.value}")
contact.phoneNumbers.forEach {
out.writeLn("$TEL;${getPhoneNumberLabel(it.type)}:${it.value}")
}
contact.emails.forEach {
val type = getEmailTypeLabel(it.type)
val delimiterType = if (type.isEmpty()) "" else ";$type"
out.writeLn("$EMAIL$delimiterType:${it.value}")
}
contact.events.forEach {
if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) {
out.writeLn("$BDAY${it.value}")
}
}
if (contact.thumbnailUri.isNotEmpty()) {
val firstLine = "$PHOTO;$ENCODING=$BASE64;$JPEG:"
val bitmap = MediaStore.Images.Media.getBitmap(activity.contentResolver, Uri.parse(contact.thumbnailUri))
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, byteArrayOutputStream)
bitmap.recycle()
val byteArray = byteArrayOutputStream.toByteArray()
val encoded = Base64.encodeToString(byteArray, Base64.NO_WRAP)
val encodedFirstLineSection = encoded.substring(0, ENCODED_PHOTO_LINE_LENGTH - firstLine.length)
out.writeLn(firstLine + encodedFirstLineSection)
var curStartIndex = encodedFirstLineSection.length
do {
val part = encoded.substring(curStartIndex, Math.min(curStartIndex + ENCODED_PHOTO_LINE_LENGTH - 1, encoded.length))
out.writeLn(" $part")
curStartIndex += ENCODED_PHOTO_LINE_LENGTH - 1
} while (curStartIndex < encoded.length)
out.writeLn("")
}
out.writeLn(END_VCARD)
contactsExported++
}
if (contact.thumbnailUri.isNotEmpty()) {
val firstLine = "$PHOTO;$ENCODING=$BASE64;$JPEG:"
val bitmap = MediaStore.Images.Media.getBitmap(activity.contentResolver, Uri.parse(contact.thumbnailUri))
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, byteArrayOutputStream)
bitmap.recycle()
val byteArray = byteArrayOutputStream.toByteArray()
val encoded = Base64.encodeToString(byteArray, Base64.NO_WRAP)
val encodedFirstLineSection = encoded.substring(0, ENCODED_PHOTO_LINE_LENGTH - firstLine.length)
out.writeLn(firstLine + encodedFirstLineSection)
var curStartIndex = encodedFirstLineSection.length
do {
val part = encoded.substring(curStartIndex, Math.min(curStartIndex + ENCODED_PHOTO_LINE_LENGTH - 1, encoded.length))
out.writeLn(" $part")
curStartIndex += ENCODED_PHOTO_LINE_LENGTH - 1
} while (curStartIndex < encoded.length)
out.writeLn("")
}
out.writeLn(END_VCARD)
contactsExported++
}
}
} catch (e: Exception) {
activity.showErrorToast(e)
}
callback(when {

View File

@ -12,7 +12,7 @@
<RelativeLayout
android:id="@+id/contact_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="@dimen/contact_item_height"
android:paddingRight="@dimen/normal_margin">
<ImageView
@ -41,22 +41,19 @@
android:id="@+id/contact_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/contact_name"
android:layout_below="@+id/contact_name"
android:layout_toLeftOf="@+id/contact_checkbox"
android:layout_toRightOf="@+id/contact_tmb"
android:maxLines="1"
android:paddingLeft="@dimen/small_margin"
android:paddingRight="@dimen/small_margin"
android:textSize="@dimen/normal_text_size"
tools:text="0123 456 789"/>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id="@+id/contact_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/contact_tmb"
android:layout_height="@dimen/contact_item_height"
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/contact_tmb"
android:clickable="false"
android:gravity="center_vertical"/>

View File

@ -25,27 +25,20 @@
<TextView
android:id="@+id/contact_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="@+id/contact_tmb"
android:layout_alignTop="@+id/contact_tmb"
android:layout_height="@dimen/contact_item_height"
android:layout_toLeftOf="@+id/contact_checkbox"
android:layout_toRightOf="@+id/contact_tmb"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingLeft="@dimen/small_margin"
android:paddingRight="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:textSize="@dimen/bigger_text_size"
tools:text="John Doe"/>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id="@+id/contact_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/contact_tmb"
android:layout_height="@dimen/contact_item_height"
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/contact_tmb"
android:clickable="false"
android:gravity="center_vertical"/>

View File

@ -13,7 +13,7 @@
<RelativeLayout
android:id="@+id/contact_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="@dimen/contact_item_height"
android:paddingRight="@dimen/activity_margin">
<ImageView
@ -31,8 +31,6 @@
android:layout_toRightOf="@+id/contact_tmb"
android:ellipsize="end"
android:maxLines="1"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:textSize="@dimen/normal_text_size"
tools:text="John Doe"/>
@ -40,10 +38,10 @@
android:id="@+id/contact_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/contact_name"
android:layout_below="@+id/contact_name"
android:layout_toRightOf="@+id/contact_tmb"
android:maxLines="1"
android:paddingLeft="@dimen/small_margin"
android:textSize="@dimen/normal_text_size"
tools:text="0123 456 789"/>

View File

@ -26,15 +26,11 @@
<TextView
android:id="@+id/contact_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="@+id/contact_tmb"
android:layout_alignTop="@+id/contact_tmb"
android:layout_height="@dimen/contact_item_height"
android:layout_toRightOf="@+id/contact_tmb"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:textSize="@dimen/bigger_text_size"
tools:text="John Doe"/>

View File

@ -4,7 +4,7 @@
<string name="address">Adresse</string>
<string name="inserting">Einfügen…</string>
<string name="updating">Aktualisiere…</string>
<string name="missing_contact_account">Bitte wähle einen Account aus, zu dem der Kontakt gehört</string>
<string name="phone_storage">Gerätespeicher</string>
<string name="new_contact">Neuer Kontakt</string>
<string name="edit_contact">Kontakt bearbeiten</string>
@ -23,7 +23,11 @@
<string name="call_contact_on_click">Kontakt bei Klick anrufen</string>
<string name="start_name_with_surname">Namen mit Nachnamen beginnen</string>
<string name="show_phone_numbers">Zeige Telefonnummern im Hauptmenü</string>
<string name="show_contact_thumbnails">Show contact thumbnails</string>
<string name="show_contact_thumbnails">Zeige Vorschaubilder für Kontakte</string>
<string name="on_contact_click">Beim Klicken auf den Kontakt</string>
<string name="call_contact">Kontakt anrufen</string>
<string name="open_contact">Kontakt bearbeiten</string>
<string name="view_contact">Kontaktdetails ansehen</string>
<!-- Emails -->
<string name="email">Email</string>

View File

@ -4,7 +4,7 @@
<string name="address">주소</string>
<string name="inserting">등록중…</string>
<string name="updating">수정중…</string>
<string name="missing_contact_source">연락처가 포함된 계정을 선택하세요.</string>
<string name="phone_storage">Phone storage</string>
<string name="new_contact">새로운 연락처</string>
<string name="edit_contact">연락처 수정</string>
@ -24,6 +24,10 @@
<string name="start_name_with_surname">성을 먼저 표시</string>
<string name="show_phone_numbers">메인 스크린에 전화번호 표시</string>
<string name="show_contact_thumbnails">Show contact thumbnails</string>
<string name="on_contact_click">On contact click</string>
<string name="call_contact">Call contact</string>
<string name="open_contact">Open contact editor</string>
<string name="view_contact">View contact details</string>
<!-- Emails -->
<string name="email">이메일</string>

View File

@ -4,7 +4,7 @@
<string name="address">Address</string>
<string name="inserting">Inserting…</string>
<string name="updating">Updating…</string>
<string name="missing_contact_source">Please select an account to which the contact belongs</string>
<string name="phone_storage">Phone storage</string>
<string name="new_contact">Novo contacto</string>
<string name="edit_contact">Editar contacto</string>
@ -24,6 +24,10 @@
<string name="start_name_with_surname">Start name with surname</string>
<string name="show_phone_numbers">Show phone numbers on the main screen</string>
<string name="show_contact_thumbnails">Show contact thumbnails</string>
<string name="on_contact_click">On contact click</string>
<string name="call_contact">Call contact</string>
<string name="open_contact">Open contact editor</string>
<string name="view_contact">View contact details</string>
<!-- Emails -->
<string name="email">E-mail</string>

View File

@ -4,7 +4,7 @@
<string name="address">Адрес</string>
<string name="inserting">Добавление…</string>
<string name="updating">Обновление…</string>
<string name="missing_contact_source">Пожалуйста, выберите учётную запись, к которой относится контакт</string>
<string name="phone_storage">Phone storage</string>
<string name="new_contact">Новый контакт</string>
<string name="edit_contact">Редактировать контакт</string>
@ -24,6 +24,10 @@
<string name="start_name_with_surname">Показывать сначала фамилию</string>
<string name="show_phone_numbers">Показывать номера телефонов на главном экране</string>
<string name="show_contact_thumbnails">Показывать фото контакта</string>
<string name="on_contact_click">При нажатии на контакт</string>
<string name="call_contact">Позвонить контакту</string>
<string name="open_contact">Открыть редактор контактов</string>
<string name="view_contact">Просмотреть подробности о контакте</string>
<!-- Emails -->
<string name="email">Эл. почта</string>

View File

@ -4,7 +4,7 @@
<string name="address">Adresa</string>
<string name="inserting">Vytvára sa…</string>
<string name="updating">Upravuje sa…</string>
<string name="missing_contact_source">Prosím zvoľte účet, ktorému patrí daný kontakt</string>
<string name="phone_storage">Úložisko mobilu</string>
<string name="new_contact">Nový kontakt</string>
<string name="edit_contact">Upraviť kontakt</string>
@ -24,6 +24,10 @@
<string name="start_name_with_surname">Začať meno priezviskom</string>
<string name="show_phone_numbers">Zobraziť telefónne čísla na hlavnej obrazovke</string>
<string name="show_contact_thumbnails">Zobraziť obrázky kontaktov</string>
<string name="on_contact_click">Po kliknutí na kontakt</string>
<string name="call_contact">Zavolať kontakt</string>
<string name="open_contact">Otvoriť editor kontaktov</string>
<string name="view_contact">Zobraziť údaje kontaktu</string>
<!-- Emails -->
<string name="email">Email</string>

View File

@ -4,7 +4,7 @@
<string name="address">Adress</string>
<string name="inserting">Lägger till…</string>
<string name="updating">Uppdaterar…</string>
<string name="missing_contact_account">Du måste välja vilket konto kontakten ska tillhöra</string>
<string name="phone_storage">Phone storage</string>
<string name="new_contact">Ny kontakt</string>
<string name="edit_contact">Redigera kontakt</string>
@ -24,6 +24,10 @@
<string name="start_name_with_surname">Visa efternamn först</string>
<string name="show_phone_numbers">Visa telefonnummer i huvudvyn</string>
<string name="show_contact_thumbnails">Show contact thumbnails</string>
<string name="on_contact_click">On contact click</string>
<string name="call_contact">Call contact</string>
<string name="open_contact">Open contact editor</string>
<string name="view_contact">View contact details</string>
<!-- Emails -->
<string name="email">E-post</string>

View File

@ -3,4 +3,5 @@
<dimen name="contact_photo_size">80dp</dimen>
<dimen name="contact_actions_size">45dp</dimen>
<dimen name="contact_icons_size">40dp</dimen>
<dimen name="contact_item_height">48dp</dimen>
</resources>

View File

@ -4,7 +4,7 @@
<string name="address">Address</string>
<string name="inserting">Inserting…</string>
<string name="updating">Updating…</string>
<string name="missing_contact_account">Please select an account to which the contact belongs</string>
<string name="phone_storage">Phone storage</string>
<string name="new_contact">New contact</string>
<string name="edit_contact">Edit contact</string>
@ -24,6 +24,10 @@
<string name="start_name_with_surname">Start name with surname</string>
<string name="show_phone_numbers">Show phone numbers on the main screen</string>
<string name="show_contact_thumbnails">Show contact thumbnails</string>
<string name="on_contact_click">On contact click</string>
<string name="call_contact">Call contact</string>
<string name="open_contact">Open contact editor</string>
<string name="view_contact">View contact details</string>
<!-- Emails -->
<string name="email">Email</string>

View File

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.2.20'
ext.kotlin_version = '1.2.21'
repositories {
google()