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 12f7e4b3..db2bef0f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -503,8 +503,8 @@ class EditContactActivity : ContactActivity() { supportActionBar?.title = resources.getString(R.string.new_contact) originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE val organization = Organization("", "") - contact = Contact(0, "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "", null, "", - ArrayList(), organization, ArrayList()) + contact = Contact(0, "", "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "", + null, "", ArrayList(), organization, ArrayList()) contact_source.text = getPublicContactSource(contact!!.source) } 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 c78e0ac2..b719390d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -11,6 +11,7 @@ import android.net.Uri import android.provider.CallLog import android.provider.ContactsContract import android.provider.ContactsContract.CommonDataKinds +import android.provider.ContactsContract.CommonDataKinds.Nickname import android.provider.ContactsContract.CommonDataKinds.Note import android.provider.MediaStore import android.text.TextUtils @@ -112,6 +113,7 @@ class ContactsHelper(val activity: Activity) { val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: "" val surname = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: "" val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: "" + val nickname = "" val photoUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_URI) ?: "" val number = ArrayList() // proper value is obtained below val emails = ArrayList() @@ -125,8 +127,8 @@ class ContactsHelper(val activity: Activity) { val groups = ArrayList() val organization = Organization("", "") val websites = ArrayList() - val contact = Contact(id, prefix, firstName, middleName, surname, suffix, photoUri, number, emails, addresses, events, - accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites) + val contact = Contact(id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, number, emails, addresses, + events, accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites) contacts.put(id, contact) } while (cursor.moveToNext()) @@ -144,6 +146,13 @@ class ContactsHelper(val activity: Activity) { contacts[key]?.phoneNumbers = phoneNumbers.valueAt(i) } + val nicknames = getNicknames() + size = nicknames.size() + for (i in 0 until size) { + val key = nicknames.keyAt(i) + contacts[key]?.nickname = nicknames.valueAt(i) + } + val emails = getEmails() size = emails.size() for (i in 0 until size) { @@ -225,6 +234,36 @@ class ContactsHelper(val activity: Activity) { return phoneNumbers } + private fun getNicknames(contactId: Int? = null): SparseArray { + val nicknames = SparseArray() + val uri = ContactsContract.Data.CONTENT_URI + val projection = arrayOf( + ContactsContract.Data.RAW_CONTACT_ID, + Nickname.NAME + ) + + val selection = getSourcesSelection(true, contactId != null) + val selectionArgs = getSourcesSelectionArgs(Nickname.CONTENT_ITEM_TYPE, contactId) + + var cursor: Cursor? = null + try { + cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) + if (cursor?.moveToFirst() == true) { + do { + val id = cursor.getIntValue(ContactsContract.Data.RAW_CONTACT_ID) + val nickname = cursor.getStringValue(Nickname.NAME) ?: continue + nicknames.put(id, nickname) + } while (cursor.moveToNext()) + } + } catch (e: Exception) { + activity.showErrorToast(e) + } finally { + cursor?.close() + } + + return nicknames + } + private fun getEmails(contactId: Int? = null): SparseArray> { val emails = SparseArray>() val uri = CommonDataKinds.Email.CONTENT_URI @@ -353,7 +392,7 @@ class ContactsHelper(val activity: Activity) { if (cursor?.moveToFirst() == true) { do { val id = cursor.getIntValue(ContactsContract.Data.RAW_CONTACT_ID) - val note = cursor.getStringValue(CommonDataKinds.Note.NOTE) ?: continue + val note = cursor.getStringValue(Note.NOTE) ?: continue notes.put(id, note) } while (cursor.moveToNext()) } @@ -654,6 +693,7 @@ class ContactsHelper(val activity: Activity) { val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: "" val surname = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: "" val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: "" + val nickname = getNicknames(id)[id] ?: "" val photoUri = cursor.getStringValue(CommonDataKinds.Phone.PHOTO_URI) ?: "" val number = getPhoneNumbers(id)[id] ?: ArrayList() val emails = getEmails(id)[id] ?: ArrayList() @@ -667,8 +707,8 @@ class ContactsHelper(val activity: Activity) { val thumbnailUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI) ?: "" val organization = getOrganizations(id)[id] ?: Organization("", "") val websites = getWebsites(id)[id] ?: ArrayList() - return Contact(id, prefix, firstName, middleName, surname, suffix, photoUri, number, emails, addresses, events, accountName, - starred, contactId, thumbnailUri, null, notes, groups, organization, websites) + return Contact(id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, number, emails, addresses, events, + accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites) } } finally { cursor?.close() 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 0cdd81ae..860b3698 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt @@ -28,6 +28,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont private val COL_MIDDLE_NAME = "middle_name" private val COL_SURNAME = "surname" private val COL_SUFFIX = "suffix" + private val COL_NICKNAME = "nickname" private val COL_PHOTO = "photo" private val COL_PHONE_NUMBERS = "phone_numbers" private val COL_EMAILS = "emails" @@ -48,9 +49,9 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont private val mDb = writableDatabase companion object { - private const val DB_VERSION = 5 const val DB_NAME = "contacts.db" - var dbInstance: DBHelper? = null + private const val DB_VERSION = 6 + private var dbInstance: DBHelper? = null var gson = Gson() fun newInstance(context: Context): DBHelper { @@ -65,7 +66,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont 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_WEBSITES TEXT)") + "$COL_WEBSITES TEXT, $COL_NICKNAME 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)") @@ -94,6 +95,10 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont if (oldVersion < 5) { db.execSQL("ALTER TABLE $CONTACTS_TABLE_NAME ADD COLUMN $COL_WEBSITES TEXT DEFAULT ''") } + + if (oldVersion < 6) { + db.execSQL("ALTER TABLE $CONTACTS_TABLE_NAME ADD COLUMN $COL_NICKNAME TEXT DEFAULT ''") + } } private fun createGroupsTable(db: SQLiteDatabase) { @@ -135,6 +140,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont put(COL_MIDDLE_NAME, contact.middleName) put(COL_SURNAME, contact.surname) put(COL_SUFFIX, contact.suffix) + put(COL_NICKNAME, contact.nickname) put(COL_PHONE_NUMBERS, gson.toJson(contact.phoneNumbers)) put(COL_EMAILS, gson.toJson(contact.emails)) put(COL_ADDRESSES, gson.toJson(contact.addresses)) @@ -252,8 +258,8 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont fun getContacts(activity: Activity, selection: String? = null, selectionArgs: Array? = null): ArrayList { 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_WEBSITES) + val projection = arrayOf(COL_ID, COL_PREFIX, COL_FIRST_NAME, COL_MIDDLE_NAME, COL_SURNAME, COL_SUFFIX, COL_NICKNAME, COL_PHONE_NUMBERS, + COL_EMAILS, 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 @@ -271,6 +277,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont val middleName = cursor.getStringValue(COL_MIDDLE_NAME) val surname = cursor.getStringValue(COL_SURNAME) val suffix = cursor.getStringValue(COL_SUFFIX) + val nickname = cursor.getStringValue(COL_NICKNAME) val phoneNumbersJson = cursor.getStringValue(COL_PHONE_NUMBERS) val phoneNumbers = if (phoneNumbersJson == "[]") ArrayList() else gson.fromJson>(phoneNumbersJson, phoneNumbersToken) @@ -315,8 +322,8 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont 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) + val contact = Contact(id, prefix, firstName, middleName, surname, suffix, nickname, "", phoneNumbers, emails, addresses, + events, SMT_PRIVATE, starred, id, "", photo, notes, groups, organization, websites) contacts.add(contact) } } 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 ae7e3dfd..3831f26f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt @@ -25,6 +25,7 @@ class VcfImporter(val activity: SimpleActivity) { private var curMiddleName = "" private var curSurname = "" private var curSuffix = "" + private var curNickname = "" private var curPhotoUri = "" private var curNotes = "" private var curCompany = "" @@ -305,8 +306,8 @@ class VcfImporter(val activity: SimpleActivity) { private fun saveContact(source: String) { val organization = Organization(curCompany, curJobPosition) - val contact = Contact(0, curPrefix, curFirstName, curMiddleName, curSurname, curSuffix, curPhotoUri, curPhoneNumbers, curEmails, curAddresses, curEvents, - source, 0, 0, "", null, curNotes, curGroups, organization, curWebsites) + val contact = Contact(0, curPrefix, curFirstName, curMiddleName, curSurname, curSuffix, curNickname, curPhotoUri, curPhoneNumbers, + curEmails, curAddresses, curEvents, source, 0, 0, "", null, curNotes, curGroups, organization, curWebsites) if (ContactsHelper(activity).insertContact(contact)) { contactsImported++ @@ -319,6 +320,7 @@ class VcfImporter(val activity: SimpleActivity) { curMiddleName = "" curSurname = "" curSuffix = "" + curNickname = "" curPhotoUri = "" curNotes = "" curCompany = "" diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt index e8229f51..700dbbba 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt @@ -7,9 +7,9 @@ import com.simplemobiletools.commons.helpers.SORT_BY_MIDDLE_NAME import com.simplemobiletools.commons.helpers.SORT_DESCENDING import com.simplemobiletools.contacts.helpers.PHONE_NUMBER_PATTERN -data class Contact(val id: Int, var prefix: String, var firstName: String, var middleName: String, var surname: String, var suffix: String, var photoUri: String, - var phoneNumbers: ArrayList, var emails: ArrayList, var addresses: ArrayList
, var events: ArrayList, - var source: String, var starred: Int, val contactId: Int, val thumbnailUri: String, var photo: Bitmap?, var notes: String, +data class Contact(val id: Int, var prefix: String, var firstName: String, var middleName: String, var surname: String, var suffix: String, var nickname: String, + var photoUri: String, var phoneNumbers: ArrayList, var emails: ArrayList, var addresses: ArrayList
, + var events: ArrayList, var source: String, var starred: Int, val contactId: Int, val thumbnailUri: String, var photo: Bitmap?, var notes: String, var groups: ArrayList, var organization: Organization, var websites: ArrayList) : Comparable { companion object { var sorting = 0