mirror of
				https://github.com/SimpleMobileTools/Simple-Contacts.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	handle contact adding/removing from groups
This commit is contained in:
		@@ -7,6 +7,7 @@ import androidx.room.RoomDatabase
 | 
			
		||||
import androidx.room.TypeConverters
 | 
			
		||||
import androidx.sqlite.db.SupportSQLiteDatabase
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.Converters
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.FIRST_CONTACT_ID
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.FIRST_GROUP_ID
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.getEmptyLocalContact
 | 
			
		||||
import com.simplemobiletools.contacts.pro.interfaces.ContactsDao
 | 
			
		||||
@@ -25,8 +26,6 @@ abstract class ContactsDatabase : RoomDatabase() {
 | 
			
		||||
    abstract fun GroupsDao(): GroupsDao
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private const val FIRST_CONTACT_ID = 1000000
 | 
			
		||||
 | 
			
		||||
        private var db: ContactsDatabase? = null
 | 
			
		||||
 | 
			
		||||
        fun getInstance(context: Context): ContactsDatabase {
 | 
			
		||||
 
 | 
			
		||||
@@ -171,26 +171,26 @@ fun BaseSimpleActivity.getTempFile(): File? {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun BaseSimpleActivity.addContactsToGroup(contacts: ArrayList<Contact>, groupId: Long) {
 | 
			
		||||
    val publicContacts = contacts.filter { it.source != SMT_PRIVATE }
 | 
			
		||||
    val privateContacts = contacts.filter { it.source == SMT_PRIVATE }
 | 
			
		||||
    val publicContacts = contacts.filter { it.source != SMT_PRIVATE }.toMutableList() as ArrayList<Contact>
 | 
			
		||||
    val privateContacts = contacts.filter { it.source == SMT_PRIVATE }.toMutableList() as ArrayList<Contact>
 | 
			
		||||
    if (publicContacts.isNotEmpty()) {
 | 
			
		||||
        ContactsHelper(this).addContactsToGroup(contacts, groupId)
 | 
			
		||||
        ContactsHelper(this).addContactsToGroup(publicContacts, groupId)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (privateContacts.isNotEmpty()) {
 | 
			
		||||
        dbHelper.addContactsToGroup(contacts, groupId)
 | 
			
		||||
        LocalContactsHelper(this).addContactsToGroup(privateContacts, groupId)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun BaseSimpleActivity.removeContactsFromGroup(contacts: ArrayList<Contact>, groupId: Long) {
 | 
			
		||||
    val publicContacts = contacts.filter { it.source != SMT_PRIVATE }
 | 
			
		||||
    val privateContacts = contacts.filter { it.source == SMT_PRIVATE }
 | 
			
		||||
    val publicContacts = contacts.filter { it.source != SMT_PRIVATE }.toMutableList() as ArrayList<Contact>
 | 
			
		||||
    val privateContacts = contacts.filter { it.source == SMT_PRIVATE }.toMutableList() as ArrayList<Contact>
 | 
			
		||||
    if (publicContacts.isNotEmpty() && hasContactPermissions()) {
 | 
			
		||||
        ContactsHelper(this).removeContactsFromGroup(contacts, groupId)
 | 
			
		||||
        ContactsHelper(this).removeContactsFromGroup(publicContacts, groupId)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (privateContacts.isNotEmpty()) {
 | 
			
		||||
        dbHelper.removeContactsFromGroup(contacts, groupId)
 | 
			
		||||
        LocalContactsHelper(this).removeContactsFromGroup(privateContacts, groupId)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,10 @@ import com.simplemobiletools.contacts.pro.R
 | 
			
		||||
import com.simplemobiletools.contacts.pro.activities.EditContactActivity
 | 
			
		||||
import com.simplemobiletools.contacts.pro.activities.ViewContactActivity
 | 
			
		||||
import com.simplemobiletools.contacts.pro.databases.ContactsDatabase
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.*
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.CONTACT_ID
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.Config
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.IS_PRIVATE
 | 
			
		||||
import com.simplemobiletools.contacts.pro.helpers.SMT_PRIVATE
 | 
			
		||||
import com.simplemobiletools.contacts.pro.interfaces.ContactsDao
 | 
			
		||||
import com.simplemobiletools.contacts.pro.interfaces.GroupsDao
 | 
			
		||||
import com.simplemobiletools.contacts.pro.models.Contact
 | 
			
		||||
@@ -25,8 +28,6 @@ import java.io.File
 | 
			
		||||
 | 
			
		||||
val Context.config: Config get() = Config.newInstance(applicationContext)
 | 
			
		||||
 | 
			
		||||
val Context.dbHelper: DBHelper get() = DBHelper.newInstance(applicationContext)
 | 
			
		||||
 | 
			
		||||
val Context.contactsDB: ContactsDao get() = ContactsDatabase.getInstance(applicationContext).ContactsDao()
 | 
			
		||||
 | 
			
		||||
val Context.groupsDB: GroupsDao get() = ContactsDatabase.getInstance(applicationContext).GroupsDao()
 | 
			
		||||
 
 | 
			
		||||
@@ -22,10 +22,11 @@ const val CONTACT_ID = "contact_id"
 | 
			
		||||
const val SMT_PRIVATE = "smt_private"   // used at the contact source of local contacts hidden from other apps
 | 
			
		||||
const val IS_PRIVATE = "is_private"
 | 
			
		||||
const val GROUP = "group"
 | 
			
		||||
const val FIRST_GROUP_ID = 10000L
 | 
			
		||||
const val PHONE_NUMBER_PATTERN = "[^0-9#*+]"
 | 
			
		||||
const val IS_FROM_SIMPLE_CONTACTS = "is_from_simple_contacts"
 | 
			
		||||
const val ADD_NEW_CONTACT_NUMBER = "add_new_contact_number"
 | 
			
		||||
const val FIRST_CONTACT_ID = 1000000
 | 
			
		||||
const val FIRST_GROUP_ID = 10000L
 | 
			
		||||
 | 
			
		||||
// extras used at third party intents
 | 
			
		||||
const val KEY_PHONE = "phone"
 | 
			
		||||
 
 | 
			
		||||
@@ -7,12 +7,12 @@ import com.simplemobiletools.contacts.pro.models.*
 | 
			
		||||
 | 
			
		||||
class Converters {
 | 
			
		||||
    private val gson = Gson()
 | 
			
		||||
    private val longType = object : TypeToken<List<Long>>() {}.type
 | 
			
		||||
    private val stringType = object : TypeToken<List<String>>() {}.type
 | 
			
		||||
    private val numberType = object : TypeToken<List<PhoneNumber>>() {}.type
 | 
			
		||||
    private val emailType = object : TypeToken<List<Email>>() {}.type
 | 
			
		||||
    private val addressType = object : TypeToken<List<Address>>() {}.type
 | 
			
		||||
    private val eventType = object : TypeToken<List<Event>>() {}.type
 | 
			
		||||
    private val groupType = object : TypeToken<List<Group>>() {}.type
 | 
			
		||||
    private val imType = object : TypeToken<List<IM>>() {}.type
 | 
			
		||||
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
@@ -21,6 +21,12 @@ class Converters {
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    fun stringListToJson(list: ArrayList<String>) = gson.toJson(list)
 | 
			
		||||
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    fun jsonToLongList(value: String) = gson.fromJson<ArrayList<Long>>(value, longType)
 | 
			
		||||
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    fun longListToJson(list: ArrayList<Long>) = gson.toJson(list)
 | 
			
		||||
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    fun jsonToPhoneNumberList(value: String) = gson.fromJson<ArrayList<PhoneNumber>>(value, numberType)
 | 
			
		||||
 | 
			
		||||
@@ -45,12 +51,6 @@ class Converters {
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    fun eventListToJson(list: ArrayList<Event>) = gson.toJson(list)
 | 
			
		||||
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    fun jsonToGroupList(value: String) = gson.fromJson<ArrayList<Group>>(value, groupType)
 | 
			
		||||
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    fun groupListToJson(list: ArrayList<Group>) = gson.toJson(list)
 | 
			
		||||
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    fun jsonToIMsList(value: String) = gson.fromJson<ArrayList<IM>>(value, imType)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,208 +0,0 @@
 | 
			
		||||
package com.simplemobiletools.contacts.pro.helpers
 | 
			
		||||
 | 
			
		||||
import android.app.Activity
 | 
			
		||||
import android.content.ContentValues
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.database.sqlite.SQLiteDatabase
 | 
			
		||||
import android.database.sqlite.SQLiteOpenHelper
 | 
			
		||||
import android.graphics.BitmapFactory
 | 
			
		||||
import com.google.gson.Gson
 | 
			
		||||
import com.google.gson.reflect.TypeToken
 | 
			
		||||
import com.simplemobiletools.commons.extensions.getBlobValue
 | 
			
		||||
import com.simplemobiletools.commons.extensions.getIntValue
 | 
			
		||||
import com.simplemobiletools.commons.extensions.getStringValue
 | 
			
		||||
import com.simplemobiletools.contacts.pro.extensions.applyRegexFiltering
 | 
			
		||||
import com.simplemobiletools.contacts.pro.extensions.config
 | 
			
		||||
import com.simplemobiletools.contacts.pro.models.*
 | 
			
		||||
 | 
			
		||||
class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
 | 
			
		||||
    private val CONTACTS_TABLE_NAME = "contacts"
 | 
			
		||||
    private val COL_ID = "id"
 | 
			
		||||
    private val COL_PREFIX = "prefix"
 | 
			
		||||
    private val COL_FIRST_NAME = "first_name"
 | 
			
		||||
    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"
 | 
			
		||||
    private val COL_EVENTS = "events"
 | 
			
		||||
    private val COL_STARRED = "starred"
 | 
			
		||||
    private val COL_ADDRESSES = "addresses"
 | 
			
		||||
    private val COL_IMS = "ims"
 | 
			
		||||
    private val COL_NOTES = "notes"
 | 
			
		||||
    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"
 | 
			
		||||
 | 
			
		||||
    private val FIRST_CONTACT_ID = 1000000
 | 
			
		||||
 | 
			
		||||
    private val mDb = writableDatabase
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val DB_NAME = "contacts.db"
 | 
			
		||||
        private const val DB_VERSION = 7
 | 
			
		||||
        private var dbInstance: DBHelper? = null
 | 
			
		||||
        var gson = Gson()
 | 
			
		||||
 | 
			
		||||
        fun newInstance(context: Context): DBHelper {
 | 
			
		||||
            if (dbInstance == null)
 | 
			
		||||
                dbInstance = DBHelper(context)
 | 
			
		||||
 | 
			
		||||
            return dbInstance!!
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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_WEBSITES TEXT, $COL_NICKNAME TEXT, $COL_IMS 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)")
 | 
			
		||||
 | 
			
		||||
        createGroupsTable(db)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {}
 | 
			
		||||
 | 
			
		||||
    private fun createGroupsTable(db: SQLiteDatabase) {
 | 
			
		||||
        db.execSQL("CREATE TABLE $GROUPS_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_TITLE TEXT)")
 | 
			
		||||
 | 
			
		||||
        // start autoincrement ID from FIRST_GROUP_ID to avoid conflicts
 | 
			
		||||
        db.execSQL("REPLACE INTO sqlite_sequence (name, seq) VALUES ('$GROUPS_TABLE_NAME', $FIRST_GROUP_ID)")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addContactsToGroup(contacts: ArrayList<Contact>, groupId: Long) {
 | 
			
		||||
        contacts.forEach {
 | 
			
		||||
            val currentGroupIds = it.groups.map { it.id } as ArrayList<Long>
 | 
			
		||||
            currentGroupIds.add(groupId)
 | 
			
		||||
            updateContactGroups(it, currentGroupIds)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun removeContactsFromGroup(contacts: ArrayList<Contact>, groupId: Long) {
 | 
			
		||||
        contacts.forEach {
 | 
			
		||||
            val currentGroupIds = it.groups.map { it.id } as ArrayList<Long>
 | 
			
		||||
            currentGroupIds.remove(groupId)
 | 
			
		||||
            updateContactGroups(it, currentGroupIds)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun updateContactGroups(contact: Contact, groupIds: ArrayList<Long>) {
 | 
			
		||||
        val contactValues = fillContactGroupValues(groupIds)
 | 
			
		||||
        val selection = "$COL_ID = ?"
 | 
			
		||||
        val selectionArgs = arrayOf(contact.id.toString())
 | 
			
		||||
        mDb.update(CONTACTS_TABLE_NAME, contactValues, selection, selectionArgs)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun fillContactGroupValues(groupIds: ArrayList<Long>): ContentValues {
 | 
			
		||||
        return ContentValues().apply {
 | 
			
		||||
            put(COL_GROUPS, gson.toJson(groupIds))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getContacts(activity: Activity, selection: String? = null, selectionArgs: Array<String>? = null): ArrayList<Contact> {
 | 
			
		||||
        val storedGroups = ContactsHelper(activity).getStoredGroupsSync()
 | 
			
		||||
        val filterDuplicates = activity.config.filterDuplicates
 | 
			
		||||
        val contacts = ArrayList<Contact>()
 | 
			
		||||
        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_IMS, COL_NOTES, COL_GROUPS, COL_COMPANY, COL_JOB_POSITION, COL_WEBSITES)
 | 
			
		||||
 | 
			
		||||
        val phoneNumbersToken = object : TypeToken<List<PhoneNumber>>() {}.type
 | 
			
		||||
        val emailsToken = object : TypeToken<List<Email>>() {}.type
 | 
			
		||||
        val addressesToken = object : TypeToken<List<Address>>() {}.type
 | 
			
		||||
        val IMsToken = object : TypeToken<List<IM>>() {}.type
 | 
			
		||||
        val eventsToken = object : TypeToken<List<Event>>() {}.type
 | 
			
		||||
        val groupIdsToken = object : TypeToken<List<Long>>() {}.type
 | 
			
		||||
        val websitesToken = object : TypeToken<List<String>>() {}.type
 | 
			
		||||
 | 
			
		||||
        val cursor = mDb.query(CONTACTS_TABLE_NAME, projection, selection, selectionArgs, null, null, null)
 | 
			
		||||
        cursor.use {
 | 
			
		||||
            while (cursor.moveToNext()) {
 | 
			
		||||
                val id = cursor.getIntValue(COL_ID)
 | 
			
		||||
                val prefix = cursor.getStringValue(COL_PREFIX)
 | 
			
		||||
                val firstName = cursor.getStringValue(COL_FIRST_NAME)
 | 
			
		||||
                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<ArrayList<PhoneNumber>>(phoneNumbersJson, phoneNumbersToken)
 | 
			
		||||
                        ?: ArrayList(1)
 | 
			
		||||
 | 
			
		||||
                // labels can be null at upgrading from older app versions, when the label wasn't available at all yet
 | 
			
		||||
                phoneNumbers.filter { it.label == null }.forEach {
 | 
			
		||||
                    it.label = ""
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                val emailsJson = cursor.getStringValue(COL_EMAILS)
 | 
			
		||||
                val emails = if (emailsJson == "[]") ArrayList() else gson.fromJson<ArrayList<Email>>(emailsJson, emailsToken)
 | 
			
		||||
                        ?: ArrayList(1)
 | 
			
		||||
 | 
			
		||||
                emails.filter { it.label == null }.forEach {
 | 
			
		||||
                    it.label = ""
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                val addressesJson = cursor.getStringValue(COL_ADDRESSES)
 | 
			
		||||
                val addresses = if (addressesJson == "[]") ArrayList() else gson.fromJson<ArrayList<Address>>(addressesJson, addressesToken)
 | 
			
		||||
                        ?: ArrayList(1)
 | 
			
		||||
 | 
			
		||||
                addresses.filter { it.label == null }.forEach {
 | 
			
		||||
                    it.label = ""
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                val IMsJson = cursor.getStringValue(COL_IMS)
 | 
			
		||||
                val IMs = if (IMsJson == "[]") ArrayList() else gson.fromJson<ArrayList<IM>>(IMsJson, IMsToken) ?: ArrayList(1)
 | 
			
		||||
 | 
			
		||||
                val eventsJson = cursor.getStringValue(COL_EVENTS)
 | 
			
		||||
                val events = if (eventsJson == "[]") ArrayList() else gson.fromJson<ArrayList<Event>>(eventsJson, eventsToken)
 | 
			
		||||
                        ?: ArrayList(1)
 | 
			
		||||
 | 
			
		||||
                val photoByteArray = cursor.getBlobValue(COL_PHOTO) ?: null
 | 
			
		||||
                val photo = if (photoByteArray?.isNotEmpty() == true) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        BitmapFactory.decodeByteArray(photoByteArray, 0, photoByteArray.size)
 | 
			
		||||
                    } catch (e: OutOfMemoryError) {
 | 
			
		||||
                        null
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    null
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                val notes = cursor.getStringValue(COL_NOTES)
 | 
			
		||||
                val starred = cursor.getIntValue(COL_STARRED)
 | 
			
		||||
 | 
			
		||||
                val groupIdsJson = cursor.getStringValue(COL_GROUPS)
 | 
			
		||||
                val groupIds = if (groupIdsJson == "[]") ArrayList() else gson.fromJson<ArrayList<Long>>(groupIdsJson, groupIdsToken)
 | 
			
		||||
                        ?: ArrayList(1)
 | 
			
		||||
                val groups = storedGroups.filter { groupIds.contains(it.id) } as ArrayList<Group>
 | 
			
		||||
 | 
			
		||||
                val company = cursor.getStringValue(COL_COMPANY)
 | 
			
		||||
                val jobPosition = cursor.getStringValue(COL_JOB_POSITION)
 | 
			
		||||
                val organization = Organization(company, jobPosition)
 | 
			
		||||
 | 
			
		||||
                val websitesJson = cursor.getStringValue(COL_WEBSITES)
 | 
			
		||||
                val websites = if (websitesJson == "[]") ArrayList() else gson.fromJson<ArrayList<String>>(websitesJson, websitesToken)
 | 
			
		||||
                        ?: ArrayList(1)
 | 
			
		||||
 | 
			
		||||
                val cleanPhoneNumbers = ArrayList<PhoneNumber>()
 | 
			
		||||
                if (filterDuplicates) {
 | 
			
		||||
                    phoneNumbers.mapTo(cleanPhoneNumbers) { PhoneNumber(it.value.applyRegexFiltering(), 0, "") }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                val contact = Contact(id, prefix, firstName, middleName, surname, suffix, nickname, "", phoneNumbers, emails, addresses,
 | 
			
		||||
                        events, SMT_PRIVATE, starred, id, "", photo, notes, groups, organization, websites, cleanPhoneNumbers, IMs)
 | 
			
		||||
                contacts.add(contact)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return contacts
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,10 +6,7 @@ import android.graphics.BitmapFactory
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import android.provider.MediaStore
 | 
			
		||||
import com.simplemobiletools.contacts.pro.extensions.*
 | 
			
		||||
import com.simplemobiletools.contacts.pro.models.Contact
 | 
			
		||||
import com.simplemobiletools.contacts.pro.models.LocalContact
 | 
			
		||||
import com.simplemobiletools.contacts.pro.models.Organization
 | 
			
		||||
import com.simplemobiletools.contacts.pro.models.PhoneNumber
 | 
			
		||||
import com.simplemobiletools.contacts.pro.models.*
 | 
			
		||||
 | 
			
		||||
class LocalContactsHelper(val activity: Activity) {
 | 
			
		||||
    fun getAllContacts() = activity.contactsDB.getContacts().map { convertLocalContactToContact(it) }.toMutableList() as ArrayList<Contact>
 | 
			
		||||
@@ -21,6 +18,27 @@ class LocalContactsHelper(val activity: Activity) {
 | 
			
		||||
        return activity.contactsDB.insertOrUpdate(localContact) > 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addContactsToGroup(contacts: ArrayList<Contact>, groupId: Long) {
 | 
			
		||||
        contacts.forEach {
 | 
			
		||||
            val localContact = convertContactToLocalContact(it)
 | 
			
		||||
            val newGroups = localContact.groups
 | 
			
		||||
            newGroups.add(groupId)
 | 
			
		||||
            newGroups.distinct()
 | 
			
		||||
            localContact.groups = newGroups
 | 
			
		||||
            activity.contactsDB.insertOrUpdate(localContact)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun removeContactsFromGroup(contacts: ArrayList<Contact>, groupId: Long) {
 | 
			
		||||
        contacts.forEach {
 | 
			
		||||
            val localContact = convertContactToLocalContact(it)
 | 
			
		||||
            val newGroups = localContact.groups
 | 
			
		||||
            newGroups.remove(groupId)
 | 
			
		||||
            localContact.groups = newGroups
 | 
			
		||||
            activity.contactsDB.insertOrUpdate(localContact)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun deleteContactIds(ids: Array<Int>) {
 | 
			
		||||
        ids.forEach {
 | 
			
		||||
            activity.contactsDB.deleteContactId(it)
 | 
			
		||||
@@ -70,6 +88,8 @@ class LocalContactsHelper(val activity: Activity) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val storedGroups = ContactsHelper(activity).getStoredGroupsSync()
 | 
			
		||||
 | 
			
		||||
        return activity.getEmptyContact().apply {
 | 
			
		||||
            id = localContact.id!!
 | 
			
		||||
            prefix = localContact.prefix
 | 
			
		||||
@@ -89,7 +109,7 @@ class LocalContactsHelper(val activity: Activity) {
 | 
			
		||||
            thumbnailUri = ""
 | 
			
		||||
            photo = contactPhoto
 | 
			
		||||
            notes = localContact.notes
 | 
			
		||||
            groups = localContact.groups
 | 
			
		||||
            groups = storedGroups.filter { localContact.groups.contains(it.id) } as ArrayList<Group>
 | 
			
		||||
            organization = Organization(localContact.company, localContact.jobPosition)
 | 
			
		||||
            websites = localContact.websites
 | 
			
		||||
            cleanPhoneNumbers = filteredPhoneNumbers
 | 
			
		||||
@@ -113,7 +133,7 @@ class LocalContactsHelper(val activity: Activity) {
 | 
			
		||||
            starred = contact.starred
 | 
			
		||||
            addresses = contact.addresses
 | 
			
		||||
            notes = contact.notes
 | 
			
		||||
            groups = contact.groups
 | 
			
		||||
            groups = contact.groups.map { it.id }.toMutableList() as ArrayList<Long>
 | 
			
		||||
            company = contact.organization.company
 | 
			
		||||
            jobPosition = contact.organization.jobPosition
 | 
			
		||||
            websites = contact.websites
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ data class LocalContact(
 | 
			
		||||
        @ColumnInfo(name = "starred") var starred: Int,
 | 
			
		||||
        @ColumnInfo(name = "addresses") var addresses: ArrayList<Address>,
 | 
			
		||||
        @ColumnInfo(name = "notes") var notes: String,
 | 
			
		||||
        @ColumnInfo(name = "groups") var groups: ArrayList<Group>,
 | 
			
		||||
        @ColumnInfo(name = "groups") var groups: ArrayList<Long>,
 | 
			
		||||
        @ColumnInfo(name = "company") var company: String,
 | 
			
		||||
        @ColumnInfo(name = "job_position") var jobPosition: String,
 | 
			
		||||
        @ColumnInfo(name = "websites") var websites: ArrayList<String>,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user