From 688f797acffd1032edb0e0f8b24d4c2a9d8e17ae Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 22 Nov 2023 11:55:31 +0100 Subject: [PATCH] Use better quality of native contact picture if available, otherwise fallback to thumbnail --- .../org/linphone/contacts/ContactLoader.kt | 13 ++--- .../org/linphone/contacts/ContactsManager.kt | 49 ++++++++++++++++--- .../main/contacts/model/ContactAvatarModel.kt | 12 +---- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/ContactLoader.kt b/app/src/main/java/org/linphone/contacts/ContactLoader.kt index f75548bfd..870e503af 100644 --- a/app/src/main/java/org/linphone/contacts/ContactLoader.kt +++ b/app/src/main/java/org/linphone/contacts/ContactLoader.kt @@ -19,10 +19,8 @@ */ package org.linphone.contacts -import android.content.ContentUris import android.database.Cursor import android.database.StaleDataException -import android.net.Uri import android.os.Bundle import android.provider.ContactsContract import android.util.Patterns @@ -134,13 +132,10 @@ class ContactLoader : LoaderManager.LoaderCallbacks { ) friend.name = displayName - friend.photo = Uri.withAppendedPath( - ContentUris.withAppendedId( - ContactsContract.Contacts.CONTENT_URI, - id.toLong() - ), - ContactsContract.Contacts.Photo.CONTENT_DIRECTORY - ).toString() + val uri = friend.getNativeContactPictureUri() + if (uri != null) { + friend.photo = uri.toString() + } val starred = cursor.getInt( diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.kt b/app/src/main/java/org/linphone/contacts/ContactsManager.kt index 12a786b93..70947ae76 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.kt @@ -32,6 +32,7 @@ import androidx.core.app.ActivityCompat import androidx.core.app.Person import androidx.core.graphics.drawable.IconCompat import androidx.loader.app.LoaderManager +import java.io.IOException import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.core.Address import org.linphone.core.ConferenceInfo @@ -374,14 +375,10 @@ class ContactsManager @UiThread constructor() { } if (friend.photo.isNullOrEmpty()) { - val picture = Uri.withAppendedPath( - ContentUris.withAppendedId( - ContactsContract.Contacts.CONTENT_URI, - id.toLong() - ), - ContactsContract.Contacts.Photo.CONTENT_DIRECTORY - ).toString() - friend.photo = picture + val uri = friend.getNativeContactPictureUri() + if (uri != null) { + friend.photo = uri.toString() + } } if (friend.nativeUri.isNullOrEmpty()) { @@ -450,6 +447,42 @@ fun Friend.getAvatarBitmap(): Bitmap? { return ImageUtils.getBitmap(coreContext.context, photo) } +@WorkerThread +fun Friend.getNativeContactPictureUri(): Uri? { + val contactId = refKey + if (contactId != null) { + try { + val lookupUri = ContentUris.withAppendedId( + ContactsContract.Contacts.CONTENT_URI, + contactId.toLong() + ) + + val pictureUri = Uri.withAppendedPath( + lookupUri, + ContactsContract.Contacts.Photo.DISPLAY_PHOTO + ) + // Check that the URI points to a real file + val contentResolver = coreContext.context.contentResolver + try { + val fd = contentResolver.openAssetFileDescriptor(pictureUri, "r") + if (fd != null) { + fd.close() + return pictureUri + } + } catch (_: IOException) { } + + // Fallback to thumbnail + return Uri.withAppendedPath( + lookupUri, + ContactsContract.Contacts.Photo.CONTENT_DIRECTORY + ) + } catch (numberFormatException: NumberFormatException) { + // Expected for contacts created by Linphone + } + } + return null +} + @WorkerThread fun Friend.getPerson(): Person { val personBuilder = Person.Builder().setName(name) diff --git a/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt index c67a79079..382ede692 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt @@ -19,14 +19,13 @@ */ package org.linphone.ui.main.contacts.model -import android.content.ContentUris import android.net.Uri -import android.provider.ContactsContract import androidx.annotation.WorkerThread import androidx.lifecycle.MutableLiveData import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.contacts.AbstractAvatarModel +import org.linphone.contacts.getNativeContactPictureUri import org.linphone.core.ChatRoom.SecurityLevel import org.linphone.core.ConsolidatedPresence import org.linphone.core.Friend @@ -107,14 +106,7 @@ class ContactAvatarModel @WorkerThread constructor(val friend: Friend) : Abstrac val refKey = friend.refKey if (refKey != null) { try { - val lookupUri = ContentUris.withAppendedId( - ContactsContract.Contacts.CONTENT_URI, - refKey.toLong() - ) - return Uri.withAppendedPath( - lookupUri, - ContactsContract.Contacts.Photo.CONTENT_DIRECTORY - ) + return friend.getNativeContactPictureUri() } catch (numberFormatException: NumberFormatException) { // Expected for contacts created by Linphone }