Workaround phone number labels not stored in vCards because they don't match the RFC

This commit is contained in:
Sylvain Berfini 2022-05-03 17:39:49 +02:00
parent a31381632f
commit c1f542cbf5
3 changed files with 73 additions and 9 deletions

View file

@ -37,6 +37,7 @@ import org.linphone.core.*
import org.linphone.core.tools.Log
import org.linphone.utils.Event
import org.linphone.utils.LinphoneUtils
import org.linphone.utils.PhoneNumberUtils
class ContactViewModelFactory(private val friend: Friend) :
ViewModelProvider.NewInstanceFactory() {
@ -213,7 +214,8 @@ class ContactViewModel(friend: Friend, async: Boolean = false) : MessageNotifier
address?.displayName = displayName.value.orEmpty()
val isMe = if (address != null) coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false else false
val secureChatAllowed = !isMe && friend.getPresenceModelForUriOrTel(number)?.hasCapability(FriendCapability.LimeX3Dh) ?: false
val noa = ContactNumberOrAddressData(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, typeLabel = phoneNumber.label ?: "", listener = listener)
val label = PhoneNumberUtils.vcardParamStringToAddressBookLabel(coreContext.context.resources, phoneNumber.label ?: "")
val noa = ContactNumberOrAddressData(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, typeLabel = label, listener = listener)
list.add(noa)
}
numbersAndAddresses.postValue(list)

View file

@ -43,6 +43,7 @@ import org.linphone.core.Friend
import org.linphone.core.GlobalState
import org.linphone.core.tools.Log
import org.linphone.utils.LinphoneUtils
import org.linphone.utils.PhoneNumberUtils
class ContactLoader : LoaderManager.LoaderCallbacks<Cursor> {
companion object {
@ -139,12 +140,10 @@ class ContactLoader : LoaderManager.LoaderCallbacks<Cursor> {
when (mime) {
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE -> {
val typeLabel =
ContactsContract.CommonDataKinds.Phone.getTypeLabel(
loader.context.resources,
data2?.toInt() ?: 0,
data3
).toString()
val label = PhoneNumberUtils.addressBookLabelTypeToVcardParamString(
data2?.toInt() ?: ContactsContract.CommonDataKinds.BaseTypes.TYPE_CUSTOM,
data3
)
val number =
if (corePreferences.preferNormalizedPhoneNumbersFromAddressBook ||
@ -155,10 +154,11 @@ class ContactLoader : LoaderManager.LoaderCallbacks<Cursor> {
} else {
data1
}
if (number != null) {
var duplicate = false
for (pn in friend.phoneNumbersWithLabel) {
if (pn.label == typeLabel && LinphoneUtils.arePhoneNumberWeakEqual(
if (pn.label == label && LinphoneUtils.arePhoneNumberWeakEqual(
pn.phoneNumber,
number
)
@ -169,7 +169,7 @@ class ContactLoader : LoaderManager.LoaderCallbacks<Cursor> {
}
if (!duplicate) {
val phoneNumber = Factory.instance()
.createFriendPhoneNumber(number, typeLabel)
.createFriendPhoneNumber(number, label)
friend.addPhoneNumberWithLabel(phoneNumber)
}
}

View file

@ -21,6 +21,8 @@ package org.linphone.utils
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.provider.ContactsContract
import android.telephony.TelephonyManager
import org.linphone.core.DialPlan
import org.linphone.core.Factory
@ -59,6 +61,66 @@ class PhoneNumberUtils {
return null
}
fun addressBookLabelTypeToVcardParamString(type: Int, default: String?): String {
return when (type) {
ContactsContract.CommonDataKinds.Phone.TYPE_ASSISTANT -> "assistant"
ContactsContract.CommonDataKinds.Phone.TYPE_CALLBACK -> "callback"
ContactsContract.CommonDataKinds.Phone.TYPE_CAR -> "car"
ContactsContract.CommonDataKinds.Phone.TYPE_COMPANY_MAIN -> "work,main"
ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME -> "home,fax"
ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK -> "work,fax"
ContactsContract.CommonDataKinds.Phone.TYPE_HOME -> "home"
ContactsContract.CommonDataKinds.Phone.TYPE_ISDN -> "isdn"
ContactsContract.CommonDataKinds.Phone.TYPE_MAIN -> "main"
ContactsContract.CommonDataKinds.Phone.TYPE_MMS -> "text"
ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE -> "cell"
ContactsContract.CommonDataKinds.Phone.TYPE_OTHER -> "other"
ContactsContract.CommonDataKinds.Phone.TYPE_OTHER_FAX -> "fax"
ContactsContract.CommonDataKinds.Phone.TYPE_PAGER -> "pager"
ContactsContract.CommonDataKinds.Phone.TYPE_RADIO -> "radio"
ContactsContract.CommonDataKinds.Phone.TYPE_TELEX -> "telex"
ContactsContract.CommonDataKinds.Phone.TYPE_TTY_TDD -> "textphone"
ContactsContract.CommonDataKinds.Phone.TYPE_WORK -> "work"
ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE -> "work,cell"
ContactsContract.CommonDataKinds.Phone.TYPE_WORK_PAGER -> "work,pager"
ContactsContract.CommonDataKinds.BaseTypes.TYPE_CUSTOM -> default ?: "custom"
else -> default ?: type.toString()
}
}
fun vcardParamStringToAddressBookLabel(resources: Resources, label: String): String {
if (label.isEmpty()) return label
val type = labelToType(label)
return ContactsContract.CommonDataKinds.Phone.getTypeLabel(resources, type, label).toString()
}
private fun labelToType(label: String): Int {
return when (label) {
"assistant" -> ContactsContract.CommonDataKinds.Phone.TYPE_ASSISTANT
"callback" -> ContactsContract.CommonDataKinds.Phone.TYPE_CALLBACK
"car" -> ContactsContract.CommonDataKinds.Phone.TYPE_CAR
"work,main" -> ContactsContract.CommonDataKinds.Phone.TYPE_COMPANY_MAIN
"home,fax" -> ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME
"work,fax" -> ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK
"home" -> ContactsContract.CommonDataKinds.Phone.TYPE_HOME
"isdn" -> ContactsContract.CommonDataKinds.Phone.TYPE_ISDN
"main" -> ContactsContract.CommonDataKinds.Phone.TYPE_MAIN
"text" -> ContactsContract.CommonDataKinds.Phone.TYPE_MMS
"cell" -> ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE
"other" -> ContactsContract.CommonDataKinds.Phone.TYPE_OTHER
"fax" -> ContactsContract.CommonDataKinds.Phone.TYPE_OTHER_FAX
"pager" -> ContactsContract.CommonDataKinds.Phone.TYPE_PAGER
"radio" -> ContactsContract.CommonDataKinds.Phone.TYPE_RADIO
"telex" -> ContactsContract.CommonDataKinds.Phone.TYPE_TELEX
"textphone" -> ContactsContract.CommonDataKinds.Phone.TYPE_TTY_TDD
"work" -> ContactsContract.CommonDataKinds.Phone.TYPE_WORK
"work,cell" -> ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE
"work,pager" -> ContactsContract.CommonDataKinds.Phone.TYPE_WORK_PAGER
"custom" -> ContactsContract.CommonDataKinds.BaseTypes.TYPE_CUSTOM
else -> ContactsContract.CommonDataKinds.BaseTypes.TYPE_CUSTOM
}
}
private fun getDialPlanFromCountryCode(countryCode: String): DialPlan? {
for (c in Factory.instance().dialPlans) {
if (countryCode.equals(c.isoCountryCode, ignoreCase = true)) return c