mirror of
https://github.com/SimpleMobileTools/Simple-Contacts.git
synced 2025-06-05 21:59:27 +02:00
make use of the system string normalizing instead of custom regex
This commit is contained in:
@ -168,7 +168,7 @@ class EditContactActivity : ContactActivity() {
|
||||
val phone = intent.extras.get(KEY_PHONE)
|
||||
if (phone != null) {
|
||||
val phoneNumber = phone.toString()
|
||||
contact!!.phoneNumbers.add(PhoneNumber(phoneNumber, DEFAULT_PHONE_NUMBER_TYPE, ""))
|
||||
contact!!.phoneNumbers.add(PhoneNumber(phoneNumber, DEFAULT_PHONE_NUMBER_TYPE, "", phoneNumber.normalizeNumber()))
|
||||
if (phoneNumber.isNotEmpty() && action == ADD_NEW_CONTACT_NUMBER) {
|
||||
highlightLastPhoneNumber = true
|
||||
}
|
||||
@ -883,7 +883,7 @@ class EditContactActivity : ContactActivity() {
|
||||
val numberLabel = if (numberType == CommonDataKinds.Phone.TYPE_CUSTOM) numberHolder.contact_number_type.value else ""
|
||||
|
||||
if (number.isNotEmpty()) {
|
||||
phoneNumbers.add(PhoneNumber(number, numberType, numberLabel))
|
||||
phoneNumbers.add(PhoneNumber(number, numberType, numberLabel, number.normalizeNumber()))
|
||||
}
|
||||
}
|
||||
return phoneNumbers
|
||||
|
@ -36,7 +36,7 @@ fun Context.getEmptyContact(): Contact {
|
||||
val originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE
|
||||
val organization = Organization("", "")
|
||||
return Contact(0, "", "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "",
|
||||
null, "", ArrayList(), organization, ArrayList(), ArrayList(), ArrayList())
|
||||
null, "", ArrayList(), organization, ArrayList(), ArrayList())
|
||||
}
|
||||
|
||||
fun Context.viewContact(contact: Contact) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.simplemobiletools.contacts.pro.extensions
|
||||
|
||||
import android.telephony.PhoneNumberUtils
|
||||
import android.widget.TextView
|
||||
import com.simplemobiletools.commons.helpers.getDateFormats
|
||||
import com.simplemobiletools.contacts.pro.helpers.PHONE_NUMBER_PATTERN
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.format.DateTimeFormat
|
||||
import java.text.DateFormat
|
||||
@ -34,4 +34,4 @@ fun String.getDateTimeFromDateString(viewToUpdate: TextView? = null): DateTime {
|
||||
return date
|
||||
}
|
||||
|
||||
fun String.applyRegexFiltering() = replace(PHONE_NUMBER_PATTERN.toRegex(), "")
|
||||
fun String.normalizeNumber() = PhoneNumberUtils.normalizeNumber(this)
|
||||
|
@ -9,8 +9,8 @@ import com.simplemobiletools.commons.helpers.PERMISSION_READ_CALL_LOG
|
||||
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CALL_LOG
|
||||
import com.simplemobiletools.contacts.pro.activities.EditContactActivity
|
||||
import com.simplemobiletools.contacts.pro.adapters.RecentCallsAdapter
|
||||
import com.simplemobiletools.contacts.pro.extensions.applyRegexFiltering
|
||||
import com.simplemobiletools.contacts.pro.extensions.contactClicked
|
||||
import com.simplemobiletools.contacts.pro.extensions.normalizeNumber
|
||||
import com.simplemobiletools.contacts.pro.helpers.IS_FROM_SIMPLE_CONTACTS
|
||||
import com.simplemobiletools.contacts.pro.helpers.KEY_PHONE
|
||||
import com.simplemobiletools.contacts.pro.helpers.RECENTS_TAB_MASK
|
||||
@ -43,10 +43,10 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
||||
val currAdapter = fragment_list.adapter
|
||||
if (currAdapter == null) {
|
||||
RecentCallsAdapter(activity!!, recentCalls, activity, fragment_list, fragment_fastscroller) {
|
||||
val recentCall = (it as RecentCall).number.applyRegexFiltering()
|
||||
val recentCall = (it as RecentCall).number.normalizeNumber()
|
||||
var selectedContact: Contact? = null
|
||||
for (contact in allContacts) {
|
||||
if (contact.phoneNumbers.any { it.value.applyRegexFiltering() == recentCall }) {
|
||||
if (contact.phoneNumbers.any { it.normalizedNumber == recentCall }) {
|
||||
selectedContact = contact
|
||||
break
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ 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 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
|
||||
|
@ -96,8 +96,8 @@ class ContactsHelper(val activity: Activity) {
|
||||
Thread {
|
||||
val uri = CommonDataKinds.Phone.CONTENT_URI
|
||||
val projection = arrayOf(ContactsContract.Data.RAW_CONTACT_ID)
|
||||
val selection = "${CommonDataKinds.Phone.NUMBER} = ?"
|
||||
val selectionArgs = arrayOf(number)
|
||||
val selection = "${CommonDataKinds.Phone.NORMALIZED_NUMBER} = ?"
|
||||
val selectionArgs = arrayOf(number.normalizeNumber())
|
||||
|
||||
var cursor: Cursor? = null
|
||||
try {
|
||||
@ -180,10 +180,9 @@ class ContactsHelper(val activity: Activity) {
|
||||
val groups = ArrayList<Group>()
|
||||
val organization = Organization("", "")
|
||||
val websites = ArrayList<String>()
|
||||
val cleanNumbers = ArrayList<PhoneNumber>()
|
||||
val ims = ArrayList<IM>()
|
||||
val contact = Contact(id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, numbers, emails, addresses,
|
||||
events, accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, cleanNumbers, ims)
|
||||
events, accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, ims)
|
||||
|
||||
contacts.put(id, contact)
|
||||
} while (cursor.moveToNext())
|
||||
@ -194,7 +193,6 @@ class ContactsHelper(val activity: Activity) {
|
||||
cursor?.close()
|
||||
}
|
||||
|
||||
val filterDuplicates = activity.config.filterDuplicates
|
||||
val phoneNumbers = getPhoneNumbers(null)
|
||||
var size = phoneNumbers.size()
|
||||
for (i in 0 until size) {
|
||||
@ -202,13 +200,6 @@ class ContactsHelper(val activity: Activity) {
|
||||
if (contacts[key] != null) {
|
||||
val numbers = phoneNumbers.valueAt(i)
|
||||
contacts[key].phoneNumbers = numbers
|
||||
|
||||
if (filterDuplicates) {
|
||||
// remove all spaces, dashes etc from numbers for easier comparing, used only at list views
|
||||
numbers.forEach {
|
||||
numbers.mapTo(contacts[key].cleanPhoneNumbers) { PhoneNumber(it.value.applyRegexFiltering(), 0, "") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,6 +266,7 @@ class ContactsHelper(val activity: Activity) {
|
||||
val projection = arrayOf(
|
||||
ContactsContract.Data.RAW_CONTACT_ID,
|
||||
CommonDataKinds.Phone.NUMBER,
|
||||
CommonDataKinds.Phone.NORMALIZED_NUMBER,
|
||||
CommonDataKinds.Phone.TYPE,
|
||||
CommonDataKinds.Phone.LABEL
|
||||
)
|
||||
@ -289,6 +281,7 @@ class ContactsHelper(val activity: Activity) {
|
||||
do {
|
||||
val id = cursor.getIntValue(ContactsContract.Data.RAW_CONTACT_ID)
|
||||
val number = cursor.getStringValue(CommonDataKinds.Phone.NUMBER) ?: continue
|
||||
val normalizedNumber = cursor.getStringValue(CommonDataKinds.Phone.NORMALIZED_NUMBER) ?: ""
|
||||
val type = cursor.getIntValue(CommonDataKinds.Phone.TYPE)
|
||||
val label = cursor.getStringValue(CommonDataKinds.Phone.LABEL) ?: ""
|
||||
|
||||
@ -296,7 +289,7 @@ class ContactsHelper(val activity: Activity) {
|
||||
phoneNumbers.put(id, ArrayList())
|
||||
}
|
||||
|
||||
val phoneNumber = PhoneNumber(number, type, label)
|
||||
val phoneNumber = PhoneNumber(number, type, label, normalizedNumber)
|
||||
phoneNumbers[id].add(phoneNumber)
|
||||
} while (cursor.moveToNext())
|
||||
}
|
||||
@ -837,10 +830,9 @@ 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()
|
||||
val cleanNumbers = ArrayList<PhoneNumber>()
|
||||
val ims = getIMs(id)[id] ?: ArrayList()
|
||||
return Contact(id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, number, emails, addresses, events,
|
||||
accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, cleanNumbers, ims)
|
||||
accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, ims)
|
||||
}
|
||||
} finally {
|
||||
cursor?.close()
|
||||
@ -990,6 +982,7 @@ class ContactsHelper(val activity: Activity) {
|
||||
withValue(ContactsContract.Data.RAW_CONTACT_ID, contact.id)
|
||||
withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
||||
withValue(CommonDataKinds.Phone.NUMBER, it.value)
|
||||
withValue(CommonDataKinds.Phone.NORMALIZED_NUMBER, it.normalizedNumber)
|
||||
withValue(CommonDataKinds.Phone.TYPE, it.type)
|
||||
withValue(CommonDataKinds.Phone.LABEL, it.label)
|
||||
operations.add(build())
|
||||
@ -1292,6 +1285,7 @@ class ContactsHelper(val activity: Activity) {
|
||||
withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
||||
withValue(CommonDataKinds.Phone.NUMBER, it.value)
|
||||
withValue(CommonDataKinds.Phone.NORMALIZED_NUMBER, it.normalizedNumber)
|
||||
withValue(CommonDataKinds.Phone.TYPE, it.type)
|
||||
withValue(CommonDataKinds.Phone.LABEL, it.label)
|
||||
operations.add(build())
|
||||
|
@ -5,8 +5,14 @@ import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.provider.MediaStore
|
||||
import com.simplemobiletools.contacts.pro.extensions.*
|
||||
import com.simplemobiletools.contacts.pro.models.*
|
||||
import com.simplemobiletools.contacts.pro.extensions.contactsDB
|
||||
import com.simplemobiletools.contacts.pro.extensions.getByteArray
|
||||
import com.simplemobiletools.contacts.pro.extensions.getEmptyContact
|
||||
import com.simplemobiletools.contacts.pro.extensions.getPhotoThumbnailSize
|
||||
import com.simplemobiletools.contacts.pro.models.Contact
|
||||
import com.simplemobiletools.contacts.pro.models.Group
|
||||
import com.simplemobiletools.contacts.pro.models.LocalContact
|
||||
import com.simplemobiletools.contacts.pro.models.Organization
|
||||
|
||||
class LocalContactsHelper(val activity: Activity) {
|
||||
fun getAllContacts() = activity.contactsDB.getContacts().map { convertLocalContactToContact(it) }.toMutableList() as ArrayList<Contact>
|
||||
@ -81,12 +87,6 @@ class LocalContactsHelper(val activity: Activity) {
|
||||
return null
|
||||
}
|
||||
|
||||
val filterDuplicates = activity.config.filterDuplicates
|
||||
val filteredPhoneNumbers = ArrayList<PhoneNumber>()
|
||||
if (filterDuplicates) {
|
||||
localContact.phoneNumbers.mapTo(filteredPhoneNumbers) { PhoneNumber(it.value.applyRegexFiltering(), 0, "") }
|
||||
}
|
||||
|
||||
val contactPhoto = if (localContact.photo == null) {
|
||||
null
|
||||
} else {
|
||||
@ -121,7 +121,6 @@ class LocalContactsHelper(val activity: Activity) {
|
||||
groups = storedGroups.filter { localContact.groups.contains(it.id) } as ArrayList<Group>
|
||||
organization = Organization(localContact.company, localContact.jobPosition)
|
||||
websites = localContact.websites
|
||||
cleanPhoneNumbers = filteredPhoneNumbers
|
||||
IMs = localContact.IMs
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import com.simplemobiletools.contacts.pro.activities.SimpleActivity
|
||||
import com.simplemobiletools.contacts.pro.extensions.getCachePhoto
|
||||
import com.simplemobiletools.contacts.pro.extensions.getCachePhotoUri
|
||||
import com.simplemobiletools.contacts.pro.extensions.groupsDB
|
||||
import com.simplemobiletools.contacts.pro.extensions.normalizeNumber
|
||||
import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.*
|
||||
import com.simplemobiletools.contacts.pro.models.*
|
||||
import ezvcard.Ezvcard
|
||||
@ -59,7 +60,7 @@ class VcfImporter(val activity: SimpleActivity) {
|
||||
""
|
||||
}
|
||||
|
||||
phoneNumbers.add(PhoneNumber(number, type, label))
|
||||
phoneNumbers.add(PhoneNumber(number, type, label, number.normalizeNumber()))
|
||||
}
|
||||
|
||||
val emails = ArrayList<Email>()
|
||||
@ -112,7 +113,6 @@ class VcfImporter(val activity: SimpleActivity) {
|
||||
val photoData = ezContact.photos.firstOrNull()?.data
|
||||
val photo = null
|
||||
val thumbnailUri = savePhoto(photoData)
|
||||
val cleanPhoneNumbers = ArrayList<PhoneNumber>()
|
||||
|
||||
val IMs = ArrayList<IM>()
|
||||
ezContact.impps.forEach {
|
||||
@ -136,7 +136,7 @@ class VcfImporter(val activity: SimpleActivity) {
|
||||
}
|
||||
|
||||
val contact = Contact(0, prefix, firstName, middleName, surname, suffix, nickname, photoUri, phoneNumbers, emails, addresses, events,
|
||||
targetContactSource, starred, contactId, thumbnailUri, photo, notes, groups, organization, websites, cleanPhoneNumbers, IMs)
|
||||
targetContactSource, starred, contactId, thumbnailUri, photo, notes, groups, organization, websites, IMs)
|
||||
|
||||
// if there is no N and ORG fields at the given contact, only FN, treat it as an organization
|
||||
if (contact.getNameToDisplay().isEmpty() && contact.organization.isEmpty() && ezContact.formattedName.value.isNotEmpty()) {
|
||||
|
@ -5,13 +5,12 @@ import com.simplemobiletools.commons.extensions.normalizeString
|
||||
import com.simplemobiletools.commons.helpers.SORT_BY_FIRST_NAME
|
||||
import com.simplemobiletools.commons.helpers.SORT_BY_MIDDLE_NAME
|
||||
import com.simplemobiletools.commons.helpers.SORT_DESCENDING
|
||||
import com.simplemobiletools.contacts.pro.extensions.applyRegexFiltering
|
||||
import com.simplemobiletools.contacts.pro.extensions.normalizeNumber
|
||||
|
||||
data class Contact(var 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<PhoneNumber>, var emails: ArrayList<Email>, var addresses: ArrayList<Address>,
|
||||
var events: ArrayList<Event>, var source: String, var starred: Int, var contactId: Int, var thumbnailUri: String, var photo: Bitmap?, var notes: String,
|
||||
var groups: ArrayList<Group>, var organization: Organization, var websites: ArrayList<String>, var cleanPhoneNumbers: ArrayList<PhoneNumber>,
|
||||
var IMs: ArrayList<IM>) :
|
||||
var groups: ArrayList<Group>, var organization: Organization, var websites: ArrayList<String>, var IMs: ArrayList<IM>) :
|
||||
Comparable<Contact> {
|
||||
companion object {
|
||||
var sorting = 0
|
||||
@ -126,21 +125,11 @@ data class Contact(var id: Int, var prefix: String, var firstName: String, var m
|
||||
|
||||
fun isABusinessContact() = prefix.isEmpty() && firstName.isEmpty() && middleName.isEmpty() && surname.isEmpty() && suffix.isEmpty() && organization.isNotEmpty()
|
||||
|
||||
// do a more advanced phone number check here, compare numbers and and search query with dashes, spaces and everything but numbers removed
|
||||
fun doesContainPhoneNumber(text: String): Boolean {
|
||||
if (text.isNotEmpty()) {
|
||||
if (phoneNumbers.any { it.value.contains(text) } || cleanPhoneNumbers.any { it.value.contains(text) }) {
|
||||
return true
|
||||
}
|
||||
return if (text.isNotEmpty()) {
|
||||
phoneNumbers.any { it.value.contains(text) || it.normalizedNumber?.contains(text.normalizeNumber()) == true || it.value.normalizeNumber().contains(text.normalizeNumber()) }
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
val filteredNumber = text.applyRegexFiltering()
|
||||
if (filteredNumber.isNotEmpty()) {
|
||||
if (phoneNumbers.any { it.value.contains(filteredNumber) } || cleanPhoneNumbers.any { it.value.contains(filteredNumber) }) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
package com.simplemobiletools.contacts.pro.models
|
||||
|
||||
data class PhoneNumber(var value: String, var type: Int, var label: String)
|
||||
data class PhoneNumber(var value: String, var type: Int, var label: String, var normalizedNumber: String?)
|
||||
|
Reference in New Issue
Block a user