diff --git a/CHANGELOG.md b/CHANGELOG.md index f21ecede..4f8ea65c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ Changelog ========== +Version 3.5.3 *(2018-04-18)* +---------------------------- + + * Allow splitting the Address in multiple lines + * Allow batch sending SMS or emails to selected contacts or whole group + * Highlight the searched string at the result contacts + +Version 3.5.2 *(2018-04-13)* +---------------------------- + + * Added an optional website field + * Parse more fields from Add Contact third party intents, like the one from WhatsApp + * Fix exporting contacts on SD cards + Version 3.5.1 *(2018-04-10)* ---------------------------- diff --git a/app/build.gradle b/app/build.gradle index 140b0da5..b357cbab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.simplemobiletools.contacts" minSdkVersion 16 targetSdkVersion 27 - versionCode 17 - versionName "3.5.1" + versionCode 19 + versionName "3.5.3" setProperty("archivesBaseName", "contacts") } @@ -45,7 +45,7 @@ ext { } dependencies { - implementation 'com.simplemobiletools:commons:3.18.23' + implementation 'com.simplemobiletools:commons:3.19.21' implementation 'joda-time:joda-time:2.9.9' implementation 'com.facebook.stetho:stetho:1.5.0' diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt index 6ba8d2f0..031f561f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -2,6 +2,7 @@ package com.simplemobiletools.contacts.activities import android.app.DatePickerDialog import android.content.ClipData +import android.content.ContentValues import android.content.Intent import android.graphics.drawable.ColorDrawable import android.net.Uri @@ -29,17 +30,13 @@ import kotlinx.android.synthetic.main.item_edit_address.view.* import kotlinx.android.synthetic.main.item_edit_email.view.* import kotlinx.android.synthetic.main.item_edit_group.view.* import kotlinx.android.synthetic.main.item_edit_phone_number.view.* +import kotlinx.android.synthetic.main.item_edit_website.view.* import kotlinx.android.synthetic.main.item_event.view.* import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat import java.util.* class EditContactActivity : ContactActivity() { - private val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME - private val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE - private val DEFAULT_ADDRESS_TYPE = CommonDataKinds.StructuredPostal.TYPE_HOME - private val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY - private val INTENT_TAKE_PHOTO = 1 private val INTENT_CHOOSE_PHOTO = 2 private val INTENT_CROP_PHOTO = 3 @@ -148,12 +145,16 @@ class EditContactActivity : ContactActivity() { } if (contact!!.id == 0 && intent.extras?.containsKey(KEY_PHONE) == true && (action == Intent.ACTION_INSERT_OR_EDIT || action == Intent.ACTION_INSERT)) { - val phoneNumber = intent.extras.get(KEY_PHONE).toString() ?: "" + val phoneNumber = intent.extras.get(KEY_PHONE)?.toString() ?: "" contact!!.phoneNumbers.add(PhoneNumber(phoneNumber, DEFAULT_PHONE_NUMBER_TYPE)) - setupPhoneNumbers() - val contactFullName = intent.extras.get(KEY_NAME)?.toString() ?: "" - contact_first_name.setText(contactFullName) + contact!!.firstName = intent.extras.get(KEY_NAME)?.toString() ?: "" + + val data = intent.extras.getParcelableArrayList("data") + if (data != null) { + parseIntentData(data) + } + setupEditContact() } setupTypePickers() @@ -179,9 +180,10 @@ class EditContactActivity : ContactActivity() { contact_addresses_image.applyColorFilter(textColor) contact_events_image.applyColorFilter(textColor) contact_notes_image.applyColorFilter(textColor) - contact_source_image.applyColorFilter(textColor) - contact_groups_image.applyColorFilter(textColor) contact_organization_image.applyColorFilter(textColor) + contact_websites_image.applyColorFilter(textColor) + contact_groups_image.applyColorFilter(textColor) + contact_source_image.applyColorFilter(textColor) val adjustedPrimaryColor = getAdjustedPrimaryColor() contact_numbers_add_new.applyColorFilter(adjustedPrimaryColor) @@ -192,6 +194,8 @@ class EditContactActivity : ContactActivity() { contact_addresses_add_new.background.applyColorFilter(textColor) contact_events_add_new.applyColorFilter(adjustedPrimaryColor) contact_events_add_new.background.applyColorFilter(textColor) + contact_websites_add_new.applyColorFilter(adjustedPrimaryColor) + contact_websites_add_new.background.applyColorFilter(textColor) contact_groups_add_new.applyColorFilter(adjustedPrimaryColor) contact_groups_add_new.background.applyColorFilter(textColor) @@ -204,6 +208,7 @@ class EditContactActivity : ContactActivity() { contact_emails_add_new.setOnClickListener { addNewEmailField() } contact_addresses_add_new.setOnClickListener { addNewAddressField() } contact_events_add_new.setOnClickListener { addNewEventField() } + contact_websites_add_new.setOnClickListener { addNewWebsiteField() } contact_groups_add_new.setOnClickListener { showSelectGroupsDialog() } setupFieldVisibility() @@ -285,6 +290,11 @@ class EditContactActivity : ContactActivity() { contact_events_holder.beVisibleIf(areEventsVisible) contact_events_add_new.beVisibleIf(areEventsVisible) + val areWebsitesVisible = showFields and SHOW_WEBSITES_FIELD != 0 + contact_websites_image.beVisibleIf(areWebsitesVisible) + contact_websites_holder.beVisibleIf(areWebsitesVisible) + contact_websites_add_new.beVisibleIf(areWebsitesVisible) + val areGroupsVisible = showFields and SHOW_GROUPS_FIELD != 0 contact_groups_image.beVisibleIf(areGroupsVisible) contact_groups_holder.beVisibleIf(areGroupsVisible) @@ -298,21 +308,27 @@ class EditContactActivity : ContactActivity() { private fun setupEditContact() { window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) supportActionBar?.title = resources.getString(R.string.edit_contact) - contact_prefix.setText(contact!!.prefix) - contact_first_name.setText(contact!!.firstName) - contact_middle_name.setText(contact!!.middleName) - contact_surname.setText(contact!!.surname) - contact_suffix.setText(contact!!.suffix) - - contact_source.text = getPublicContactSource(contact!!.source) + setupNames() setupPhoneNumbers() setupEmails() setupAddresses() setupNotes() setupOrganization() + setupWebsites() setupEvents() setupGroups() + setupContactSource() + } + + private fun setupNames() { + contact!!.apply { + contact_prefix.setText(prefix) + contact_first_name.setText(firstName) + contact_middle_name.setText(middleName) + contact_surname.setText(surname) + contact_suffix.setText(suffix) + } } private fun setupPhoneNumbers() { @@ -379,6 +395,20 @@ class EditContactActivity : ContactActivity() { } } + private fun setupWebsites() { + if (showFields and SHOW_WEBSITES_FIELD != 0) { + contact!!.websites.forEachIndexed { index, website -> + var websitesHolder = contact_websites_holder.getChildAt(index) + if (websitesHolder == null) { + websitesHolder = layoutInflater.inflate(R.layout.item_edit_website, contact_websites_holder, false) + contact_websites_holder.addView(websitesHolder) + } + + websitesHolder!!.contact_website.setText(website) + } + } + } + private fun setupEvents() { if (showFields and SHOW_EVENTS_FIELD != 0) { contact!!.events.forEachIndexed { index, event -> @@ -462,8 +492,11 @@ class EditContactActivity : ContactActivity() { } } + private fun setupContactSource() { + contact_source.text = getPublicContactSource(contact!!.source) + } + private fun setupNewContact() { - //window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE) supportActionBar?.title = resources.getString(R.string.new_contact) val contactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE val organization = Organization("", "") @@ -686,6 +719,7 @@ class EditContactActivity : ContactActivity() { source = contact!!.source starred = if (isContactStarred()) 1 else 0 notes = contact_notes.value + websites = getFilledWebsites() val company = contact_organization_company.value val jobPosition = contact_organization_job_position.value @@ -764,6 +798,19 @@ class EditContactActivity : ContactActivity() { return events } + private fun getFilledWebsites(): ArrayList { + val websites = ArrayList() + val websitesCount = contact_websites_holder.childCount + for (i in 0 until websitesCount) { + val websiteHolder = contact_websites_holder.getChildAt(i) + val website = websiteHolder.contact_website.value + if (website.isNotEmpty()) { + websites.add(website) + } + } + return websites + } + private fun insertNewContact() { isSaving = true toast(R.string.inserting) @@ -844,6 +891,16 @@ class EditContactActivity : ContactActivity() { } } + private fun addNewWebsiteField() { + val websitesHolder = layoutInflater.inflate(R.layout.item_edit_website, contact_websites_holder, false) as ViewGroup + updateTextColors(websitesHolder) + contact_websites_holder.addView(websitesHolder) + contact_websites_holder.onGlobalLayout { + websitesHolder.contact_website.requestFocus() + showKeyboard(websitesHolder.contact_website) + } + } + private fun isContactStarred() = contact_toggle_favorite.tag == 1 private fun getStarDrawable(on: Boolean) = resources.getDrawable(if (on) R.drawable.ic_star_on_big else R.drawable.ic_star_off_big) @@ -867,6 +924,57 @@ class EditContactActivity : ContactActivity() { } } + private fun parseIntentData(data: ArrayList) { + data.forEach { + when (it.get(CommonDataKinds.StructuredName.MIMETYPE)) { + CommonDataKinds.Email.CONTENT_ITEM_TYPE -> parseEmail(it) + CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE -> parseAddress(it) + CommonDataKinds.Organization.CONTENT_ITEM_TYPE -> parseOrganization(it) + CommonDataKinds.Event.CONTENT_ITEM_TYPE -> parseEvent(it) + CommonDataKinds.Website.CONTENT_ITEM_TYPE -> parseWebsite(it) + CommonDataKinds.Note.CONTENT_ITEM_TYPE -> parseNote(it) + } + } + } + + private fun parseEmail(contentValues: ContentValues) { + val type = contentValues.getAsInteger(CommonDataKinds.Email.DATA2) ?: DEFAULT_EMAIL_TYPE + val emailValue = contentValues.getAsString(CommonDataKinds.Email.DATA1) ?: return + val email = Email(emailValue, type) + contact!!.emails.add(email) + } + + private fun parseAddress(contentValues: ContentValues) { + val type = contentValues.getAsInteger(CommonDataKinds.StructuredPostal.DATA2) ?: DEFAULT_ADDRESS_TYPE + val addressValue = contentValues.getAsString(CommonDataKinds.StructuredPostal.DATA4) + ?: contentValues.getAsString(CommonDataKinds.StructuredPostal.DATA1) ?: return + val address = Address(addressValue, type) + contact!!.addresses.add(address) + } + + private fun parseOrganization(contentValues: ContentValues) { + val company = contentValues.getAsString(CommonDataKinds.Organization.DATA1) ?: "" + val jobPosition = contentValues.getAsString(CommonDataKinds.Organization.DATA4) ?: "" + contact!!.organization = Organization(company, jobPosition) + } + + private fun parseEvent(contentValues: ContentValues) { + val type = contentValues.getAsInteger(CommonDataKinds.Event.DATA2) ?: DEFAULT_EVENT_TYPE + val eventValue = contentValues.getAsString(CommonDataKinds.Event.DATA1) ?: return + val event = Event(eventValue, type) + contact!!.events.add(event) + } + + private fun parseWebsite(contentValues: ContentValues) { + val website = contentValues.getAsString(CommonDataKinds.Website.DATA1) ?: return + contact!!.websites.add(website) + } + + private fun parseNote(contentValues: ContentValues) { + val note = contentValues.getAsString(CommonDataKinds.Note.DATA1) ?: return + contact!!.notes = note + } + private fun startTakePhotoIntent() { val uri = getCachePhotoUri() lastPhotoIntentUri = uri diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/GroupContactsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/GroupContactsActivity.kt index 2ee2ab73..c81d309b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/GroupContactsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/GroupContactsActivity.kt @@ -1,6 +1,8 @@ package com.simplemobiletools.contacts.activities import android.os.Bundle +import android.view.Menu +import android.view.MenuItem import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.contacts.R import com.simplemobiletools.contacts.adapters.ContactsAdapter @@ -46,6 +48,20 @@ class GroupContactsActivity : SimpleActivity(), RemoveFromGroupListener, Refresh refreshContacts() } + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_group, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.send_sms_to_group -> sendSMSToGroup() + R.id.send_email_to_group -> sendEmailToGroup() + else -> return super.onOptionsItemSelected(item) + } + return true + } + private fun fabClicked() { SelectContactsDialog(this, allContacts, groupContacts) { addedContacts, removedContacts -> Thread { @@ -74,6 +90,14 @@ class GroupContactsActivity : SimpleActivity(), RemoveFromGroupListener, Refresh } } + private fun sendSMSToGroup() { + sendSMSToContacts(groupContacts) + } + + private fun sendEmailToGroup() { + sendEmailToContacts(groupContacts) + } + private fun updateContacts(contacts: ArrayList) { val currAdapter = group_contacts_list.adapter if (currAdapter == null) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt index 664acf60..22722186 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt @@ -374,8 +374,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { if (contacts.isEmpty()) { toast(R.string.no_entries_for_exporting) } else { - toast(R.string.exporting) - VcfExporter().exportContacts(this, file, contacts as ArrayList) { + VcfExporter().exportContacts(this, file, contacts as ArrayList, true) { toast(when (it) { VcfExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful VcfExporter.ExportResult.EXPORT_PARTIAL -> R.string.exporting_some_entries_failed diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt index 09ec8269..80e754d8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt @@ -157,6 +157,9 @@ class ViewContactActivity : ContactActivity() { setImageDrawable(getStarDrawable(contact!!.starred == 1)) tag = contact!!.starred applyColorFilter(config.textColor) + setOnClickListener { + toast(R.string.must_be_at_edit) + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt index 347a6f88..ca85d078 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt @@ -12,19 +12,14 @@ import com.bumptech.glide.signature.ObjectKey import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog -import com.simplemobiletools.commons.extensions.beVisibleIf -import com.simplemobiletools.commons.extensions.getColoredDrawableWithColor -import com.simplemobiletools.commons.extensions.isActivityDestroyed +import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.views.FastScroller import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.contacts.R import com.simplemobiletools.contacts.activities.SimpleActivity import com.simplemobiletools.contacts.dialogs.CreateNewGroupDialog -import com.simplemobiletools.contacts.extensions.addContactsToGroup -import com.simplemobiletools.contacts.extensions.config -import com.simplemobiletools.contacts.extensions.editContact -import com.simplemobiletools.contacts.extensions.shareContacts +import com.simplemobiletools.contacts.extensions.* import com.simplemobiletools.contacts.helpers.* import com.simplemobiletools.contacts.interfaces.RefreshContactsListener import com.simplemobiletools.contacts.interfaces.RemoveFromGroupListener @@ -39,6 +34,9 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList addToFavorites() R.id.cab_add_to_group -> addToGroup() R.id.cab_share -> shareContacts() + R.id.cab_send_sms_to_contacts -> sendSMSToContacts() + R.id.cab_send_email_to_contacts -> sendEmailToContacts() R.id.cab_remove -> removeContacts() R.id.cab_delete -> askConfirmDelete() } @@ -113,11 +115,15 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList) { + fun updateItems(newItems: ArrayList, highlightText: String = "") { if (newItems.hashCode() != contactItems.hashCode()) { - contactItems = newItems + contactItems = newItems.clone() as ArrayList + textToHighlight = highlightText notifyDataSetChanged() finishActMode() + } else if (textToHighlight != highlightText) { + textToHighlight = highlightText + notifyDataSetChanged() } } @@ -174,21 +180,13 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList() - selectedPositions.forEach { - newFavorites.add(contactItems[it]) - } - ContactsHelper(activity).addFavorites(newFavorites) + ContactsHelper(activity).addFavorites(getSelectedContacts()) refreshListener?.refreshContacts(FAVORITES_TAB_MASK) finishActMode() } private fun addToGroup() { - val selectedContacts = ArrayList() - selectedPositions.forEach { - selectedContacts.add(contactItems[it]) - } - + val selectedContacts = getSelectedContacts() val NEW_GROUP_ID = -1 val items = ArrayList() ContactsHelper(activity).getStoredGroups().forEach { @@ -225,6 +223,22 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList { + val contacts = ArrayList() + selectedPositions.forEach { + contacts.add(contactItems[it]) + } + return contacts + } + override fun onViewRecycled(holder: ViewHolder) { super.onViewRecycled(holder) if (!activity.isActivityDestroyed()) { @@ -234,13 +248,18 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList) { return } - VcfExporter().exportContacts(this, file, contacts) { + VcfExporter().exportContacts(this, file, contacts, false) { if (it == VcfExporter.ExportResult.EXPORT_OK) { sharePathIntent(file.absolutePath, BuildConfig.APPLICATION_ID) } else { @@ -99,6 +99,47 @@ fun BaseSimpleActivity.shareContacts(contacts: ArrayList) { } } +fun BaseSimpleActivity.sendSMSToContacts(contacts: ArrayList) { + val numbers = StringBuilder() + contacts.forEach { + it.phoneNumbers.forEach { + if (it.value.isNotEmpty()) { + numbers.append("${it.value};") + } + } + + val uriString = "smsto:${numbers.toString().trimEnd(';')}" + Intent(Intent.ACTION_SENDTO, Uri.parse(uriString)).apply { + if (resolveActivity(packageManager) != null) { + startActivity(this) + } else { + toast(R.string.no_app_found) + } + } + } +} + +fun BaseSimpleActivity.sendEmailToContacts(contacts: ArrayList) { + val emails = ArrayList() + contacts.forEach { + it.emails.forEach { + if (it.value.isNotEmpty()) { + emails.add(it.value) + } + } + } + + Intent(Intent.ACTION_SEND_MULTIPLE).apply { + type = "message/rfc822" + putExtra(Intent.EXTRA_EMAIL, emails.toTypedArray()) + if (resolveActivity(packageManager) != null) { + startActivity(this) + } else { + toast(R.string.no_app_found) + } + } +} + fun BaseSimpleActivity.getTempFile(): File? { val folder = File(cacheDir, "contacts") if (!folder.exists()) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt index 2bbcdd25..4e632c8c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt @@ -74,6 +74,9 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) fun primaryColorChanged() { fragment_fastscroller.updatePrimaryColor() fragment_fastscroller.updateBubblePrimaryColor() + (fragment_list.adapter as? ContactsAdapter)?.apply { + adjustedPrimaryColor = context.getAdjustedPrimaryColor() + } } fun startNameWithSurnameChanged(startNameWithSurname: Boolean) { @@ -254,7 +257,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } fragment_placeholder.beVisibleIf(filtered.isEmpty()) - updateItems(filtered) + updateItems(filtered, text) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt index 03e65cbe..a4f0b9b7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt @@ -1,5 +1,7 @@ package com.simplemobiletools.contacts.helpers +import android.provider.ContactsContract.CommonDataKinds + // shared prefs const val SHOW_CONTACT_THUMBNAILS = "show_contact_thumbnails" const val SHOW_PHONE_NUMBERS = "show_phone_numbers" @@ -46,6 +48,7 @@ const val ADR = "ADR" const val NOTE = "NOTE:" const val ORG = "ORG:" const val TITLE = "TITLE:" +const val URL = "URL:" const val ENCODING = "ENCODING" const val BASE64 = "BASE64" const val JPEG = "JPEG" @@ -83,3 +86,10 @@ const val SHOW_ORGANIZATION_FIELD = 1024 const val SHOW_GROUPS_FIELD = 2048 const val SHOW_CONTACT_SOURCE_FIELD = 4096 const val SHOW_WEBSITES_FIELD = 8192 + +const val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME +const val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE +const val DEFAULT_ADDRESS_TYPE = CommonDataKinds.StructuredPostal.TYPE_HOME +const val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY +const val DEFAULT_ORGANIZATION_TYPE = CommonDataKinds.Organization.TYPE_WORK +const val DEFAULT_WEBSITE_TYPE = CommonDataKinds.Website.TYPE_HOMEPAGE 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 8804a680..fc09e35d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -839,12 +839,31 @@ class ContactsHelper(val activity: BaseSimpleActivity) { val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Organization.CONTENT_ITEM_TYPE) withSelection(selection, selectionArgs) withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) - withValue(CommonDataKinds.Organization.TYPE, CommonDataKinds.Organization.TYPE_WORK) + withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) - withValue(CommonDataKinds.Organization.TYPE, CommonDataKinds.Organization.TYPE_WORK) + withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) operations.add(build()) } + // delete websites + ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI).apply { + val selection = "${ContactsContract.Data.RAW_CONTACT_ID} = ? AND ${ContactsContract.Data.MIMETYPE} = ? " + val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Website.CONTENT_ITEM_TYPE) + withSelection(selection, selectionArgs) + operations.add(build()) + } + + // add websites + contact.websites.forEach { + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply { + withValue(ContactsContract.Data.RAW_CONTACT_ID, contact.id) + withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Website.CONTENT_ITEM_TYPE) + withValue(CommonDataKinds.Website.URL, it) + withValue(CommonDataKinds.Website.TYPE, DEFAULT_WEBSITE_TYPE) + operations.add(build()) + } + } + // delete groups val relevantGroupIDs = getStoredGroups().map { it.id } if (relevantGroupIDs.isNotEmpty()) { @@ -1045,12 +1064,23 @@ class ContactsHelper(val activity: BaseSimpleActivity) { withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) - withValue(CommonDataKinds.Organization.TYPE, CommonDataKinds.Organization.TYPE_WORK) + withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) - withValue(CommonDataKinds.Organization.TYPE, CommonDataKinds.Organization.TYPE_WORK) + withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) operations.add(build()) } + // websites + contact.websites.forEach { + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply { + withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Website.CONTENT_ITEM_TYPE) + withValue(CommonDataKinds.Website.URL, it) + withValue(CommonDataKinds.Website.TYPE, DEFAULT_WEBSITE_TYPE) + operations.add(build()) + } + } + // groups contact.groups.forEach { ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt index d0fe214e..c082d6bf 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt @@ -38,6 +38,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont private val COL_COMPANY = "company" private val COL_JOB_POSITION = "job_position" private val COL_GROUPS = "groups" + private val COL_WEBSITES = "websites" private val GROUPS_TABLE_NAME = "groups" private val COL_TITLE = "title" @@ -47,7 +48,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont private val mDb = writableDatabase companion object { - private const val DB_VERSION = 4 + private const val DB_VERSION = 5 const val DB_NAME = "contacts.db" var dbInstance: DBHelper? = null var gson = Gson() @@ -63,7 +64,8 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont override fun onCreate(db: SQLiteDatabase) { db.execSQL("CREATE TABLE $CONTACTS_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_FIRST_NAME TEXT, $COL_MIDDLE_NAME TEXT, " + "$COL_SURNAME TEXT, $COL_PHOTO BLOB, $COL_PHONE_NUMBERS TEXT, $COL_EMAILS TEXT, $COL_EVENTS TEXT, $COL_STARRED INTEGER, " + - "$COL_ADDRESSES TEXT, $COL_NOTES TEXT, $COL_GROUPS TEXT, $COL_PREFIX TEXT, $COL_SUFFIX TEXT, $COL_COMPANY TEXT, $COL_JOB_POSITION TEXT)") + "$COL_ADDRESSES TEXT, $COL_NOTES TEXT, $COL_GROUPS TEXT, $COL_PREFIX TEXT, $COL_SUFFIX TEXT, $COL_COMPANY TEXT, $COL_JOB_POSITION TEXT," + + "$COL_WEBSITES TEXT)") // start autoincrement ID from FIRST_CONTACT_ID to avoid conflicts db.execSQL("REPLACE INTO sqlite_sequence (name, seq) VALUES ('$CONTACTS_TABLE_NAME', $FIRST_CONTACT_ID)") @@ -88,6 +90,10 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont db.execSQL("ALTER TABLE $CONTACTS_TABLE_NAME ADD COLUMN $COL_COMPANY TEXT DEFAULT ''") db.execSQL("ALTER TABLE $CONTACTS_TABLE_NAME ADD COLUMN $COL_JOB_POSITION TEXT DEFAULT ''") } + + if (oldVersion < 5) { + db.execSQL("ALTER TABLE $CONTACTS_TABLE_NAME ADD COLUMN $COL_WEBSITES TEXT DEFAULT ''") + } } private fun createGroupsTable(db: SQLiteDatabase) { @@ -134,6 +140,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont put(COL_GROUPS, gson.toJson(contact.groups.map { it.id })) put(COL_COMPANY, contact.organization.company) put(COL_JOB_POSITION, contact.organization.jobPosition) + put(COL_WEBSITES, gson.toJson(contact.websites)) if (contact.photoUri.isNotEmpty()) { put(COL_PHOTO, getPhotoByteArray(contact.photoUri)) @@ -242,13 +249,14 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont val storedGroups = ContactsHelper(activity).getStoredGroups() val contacts = ArrayList() val projection = arrayOf(COL_ID, COL_PREFIX, COL_FIRST_NAME, COL_MIDDLE_NAME, COL_SURNAME, COL_SUFFIX, COL_PHONE_NUMBERS, COL_EMAILS, - COL_EVENTS, COL_STARRED, COL_PHOTO, COL_ADDRESSES, COL_NOTES, COL_GROUPS, COL_COMPANY, COL_JOB_POSITION) + COL_EVENTS, COL_STARRED, COL_PHOTO, COL_ADDRESSES, COL_NOTES, COL_GROUPS, COL_COMPANY, COL_JOB_POSITION, COL_WEBSITES) val phoneNumbersToken = object : TypeToken>() {}.type val emailsToken = object : TypeToken>() {}.type val addressesToken = object : TypeToken>() {}.type val eventsToken = object : TypeToken>() {}.type val groupIdsToken = object : TypeToken>() {}.type + val websitesToken = object : TypeToken>() {}.type val cursor = mDb.query(CONTACTS_TABLE_NAME, projection, selection, selectionArgs, null, null, null) cursor.use { @@ -295,7 +303,9 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont val jobPosition = cursor.getStringValue(COL_JOB_POSITION) val organization = Organization(company, jobPosition) - val websites = ArrayList() + val websitesJson = cursor.getStringValue(COL_WEBSITES) + val websites = if (websitesJson == "[]") ArrayList() else gson.fromJson>(websitesJson, websitesToken) + ?: ArrayList(1) val contact = Contact(id, prefix, firstName, middleName, surname, suffix, "", phoneNumbers, emails, addresses, events, SMT_PRIVATE, starred, id, "", photo, notes, groups, organization, websites) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt index 80e503eb..88f077f3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt @@ -6,11 +6,9 @@ import android.provider.ContactsContract.CommonDataKinds 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.toFileDirItem -import com.simplemobiletools.commons.extensions.writeLn -import com.simplemobiletools.contacts.helpers.VcfExporter.ExportResult.* +import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.contacts.R +import com.simplemobiletools.contacts.helpers.VcfExporter.ExportResult.EXPORT_FAIL import com.simplemobiletools.contacts.models.Contact import java.io.BufferedWriter import java.io.ByteArrayOutputStream @@ -26,14 +24,18 @@ class VcfExporter { private var contactsExported = 0 private var contactsFailed = 0 - fun exportContacts(activity: BaseSimpleActivity, file: File, contacts: ArrayList, callback: (result: ExportResult) -> Unit) { - try { - activity.getFileOutputStream(file.toFileDirItem(activity)) { + fun exportContacts(activity: BaseSimpleActivity, file: File, contacts: ArrayList, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) { + activity.getFileOutputStream(file.toFileDirItem(activity), true) { + try { if (it == null) { callback(EXPORT_FAIL) return@getFileOutputStream } + if (showExportingToast) { + activity.toast(R.string.exporting) + } + it.bufferedWriter().use { out -> for (contact in contacts) { out.writeLn(BEGIN_VCARD) @@ -53,7 +55,7 @@ class VcfExporter { contact.addresses.forEach { val type = getAddressTypeLabel(it.type) val delimiterType = if (type.isEmpty()) "" else ";$type" - out.writeLn("$ADR$delimiterType:;;${it.value};;;;") + out.writeLn("$ADR$delimiterType:;;${it.value.replace("\n", "\\n")};;;;") } contact.events.forEach { @@ -71,6 +73,10 @@ class VcfExporter { out.writeLn("$TITLE${contact.organization.jobPosition.replace("\n", "\\n")}") } + contact.websites.forEach { + out.writeLn("$URL$it") + } + if (contact.thumbnailUri.isNotEmpty()) { val bitmap = MediaStore.Images.Media.getBitmap(activity.contentResolver, Uri.parse(contact.thumbnailUri)) addBitmap(bitmap, out) @@ -84,16 +90,17 @@ class VcfExporter { contactsExported++ } } - } - } catch (e: Exception) { - activity.showErrorToast(e) - } - callback(when { - contactsExported == 0 -> EXPORT_FAIL - contactsFailed > 0 -> EXPORT_PARTIAL - else -> EXPORT_OK - }) + } catch (e: Exception) { + activity.showErrorToast(e) + } + + callback(when { + contactsExported == 0 -> EXPORT_FAIL + contactsFailed > 0 -> ExportResult.EXPORT_PARTIAL + else -> ExportResult.EXPORT_OK + }) + } } private fun addBitmap(bitmap: Bitmap, out: BufferedWriter) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt index c1938d19..85561636 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt @@ -91,6 +91,7 @@ class VcfImporter(val activity: SimpleActivity) { line.toUpperCase().startsWith(PHOTO) -> addPhoto(line.substring(PHOTO.length)) line.toUpperCase().startsWith(ORG) -> addCompany(line.substring(ORG.length)) line.toUpperCase().startsWith(TITLE) -> addJobPosition(line.substring(TITLE.length)) + line.toUpperCase().startsWith(URL) -> addWebsite(line.substring(URL.length)) line.toUpperCase() == END_VCARD -> saveContact(targetContactSource) isGettingPhoto -> currentPhotoString.append(line.trim()) } @@ -186,7 +187,7 @@ class VcfImporter(val activity: SimpleActivity) { val type = getAddressTypeId(rawType.toUpperCase()) val addresses = addressParts[1].split(";") if (addresses.size == 7) { - curAddresses.add(Address(addresses[2], type)) + curAddresses.add(Address(addresses[2].replace("\\n", "\n"), type)) } } @@ -251,6 +252,10 @@ class VcfImporter(val activity: SimpleActivity) { curJobPosition = jobPosition } + private fun addWebsite(website: String) { + curWebsites.add(website) + } + private fun saveContact(source: String) { val organization = Organization(curCompany, curJobPosition) val contact = Contact(0, curPrefix, curFirstName, curMiddleName, curSurname, curSuffix, curPhotoUri, curPhoneNumbers, curEmails, curAddresses, curEvents, diff --git a/app/src/main/res/layout/activity_edit_contact.xml b/app/src/main/res/layout/activity_edit_contact.xml index 68f6ac87..f09f6d3d 100644 --- a/app/src/main/res/layout/activity_edit_contact.xml +++ b/app/src/main/res/layout/activity_edit_contact.xml @@ -51,7 +51,7 @@ android:paddingLeft="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin" android:scaleType="center" - android:src="@drawable/ic_email"/> + android:src="@drawable/ic_email_big"/> + android:src="@drawable/ic_sms_big"/> @@ -200,9 +200,9 @@ android:layout_height="wrap_content" android:layout_below="@+id/contact_numbers_holder" android:layout_centerHorizontal="true" + android:layout_marginBottom="@dimen/medium_margin" android:background="@drawable/button_background" android:paddingBottom="@dimen/medium_margin" - android:layout_marginBottom="@dimen/medium_margin" android:paddingLeft="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin" android:paddingTop="@dimen/medium_margin" @@ -386,6 +386,44 @@ android:textCursorDrawable="@null" android:textSize="@dimen/bigger_text_size"/> + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_view_contact.xml b/app/src/main/res/layout/activity_view_contact.xml index d72416a6..8d50e8cf 100644 --- a/app/src/main/res/layout/activity_view_contact.xml +++ b/app/src/main/res/layout/activity_view_contact.xml @@ -52,7 +52,7 @@ android:paddingLeft="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin" android:scaleType="center" - android:src="@drawable/ic_email"/> + android:src="@drawable/ic_email_big"/> + android:src="@drawable/ic_sms_big"/> diff --git a/app/src/main/res/layout/item_edit_address.xml b/app/src/main/res/layout/item_edit_address.xml index f18e5552..36a6e910 100644 --- a/app/src/main/res/layout/item_edit_address.xml +++ b/app/src/main/res/layout/item_edit_address.xml @@ -13,10 +13,7 @@ android:layout_toLeftOf="@+id/contact_address_type" android:layout_toStartOf="@+id/contact_address_type" android:hint="@string/address" - android:inputType="textCapWords" - android:lines="1" - android:maxLines="1" - android:singleLine="true" + android:inputType="textCapWords|textMultiLine" android:textCursorDrawable="@null" android:textSize="@dimen/bigger_text_size"/> diff --git a/app/src/main/res/layout/item_edit_website.xml b/app/src/main/res/layout/item_edit_website.xml new file mode 100644 index 00000000..8eda6c0c --- /dev/null +++ b/app/src/main/res/layout/item_edit_website.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/res/layout/item_view_address.xml b/app/src/main/res/layout/item_view_address.xml index fa3497b8..c3f46463 100644 --- a/app/src/main/res/layout/item_view_address.xml +++ b/app/src/main/res/layout/item_view_address.xml @@ -15,9 +15,6 @@ android:layout_centerVertical="true" android:layout_toLeftOf="@+id/contact_address_type" android:layout_toStartOf="@+id/contact_address_type" - android:lines="1" - android:maxLines="1" - android:singleLine="true" android:textSize="@dimen/bigger_text_size"/> + + + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d8499871..ad6daa49 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -9,6 +9,10 @@ Company Job position Website + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group Neuer Kontakt Kontakt bearbeiten @@ -69,6 +73,7 @@ Favoriten hinzufügen Zu Favoriten hinzufügen Aus Favoriten entfernen + You must be at the Edit screen to modify a contact Kontakte durchsuchen diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index d7b4b75f..fc2e9af5 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -9,6 +9,10 @@ Company Job position Website + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group Νέα επαφή Επεξεργασία επαφής @@ -69,6 +73,7 @@ Προσθήκη αγαπημένων Προσθήκη στα αγαπημένα Αφαίρεση από τα αγαπημένα + You must be at the Edit screen to modify a contact Αναζήτηση επαφών diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9fb63361..89a0769e 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -8,7 +8,11 @@ Stockage du téléphone (non visible par d\'autres applis) Société Poste - Website + Site web + Envoyer un SMS aux contacts + Envoyer un e-mail aux contacts + Envoyer un SMS au groupe + Envoyer un e-mail au groupe Nouveau contact Modifier contact @@ -35,15 +39,15 @@ Supprimer la photo - Commencer le nom par le nom de famille - Afficher les numéros de téléphone sur l\'écran principal + Trier les contacts par nom de famille + Afficher les numéros de téléphone Afficher les vignettes des contacts Sur appui du contact Appeler le contact Voir les détails du contact Afficher l\'onglet favoris Afficher l\'onglet groupes - Configurer l\'affichage des champs de contact + Configurer l\'affichage des champs des contacts E-mail @@ -65,10 +69,11 @@ Anniversaire - Il semble que vous n\'ayez pas encore ajouté de contact favori. + Vous n\'ayez pas encore ajouté de contact favori. Ajouter des favoris Ajouter aux favoris Retirer des favoris + You must be at the Edit screen to modify a contact Rechercher des contacts @@ -93,7 +98,7 @@ Évènements (naissances, anniversaires) Notes Organisation - Websites + Sites web Groupe Source du contact diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 76955392..446dd86b 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -6,9 +6,13 @@ Ažuriranje… Pohrana na telefonu Pohrana na telefonu (nije vidljiva drugim aplikacijama)) - Company - Job position - Website + Tvrtka + Radno mjesto + Web stranica + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group Novi kontakt Uredi kontakt @@ -69,6 +73,7 @@ Dodaj favorite Dodaj u favorite Ukloni iz favorita + You must be at the Edit screen to modify a contact Pretraži kontakte @@ -84,22 +89,22 @@ Naziv datoteke (bez .vcf) - Select fields to show - Prefix - Suffix - Phone numbers - Emails - Addresses - Events (birthdays, anniversaries) - Notes - Organization - Websites - Groups - Contact source + Odaberi polja za prikaz + Prefiks + Sufiks + Brojevi telefona + E-pošte + Adrese + Događaji (rođendani, godišnjice) + Bilješke + Organizacije + Web stranice + Grupe + Izvori kontakata - I want to change what fields are visible at contacts. Can I do it? - Yes, all you have to do is go in Settings -> Manage shown contact fields. There you can select what fields should be visible. Some of them are even disabled by default, so you might find some new ones there. + Želim promijeniti polja koja su vidljiva na kontaktima. Mogu li to napraviti? + Da, sve što morate učiniti je otići u Postavke -> Upravljanje poljima za prikaz. Tamo možete odabrati polja koja bi trebala biti vidljiva. Neka od njih su čak i onemogućena prema zadanim postavkama, tako da možete pronaći neke nove. diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 7ccd0798..a1f591d6 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -9,6 +9,10 @@ Company Job position Website + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group 새로운 연락처 연락처 수정 @@ -69,6 +73,7 @@ 자주쓰는 연락처 등록 자주쓰는 연락처에 추가 자주쓰는 연락처에서 제거 + You must be at the Edit screen to modify a contact 연락처 검색 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 164db0a4..c6c2d496 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -9,6 +9,10 @@ Company Job position Website + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group Naujas kontaktas Redaguoti kontaktą @@ -69,6 +73,7 @@ Pridėti mėgiamiausiuosius Pridėti į mėgiamiausiuosius Pašalinti iš mėgiamiausiųjų + You must be at the Edit screen to modify a contact Ieškoti kontaktų @@ -84,22 +89,22 @@ Bylos vardas (be .vcf) - Select fields to show - Prefix - Suffix - Phone numbers - Emails - Addresses - Events (birthdays, anniversaries) - Notes - Organization - Websites - Groups - Contact source + Pasirinkti rodomus laukelius + Priešdėlis + Priesaga + Telefonų numeriai + Elektroniniaipaštai + Adresai + Įvykiai (gimtadieniai, sukaktys) + Užrašai + Organizacija + Interneto puslapiai + Grupės + Kontakto šaltinis - I want to change what fields are visible at contacts. Can I do it? - Yes, all you have to do is go in Settings -> Manage shown contact fields. There you can select what fields should be visible. Some of them are even disabled by default, so you might find some new ones there. + Noriu pakeisti, kokie laukai yra matomi kontaktuose. Ar galiu tai padaryti? + Taip, viskas, ką jums reikia padaryti, tai eiti į Nustatymai -> Tvarkyti rodomus kontaktų laukus. Čia galite pasirinkti, kurie laukai turėtų būti matomi. Kai kurie iš jų netgi yra išjungiami pagal numatytuosius nustatymus, todėl ten galite rasti naujų. diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 56d5f5fe..3fcc26e8 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -8,7 +8,11 @@ Armazenamento do telefone (não visível por outras alicações) Organização Cargo - Website + Site + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group Novo contacto Editar contacto @@ -38,7 +42,7 @@ Ordenar por apelido Mostrar número de telefone no ecrã principal Mostrar miniatura do contacto - Ao clicar no contacto + Ao tocar no contacto Ligar Ver detalhes Mostrar favoritos @@ -65,10 +69,11 @@ Aniversário - Parece que ainda não adicionou contactos como favoritos. + Parece que ainda não adicionou contactos como favoritos Adicionar favoritos Adicionar aos favoritos Remover dos favoritos + You must be at the Edit screen to modify a contact Pesquisar contactos @@ -79,7 +84,7 @@ Exportar contactos Importar contactos de um ficheiro .vcf Exportar contactos para um ficheiro .vcf - Destino da fonte do contacto + Destino da origem do contacto Incluir fontes dos contactos Nome do ficheiro (sem .vcf) @@ -93,9 +98,9 @@ Eventos (data de nascimento, aniversário) Notas Organização - Websites + Site Grupos - Fonte do contacto + Origem do contacto I want to change what fields are visible at contacts. Can I do it? diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index b9818f63..1a29ddf2 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -9,6 +9,10 @@ Организация Должность Сайт + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group Новый контакт Редактировать контакт @@ -69,6 +73,7 @@ Добавить избранные Добавить в избранные Удалить из избранных + You must be at the Edit screen to modify a contact Поиск контактов diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index be962c4e..a16d32fb 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -9,6 +9,10 @@ Firma Pracovná pozícia Website + Poslať kontaktom SMS + Poslať kontaktom email + Poslať skupine SMS + Poslať skupine email Nový kontakt Upraviť kontakt @@ -69,6 +73,7 @@ Pridať obľúbené Pridať medzi obľúbené Odstrániť z obľúbených + Pre úpravu kontaktu musíte byť v Editore kontaktu Hľadať v kontaktoch diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 4fa202ed..c6f7c6d3 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -6,9 +6,13 @@ Uppdaterar… Telefonens lagringsutrymme Telefonens lagringsutrymme (inte synligt för andra appar) - Company - Job position - Website + Företag + Befattning + Webbplats + Skicka sms till kontakter + Skicka e-post till kontakter + Skicka sms till grupp + Skicka e-post till grupp Ny kontakt Redigera kontakt @@ -43,7 +47,7 @@ Visa kontaktuppgifter Visa fliken Favoriter Visa fliken Grupper - Manage shown contact fields + Hantera visade kontaktfält E-post @@ -69,6 +73,7 @@ Lägg till favoriter Lägg till i favoriter Ta bort från favoriter + You must be at the Edit screen to modify a contact Sök efter kontakter @@ -84,18 +89,18 @@ Filnamn (utan .vcf) - Select fields to show + Välj vilka fält som ska visas Prefix Suffix - Phone numbers - Emails - Addresses - Events (birthdays, anniversaries) - Notes - Organization - Websites - Groups - Contact source + Telefonnummer + E-postadresser + Adresser + Händelser (födelsedagar, årsdagar) + Anteckningar + Organisation + Webbplatser + Grupper + Kontaktkälla I want to change what fields are visible at contacts. Can I do it? diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index e10f2970..22d3d9d1 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -9,6 +9,10 @@ 公司 職位 Website + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group 新聯絡人 編輯聯絡人 @@ -69,6 +73,7 @@ 添加我的最愛 加入我的最愛 從我的最愛移除 + You must be at the Edit screen to modify a contact 搜尋聯絡人 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a62b2013..a5b8c8ae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,6 +9,10 @@ Company Job position Website + Send SMS to contacts + Send email to contacts + Send SMS to group + Send email to group New contact Edit contact @@ -69,6 +73,7 @@ Add favorites Add to favorites Remove from favorites + You must be at the Edit screen to modify a contact Search contacts diff --git a/build.gradle b/build.gradle index 3437621a..9b9625a9 100644 --- a/build.gradle +++ b/build.gradle @@ -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.31' + ext.kotlin_version = '1.2.40' repositories { google() @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0' + classpath 'com.android.tools.build:gradle:3.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong