diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactEditorViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactEditorViewModel.kt index 6d949e332..207b7a82a 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactEditorViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactEditorViewModel.kt @@ -192,7 +192,7 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactViewModelInt private fun updateNumbersAndAddresses() { val phoneNumbers = arrayListOf() - for (number in c?.phoneNumbers.orEmpty()) { + for (number in c?.rawPhoneNumbers.orEmpty()) { phoneNumbers.add(NumberOrAddressEditorViewModel(number, false)) } if (phoneNumbers.isEmpty()) { diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactNumberOrAddressViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactNumberOrAddressViewModel.kt index c51097c6d..852bdea9b 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactNumberOrAddressViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactNumberOrAddressViewModel.kt @@ -29,6 +29,7 @@ class ContactNumberOrAddressViewModel( val displayedValue: String, val isSip: Boolean = true, val showSecureChat: Boolean = false, + val typeLabel: String = "", private val listener: ContactNumberOrAddressClickListener ) : ViewModel() { val showInvite = !hasPresence && !isSip diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt index 380e23b33..c788020e7 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt @@ -175,14 +175,15 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont val noa = ContactNumberOrAddressViewModel(address, hasPresence, displayValue, showSecureChat = secureChatAllowed, listener = listener) list.add(noa) } - for (number in contact.phoneNumbers) { + for (phoneNumber in contact.phoneNumbers) { + val number = phoneNumber.value val presenceModel = contact.friend?.getPresenceModelForUriOrTel(number) val hasPresence = presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open val contactAddress = presenceModel?.contact ?: number val address = coreContext.core.interpretUrl(contactAddress) val isMe = if (address != null) coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(address) ?: false else false val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(number)?.hasCapability(FriendCapability.LimeX3Dh) ?: false - val noa = ContactNumberOrAddressViewModel(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, listener = listener) + val noa = ContactNumberOrAddressViewModel(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, typeLabel = phoneNumber.typeLabel, listener = listener) list.add(noa) } numbersAndAddresses.value = list diff --git a/app/src/main/java/org/linphone/contact/AsyncContactsLoader.kt b/app/src/main/java/org/linphone/contact/AsyncContactsLoader.kt index b1ced61a4..46f578329 100644 --- a/app/src/main/java/org/linphone/contact/AsyncContactsLoader.kt +++ b/app/src/main/java/org/linphone/contact/AsyncContactsLoader.kt @@ -41,8 +41,8 @@ class AsyncContactsLoader(private val context: Context) : ContactsContract.Contacts.STARRED, ContactsContract.Contacts.LOOKUP_KEY, "data1", // Company, Phone or SIP Address - "data2", // ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME - "data3", // ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME + "data2", // ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.SipAddress.TYPE + "data3", // ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, ContactsContract.CommonDataKinds.Phone.LABEL, ContactsContract.CommonDataKinds.SipAddress.LABEL "data4" ) } @@ -75,6 +75,7 @@ class AsyncContactsLoader(private val context: Context) : contact.sipAddresses.clear() contact.rawSipAddresses.clear() contact.phoneNumbers.clear() + contact.rawPhoneNumbers.clear() androidContactsCache[contact.nativeId] = contact nativeIds.add(contact.nativeId) } else { diff --git a/app/src/main/java/org/linphone/contact/Contact.kt b/app/src/main/java/org/linphone/contact/Contact.kt index 8538462e4..a4778f5e4 100644 --- a/app/src/main/java/org/linphone/contact/Contact.kt +++ b/app/src/main/java/org/linphone/contact/Contact.kt @@ -33,6 +33,12 @@ import org.linphone.core.PresenceBasicStatus import org.linphone.core.tools.Log import org.linphone.utils.ImageUtils +data class PhoneNumber(val value: String, val typeLabel: String) : Comparable { + override fun compareTo(other: PhoneNumber): Int { + return value.compareTo(other.value) + } +} + open class Contact : Comparable { var fullName: String? = null var firstName: String? = null @@ -40,7 +46,8 @@ open class Contact : Comparable { var organization: String? = null var isStarred: Boolean = false - var phoneNumbers = arrayListOf() + var phoneNumbers = arrayListOf() + var rawPhoneNumbers = arrayListOf() var sipAddresses = arrayListOf
() // Raw SIP addresses are only used for contact edition var rawSipAddresses = arrayListOf() @@ -53,7 +60,7 @@ open class Contact : Comparable { if (fn == otherFn) { if (phoneNumbers.size == other.phoneNumbers.size && phoneNumbers.size > 0) { if (phoneNumbers != other.phoneNumbers) { - for (i in 0..phoneNumbers.size) { + for (i in 0 until phoneNumbers.size) { val compare = phoneNumbers[i].compareTo(other.phoneNumbers[i]) if (compare != 0) return compare } @@ -64,7 +71,7 @@ open class Contact : Comparable { if (sipAddresses.size == other.sipAddresses.size && sipAddresses.size > 0) { if (sipAddresses != other.sipAddresses) { - for (i in 0..sipAddresses.size) { + for (i in 0 until sipAddresses.size) { val compare = sipAddresses[i].asStringUriOnly().compareTo(other.sipAddresses[i].asStringUriOnly()) if (compare != 0) return compare } @@ -89,7 +96,10 @@ open class Contact : Comparable { phoneNumbers.clear() for (number in friend.phoneNumbers) { - if (!phoneNumbers.contains(number)) phoneNumbers.add(number) + if (!rawPhoneNumbers.contains(number)) { + phoneNumbers.add(PhoneNumber(number, "")) + rawPhoneNumbers.add(number) + } } sipAddresses.clear() @@ -151,7 +161,7 @@ open class Contact : Comparable { val presenceModel = friend?.getPresenceModelForUriOrTel(address.asStringUriOnly()) if (presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open) return true } - for (number in phoneNumbers) { + for (number in rawPhoneNumbers) { val presenceModel = friend?.getPresenceModelForUriOrTel(number) if (presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open) return true } diff --git a/app/src/main/java/org/linphone/contact/ContactsManager.kt b/app/src/main/java/org/linphone/contact/ContactsManager.kt index 8e8e4111c..73d1a9585 100644 --- a/app/src/main/java/org/linphone/contact/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contact/ContactsManager.kt @@ -345,7 +345,7 @@ class ContactsManager(private val context: Context) { } private fun storePresenceInNativeContact(contact: NativeContact) { - for (phoneNumber in contact.phoneNumbers) { + for (phoneNumber in contact.rawPhoneNumbers) { val sipAddress = contact.getContactForPhoneNumberOrAddress(phoneNumber) if (sipAddress != null) { Log.d("[Contacts Manager] Found presence information to store in native contact $contact under Linphone sync account") diff --git a/app/src/main/java/org/linphone/contact/NativeContact.kt b/app/src/main/java/org/linphone/contact/NativeContact.kt index d26a5ba82..3844bcd6d 100644 --- a/app/src/main/java/org/linphone/contact/NativeContact.kt +++ b/app/src/main/java/org/linphone/contact/NativeContact.kt @@ -108,9 +108,24 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null) return } - Log.d("[Native Contact] Found phone number $data1 ($data4)") + val labelColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL) + val label: String? = cursor.getString(labelColumnIndex) + val typeColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE) + val type: Int = cursor.getInt(typeColumnIndex) + val typeLabel = ContactsContract.CommonDataKinds.Phone.getTypeLabel( + coreContext.context.resources, + type, + label + ).toString() + val number = data4 ?: data1 - if (number != null && number.isNotEmpty() && !phoneNumbers.contains(number)) phoneNumbers.add(number) + if (number != null && number.isNotEmpty()) { + Log.d("[Native Contact] Found phone number $data1 ($data4), type label is $typeLabel") + if (!rawPhoneNumbers.contains(number)) { + phoneNumbers.add(PhoneNumber(number, typeLabel)) + rawPhoneNumbers.add(number) + } + } } linphoneMime, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE -> { if (data1 == null) { @@ -119,7 +134,7 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null) } Log.d("[Native Contact] Found SIP address $data1") - if (phoneNumbers.contains(data1)) { + if (rawPhoneNumbers.contains(data1)) { Log.d("[Native Contact] SIP address value already exists in phone numbers list, skipping") return } @@ -131,6 +146,7 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null) } val stringAddress = address.asStringUriOnly() + Log.d("[Native Contact] Found SIP address $stringAddress") if (!rawSipAddresses.contains(stringAddress)) { sipAddresses.add(address) rawSipAddresses.add(stringAddress) @@ -191,7 +207,7 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null) } for (address in sipAddresses) friend.addAddress(address) - for (number in phoneNumbers) friend.addPhoneNumber(number) + for (number in rawPhoneNumbers) friend.addPhoneNumber(number) friend.done() if (created) coreContext.core.defaultFriendList?.addFriend(friend) @@ -220,6 +236,7 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null) sipAddresses.clear() rawSipAddresses.clear() phoneNumbers.clear() + rawPhoneNumbers.clear() while (cursor.moveToNext()) { syncValuesFromAndroidCursor(cursor) diff --git a/app/src/main/res/layout/contact_detail_cell.xml b/app/src/main/res/layout/contact_detail_cell.xml index db9feb6b7..db702bce8 100644 --- a/app/src/main/res/layout/contact_detail_cell.xml +++ b/app/src/main/res/layout/contact_detail_cell.xml @@ -72,6 +72,15 @@ android:scrollHorizontally="true" android:singleLine="true" /> + +