ContactItem improvements (#1324)

* ContactRepository: try to deduplicate phoneNumbers in a smart way

* AndroidManifest: use CALL_PHONE permission to allow for making phone calls

* Implement CallOnTap with contact results

- contact activities that require permissions we do not have are not
  listed
- add CallOnTap setting for phone number results on search behind
  contacts settings

* utilize PhoneNumberUtils

* navroute settings/search/contacts

* queryIntentActivities -> resolveActivity

* localization

* Code formatting

* Wrap contact search settings in preference category

---------

Co-authored-by: MM20 <15646950+MM2-0@users.noreply.github.com>
This commit is contained in:
Christoph
2025-03-29 17:18:30 +01:00
committed by GitHub
co-authored by MM20
parent 21894d8df2
commit bceae1aa58
14 changed files with 191 additions and 10 deletions
@@ -2,9 +2,12 @@ package de.mm20.launcher2.contacts
import android.content.ContentUris
import android.content.Context
import android.os.Build
import android.provider.ContactsContract
import android.telephony.PhoneNumberUtils
import androidx.core.database.getLongOrNull
import androidx.core.database.getStringOrNull
import de.mm20.launcher2.ktx.distinctByEquality
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.search.ContactSearchSettings
@@ -136,11 +139,10 @@ internal class ContactRepository(
}
else -> {
val mimeType = dataCursor.getStringOrNull(mimeTypeColumn) ?: continue
contactApps += ContactApp(
label = dataCursor.getStringOrNull(data3Column) ?: continue,
packageName = dataCursor.getStringOrNull(accountTypeColumn) ?: continue,
mimeType = mimeType,
mimeType = dataCursor.getStringOrNull(mimeTypeColumn) ?: continue,
uri = ContentUris.withAppendedId(
ContactsContract.Data.CONTENT_URI,
dataCursor.getLongOrNull(idColumn) ?: continue
@@ -164,12 +166,24 @@ internal class ContactRepository(
}
lookupKeyCursor.close()
val mainLocaleISO3 = context.resources.configuration.locales[0].isO3Country
return@withContext AndroidContact(
id = id,
firstName = firstName,
lastName = lastName,
displayName = displayName,
phoneNumbers = phoneNumbers.distinct(),
phoneNumbers = phoneNumbers.sortedByDescending {
it.number.count { !PhoneNumberUtils.isReallyDialable(it) }
}.distinctByEquality { a, b ->
if (Build.VERSION.SDK_INT < 31) {
PhoneNumberUtils.compare(context, a.number, b.number)
} else {
PhoneNumberUtils.areSamePhoneNumber(a.number, b.number, mainLocaleISO3)
}
}.map {
it.copy(number = PhoneNumberUtils.formatNumber(it.number, mainLocaleISO3))
},
emailAddresses = emailAddresses.distinct(),
postalAddresses = postalAddresses.distinct(),
contactApps = contactApps.distinct(),