add a nickname field to contacts

This commit is contained in:
tibbi 2018-08-12 20:52:46 +02:00
parent 041dc19856
commit 87069862f8
5 changed files with 68 additions and 19 deletions

View File

@ -503,8 +503,8 @@ class EditContactActivity : ContactActivity() {
supportActionBar?.title = resources.getString(R.string.new_contact) supportActionBar?.title = resources.getString(R.string.new_contact)
originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE
val organization = Organization("", "") val organization = Organization("", "")
contact = Contact(0, "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "", null, "", contact = Contact(0, "", "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "",
ArrayList(), organization, ArrayList()) null, "", ArrayList(), organization, ArrayList())
contact_source.text = getPublicContactSource(contact!!.source) contact_source.text = getPublicContactSource(contact!!.source)
} }

View File

@ -11,6 +11,7 @@ import android.net.Uri
import android.provider.CallLog import android.provider.CallLog
import android.provider.ContactsContract import android.provider.ContactsContract
import android.provider.ContactsContract.CommonDataKinds import android.provider.ContactsContract.CommonDataKinds
import android.provider.ContactsContract.CommonDataKinds.Nickname
import android.provider.ContactsContract.CommonDataKinds.Note import android.provider.ContactsContract.CommonDataKinds.Note
import android.provider.MediaStore import android.provider.MediaStore
import android.text.TextUtils import android.text.TextUtils
@ -112,6 +113,7 @@ class ContactsHelper(val activity: Activity) {
val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: "" val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: ""
val surname = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: "" val surname = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: ""
val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: "" val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: ""
val nickname = ""
val photoUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_URI) ?: "" val photoUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_URI) ?: ""
val number = ArrayList<PhoneNumber>() // proper value is obtained below val number = ArrayList<PhoneNumber>() // proper value is obtained below
val emails = ArrayList<Email>() val emails = ArrayList<Email>()
@ -125,8 +127,8 @@ class ContactsHelper(val activity: Activity) {
val groups = ArrayList<Group>() val groups = ArrayList<Group>()
val organization = Organization("", "") val organization = Organization("", "")
val websites = ArrayList<String>() val websites = ArrayList<String>()
val contact = Contact(id, prefix, firstName, middleName, surname, suffix, photoUri, number, emails, addresses, events, val contact = Contact(id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, number, emails, addresses,
accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites) events, accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites)
contacts.put(id, contact) contacts.put(id, contact)
} while (cursor.moveToNext()) } while (cursor.moveToNext())
@ -144,6 +146,13 @@ class ContactsHelper(val activity: Activity) {
contacts[key]?.phoneNumbers = phoneNumbers.valueAt(i) 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() val emails = getEmails()
size = emails.size() size = emails.size()
for (i in 0 until size) { for (i in 0 until size) {
@ -225,6 +234,36 @@ class ContactsHelper(val activity: Activity) {
return phoneNumbers return phoneNumbers
} }
private fun getNicknames(contactId: Int? = null): SparseArray<String> {
val nicknames = SparseArray<String>()
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<ArrayList<Email>> { private fun getEmails(contactId: Int? = null): SparseArray<ArrayList<Email>> {
val emails = SparseArray<ArrayList<Email>>() val emails = SparseArray<ArrayList<Email>>()
val uri = CommonDataKinds.Email.CONTENT_URI val uri = CommonDataKinds.Email.CONTENT_URI
@ -353,7 +392,7 @@ class ContactsHelper(val activity: Activity) {
if (cursor?.moveToFirst() == true) { if (cursor?.moveToFirst() == true) {
do { do {
val id = cursor.getIntValue(ContactsContract.Data.RAW_CONTACT_ID) 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) notes.put(id, note)
} while (cursor.moveToNext()) } while (cursor.moveToNext())
} }
@ -654,6 +693,7 @@ class ContactsHelper(val activity: Activity) {
val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: "" val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: ""
val surname = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: "" val surname = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: ""
val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: "" val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: ""
val nickname = getNicknames(id)[id] ?: ""
val photoUri = cursor.getStringValue(CommonDataKinds.Phone.PHOTO_URI) ?: "" val photoUri = cursor.getStringValue(CommonDataKinds.Phone.PHOTO_URI) ?: ""
val number = getPhoneNumbers(id)[id] ?: ArrayList() val number = getPhoneNumbers(id)[id] ?: ArrayList()
val emails = getEmails(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 thumbnailUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI) ?: ""
val organization = getOrganizations(id)[id] ?: Organization("", "") val organization = getOrganizations(id)[id] ?: Organization("", "")
val websites = getWebsites(id)[id] ?: ArrayList() val websites = getWebsites(id)[id] ?: ArrayList()
return Contact(id, prefix, firstName, middleName, surname, suffix, photoUri, number, emails, addresses, events, accountName, return Contact(id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, number, emails, addresses, events,
starred, contactId, thumbnailUri, null, notes, groups, organization, websites) accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites)
} }
} finally { } finally {
cursor?.close() cursor?.close()

View File

@ -28,6 +28,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
private val COL_MIDDLE_NAME = "middle_name" private val COL_MIDDLE_NAME = "middle_name"
private val COL_SURNAME = "surname" private val COL_SURNAME = "surname"
private val COL_SUFFIX = "suffix" private val COL_SUFFIX = "suffix"
private val COL_NICKNAME = "nickname"
private val COL_PHOTO = "photo" private val COL_PHOTO = "photo"
private val COL_PHONE_NUMBERS = "phone_numbers" private val COL_PHONE_NUMBERS = "phone_numbers"
private val COL_EMAILS = "emails" private val COL_EMAILS = "emails"
@ -48,9 +49,9 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
private val mDb = writableDatabase private val mDb = writableDatabase
companion object { companion object {
private const val DB_VERSION = 5
const val DB_NAME = "contacts.db" const val DB_NAME = "contacts.db"
var dbInstance: DBHelper? = null private const val DB_VERSION = 6
private var dbInstance: DBHelper? = null
var gson = Gson() var gson = Gson()
fun newInstance(context: Context): DBHelper { 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, " + 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_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)") "$COL_WEBSITES TEXT, $COL_NICKNAME TEXT)")
// start autoincrement ID from FIRST_CONTACT_ID to avoid conflicts // 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)") 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) { if (oldVersion < 5) {
db.execSQL("ALTER TABLE $CONTACTS_TABLE_NAME ADD COLUMN $COL_WEBSITES TEXT DEFAULT ''") 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) { 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_MIDDLE_NAME, contact.middleName)
put(COL_SURNAME, contact.surname) put(COL_SURNAME, contact.surname)
put(COL_SUFFIX, contact.suffix) put(COL_SUFFIX, contact.suffix)
put(COL_NICKNAME, contact.nickname)
put(COL_PHONE_NUMBERS, gson.toJson(contact.phoneNumbers)) put(COL_PHONE_NUMBERS, gson.toJson(contact.phoneNumbers))
put(COL_EMAILS, gson.toJson(contact.emails)) put(COL_EMAILS, gson.toJson(contact.emails))
put(COL_ADDRESSES, gson.toJson(contact.addresses)) 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<String>? = null): ArrayList<Contact> { fun getContacts(activity: Activity, selection: String? = null, selectionArgs: Array<String>? = null): ArrayList<Contact> {
val storedGroups = ContactsHelper(activity).getStoredGroups() val storedGroups = ContactsHelper(activity).getStoredGroups()
val contacts = ArrayList<Contact>() val contacts = ArrayList<Contact>()
val projection = arrayOf(COL_ID, COL_PREFIX, COL_FIRST_NAME, COL_MIDDLE_NAME, COL_SURNAME, COL_SUFFIX, COL_PHONE_NUMBERS, COL_EMAILS, val projection = arrayOf(COL_ID, COL_PREFIX, COL_FIRST_NAME, COL_MIDDLE_NAME, COL_SURNAME, COL_SUFFIX, COL_NICKNAME, COL_PHONE_NUMBERS,
COL_EVENTS, COL_STARRED, COL_PHOTO, COL_ADDRESSES, COL_NOTES, COL_GROUPS, COL_COMPANY, COL_JOB_POSITION, COL_WEBSITES) 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<List<PhoneNumber>>() {}.type val phoneNumbersToken = object : TypeToken<List<PhoneNumber>>() {}.type
val emailsToken = object : TypeToken<List<Email>>() {}.type val emailsToken = object : TypeToken<List<Email>>() {}.type
@ -271,6 +277,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
val middleName = cursor.getStringValue(COL_MIDDLE_NAME) val middleName = cursor.getStringValue(COL_MIDDLE_NAME)
val surname = cursor.getStringValue(COL_SURNAME) val surname = cursor.getStringValue(COL_SURNAME)
val suffix = cursor.getStringValue(COL_SUFFIX) val suffix = cursor.getStringValue(COL_SUFFIX)
val nickname = cursor.getStringValue(COL_NICKNAME)
val phoneNumbersJson = cursor.getStringValue(COL_PHONE_NUMBERS) val phoneNumbersJson = cursor.getStringValue(COL_PHONE_NUMBERS)
val phoneNumbers = if (phoneNumbersJson == "[]") ArrayList() else gson.fromJson<ArrayList<PhoneNumber>>(phoneNumbersJson, phoneNumbersToken) val phoneNumbers = if (phoneNumbersJson == "[]") ArrayList() else gson.fromJson<ArrayList<PhoneNumber>>(phoneNumbersJson, phoneNumbersToken)
@ -315,8 +322,8 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
val websites = if (websitesJson == "[]") ArrayList() else gson.fromJson<ArrayList<String>>(websitesJson, websitesToken) val websites = if (websitesJson == "[]") ArrayList() else gson.fromJson<ArrayList<String>>(websitesJson, websitesToken)
?: ArrayList(1) ?: ArrayList(1)
val contact = Contact(id, prefix, firstName, middleName, surname, suffix, "", phoneNumbers, emails, addresses, events, val contact = Contact(id, prefix, firstName, middleName, surname, suffix, nickname, "", phoneNumbers, emails, addresses,
SMT_PRIVATE, starred, id, "", photo, notes, groups, organization, websites) events, SMT_PRIVATE, starred, id, "", photo, notes, groups, organization, websites)
contacts.add(contact) contacts.add(contact)
} }
} }

View File

@ -25,6 +25,7 @@ class VcfImporter(val activity: SimpleActivity) {
private var curMiddleName = "" private var curMiddleName = ""
private var curSurname = "" private var curSurname = ""
private var curSuffix = "" private var curSuffix = ""
private var curNickname = ""
private var curPhotoUri = "" private var curPhotoUri = ""
private var curNotes = "" private var curNotes = ""
private var curCompany = "" private var curCompany = ""
@ -305,8 +306,8 @@ class VcfImporter(val activity: SimpleActivity) {
private fun saveContact(source: String) { private fun saveContact(source: String) {
val organization = Organization(curCompany, curJobPosition) val organization = Organization(curCompany, curJobPosition)
val contact = Contact(0, curPrefix, curFirstName, curMiddleName, curSurname, curSuffix, curPhotoUri, curPhoneNumbers, curEmails, curAddresses, curEvents, val contact = Contact(0, curPrefix, curFirstName, curMiddleName, curSurname, curSuffix, curNickname, curPhotoUri, curPhoneNumbers,
source, 0, 0, "", null, curNotes, curGroups, organization, curWebsites) curEmails, curAddresses, curEvents, source, 0, 0, "", null, curNotes, curGroups, organization, curWebsites)
if (ContactsHelper(activity).insertContact(contact)) { if (ContactsHelper(activity).insertContact(contact)) {
contactsImported++ contactsImported++
@ -319,6 +320,7 @@ class VcfImporter(val activity: SimpleActivity) {
curMiddleName = "" curMiddleName = ""
curSurname = "" curSurname = ""
curSuffix = "" curSuffix = ""
curNickname = ""
curPhotoUri = "" curPhotoUri = ""
curNotes = "" curNotes = ""
curCompany = "" curCompany = ""

View File

@ -7,9 +7,9 @@ import com.simplemobiletools.commons.helpers.SORT_BY_MIDDLE_NAME
import com.simplemobiletools.commons.helpers.SORT_DESCENDING import com.simplemobiletools.commons.helpers.SORT_DESCENDING
import com.simplemobiletools.contacts.helpers.PHONE_NUMBER_PATTERN 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, 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 phoneNumbers: ArrayList<PhoneNumber>, var emails: ArrayList<Email>, var addresses: ArrayList<Address>, var events: ArrayList<Event>, var photoUri: String, var phoneNumbers: ArrayList<PhoneNumber>, var emails: ArrayList<Email>, var addresses: ArrayList<Address>,
var source: String, var starred: Int, val contactId: Int, val thumbnailUri: String, var photo: Bitmap?, var notes: String, var events: ArrayList<Event>, var source: String, var starred: Int, val contactId: Int, val thumbnailUri: String, var photo: Bitmap?, var notes: String,
var groups: ArrayList<Group>, var organization: Organization, var websites: ArrayList<String>) : Comparable<Contact> { var groups: ArrayList<Group>, var organization: Organization, var websites: ArrayList<String>) : Comparable<Contact> {
companion object { companion object {
var sorting = 0 var sorting = 0