mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Reworked & improved how we load contact pictures
This commit is contained in:
parent
a037fb5487
commit
e5617d53ee
3 changed files with 32 additions and 91 deletions
|
|
@ -25,7 +25,6 @@ import android.content.Context
|
|||
import android.content.pm.PackageManager
|
||||
import android.database.Cursor
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.provider.ContactsContract
|
||||
import androidx.annotation.UiThread
|
||||
|
|
@ -47,6 +46,7 @@ import org.linphone.ui.main.MainActivity
|
|||
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressClickListener
|
||||
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel
|
||||
import org.linphone.ui.main.model.isInSecureMode
|
||||
import org.linphone.utils.ImageUtils
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
import org.linphone.utils.PhoneNumberUtils
|
||||
|
||||
|
|
@ -304,12 +304,7 @@ class ContactsManager @UiThread constructor(context: Context) {
|
|||
val personBuilder = Person.Builder().setName(name)
|
||||
|
||||
val photo = account?.params?.pictureUri.orEmpty()
|
||||
val bm: Bitmap? = if (photo.isNotEmpty()) {
|
||||
BitmapFactory.decodeFile(photo)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val bm = ImageUtils.getBitmap(coreContext.context, photo)
|
||||
personBuilder.setIcon(
|
||||
if (bm == null) {
|
||||
coreContext.contactsManager.contactAvatar
|
||||
|
|
@ -329,16 +324,16 @@ class ContactsManager @UiThread constructor(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun Friend.getAvatarBitmap(): Bitmap? {
|
||||
return ImageUtils.getBitmap(coreContext.context, photo)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun Friend.getPerson(): Person {
|
||||
val personBuilder = Person.Builder().setName(name)
|
||||
|
||||
val bm: Bitmap? = if (!photo.isNullOrEmpty()) {
|
||||
BitmapFactory.decodeFile(photo)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val bm: Bitmap? = getAvatarBitmap()
|
||||
personBuilder.setIcon(
|
||||
if (bm == null) {
|
||||
coreContext.contactsManager.contactAvatar
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import android.content.Intent
|
|||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import androidx.annotation.AnyThread
|
||||
import androidx.annotation.MainThread
|
||||
|
|
@ -42,10 +41,10 @@ import androidx.core.app.Person
|
|||
import androidx.core.app.RemoteInput
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.LocusIdCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
import org.linphone.R
|
||||
import org.linphone.contacts.getAvatarBitmap
|
||||
import org.linphone.contacts.getPerson
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.Call
|
||||
|
|
@ -488,12 +487,6 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
|
||||
val contact =
|
||||
coreContext.contactsManager.findContactByAddress(address)
|
||||
val contactPicture = contact?.photo
|
||||
val roundPicture = if (!contactPicture.isNullOrEmpty()) {
|
||||
BitmapFactory.decodeFile(contactPicture)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val displayName = contact?.name ?: LinphoneUtils.getDisplayName(address)
|
||||
|
||||
val originalMessage = getTextDescribingMessage(message)
|
||||
|
|
@ -508,7 +501,6 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
contact,
|
||||
displayName,
|
||||
message.time,
|
||||
senderAvatar = roundPicture,
|
||||
isOutgoing = false,
|
||||
isReaction = true,
|
||||
reactionToMessageId = message.messageId,
|
||||
|
|
@ -590,12 +582,6 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
private fun getNotifiableForChatMessage(message: ChatMessage): NotifiableMessage {
|
||||
val contact =
|
||||
coreContext.contactsManager.findContactByAddress(message.fromAddress)
|
||||
val contactPicture = contact?.photo
|
||||
val roundPicture = if (!contactPicture.isNullOrEmpty()) {
|
||||
BitmapFactory.decodeFile(contactPicture)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val displayName = contact?.name ?: LinphoneUtils.getDisplayName(message.fromAddress)
|
||||
|
||||
val text = getTextDescribingMessage(message)
|
||||
|
|
@ -604,7 +590,6 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
contact,
|
||||
displayName,
|
||||
message.time * 1000, /* Linphone timestamps are in seconds */
|
||||
senderAvatar = roundPicture,
|
||||
isOutgoing = message.isOutgoing
|
||||
)
|
||||
|
||||
|
|
@ -648,15 +633,9 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
|
||||
val contact =
|
||||
coreContext.contactsManager.findContactByAddress(call.remoteAddress)
|
||||
val contactPicture = contact?.photo
|
||||
val roundPicture = if (!contactPicture.isNullOrEmpty()) {
|
||||
BitmapFactory.decodeFile(contactPicture)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val displayName = contact?.name ?: LinphoneUtils.getDisplayName(call.remoteAddress)
|
||||
|
||||
val person = getPerson(contact, displayName, roundPicture)
|
||||
val person = getPerson(contact, displayName)
|
||||
val caller = Person.Builder()
|
||||
.setName(person.name)
|
||||
.setIcon(person.icon)
|
||||
|
|
@ -743,12 +722,12 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
var lastPerson: Person? = null
|
||||
for (message in notifiable.messages) {
|
||||
val friend = message.friend
|
||||
val person = getPerson(friend, message.sender, message.senderAvatar)
|
||||
val person = getPerson(friend, message.sender)
|
||||
|
||||
if (!message.isOutgoing) {
|
||||
// We don't want to see our own avatar
|
||||
lastPerson = person
|
||||
lastPersonAvatar = message.senderAvatar
|
||||
lastPersonAvatar = friend?.getAvatarBitmap()
|
||||
|
||||
if (allPersons.find { it.key == person.key } == null) {
|
||||
allPersons.add(person)
|
||||
|
|
@ -797,6 +776,8 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
notificationBuilder.addPerson(person)
|
||||
}
|
||||
|
||||
// TODO FIXME: shortcuts!
|
||||
|
||||
return notificationBuilder.build()
|
||||
}
|
||||
|
||||
|
|
@ -957,17 +938,11 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun getPerson(friend: Friend?, displayName: String, picture: Bitmap?): Person {
|
||||
private fun getPerson(friend: Friend?, displayName: String): Person {
|
||||
return friend?.getPerson()
|
||||
?: Person.Builder()
|
||||
.setName(displayName)
|
||||
.setIcon(
|
||||
if (picture != null) {
|
||||
IconCompat.createWithAdaptiveBitmap(picture)
|
||||
} else {
|
||||
coreContext.contactsManager.contactAvatar
|
||||
}
|
||||
)
|
||||
.setIcon(coreContext.contactsManager.contactAvatar)
|
||||
.setKey(displayName)
|
||||
.build()
|
||||
}
|
||||
|
|
@ -1013,7 +988,6 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
channel.enableLights(true)
|
||||
channel.enableVibration(true)
|
||||
channel.setShowBadge(true)
|
||||
channel.setAllowBubbles(false)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
|
|
@ -1071,7 +1045,6 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
val friend: Friend?,
|
||||
val sender: String,
|
||||
val time: Long,
|
||||
val senderAvatar: Bitmap? = null,
|
||||
var filePath: Uri? = null,
|
||||
var fileMime: String? = null,
|
||||
val isOutgoing: Boolean = false,
|
||||
|
|
|
|||
|
|
@ -21,14 +21,8 @@ package org.linphone.utils
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.ImageDecoder
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffXfermode
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import androidx.annotation.AnyThread
|
||||
import androidx.annotation.WorkerThread
|
||||
import java.io.FileNotFoundException
|
||||
import org.linphone.core.tools.Log
|
||||
|
|
@ -38,58 +32,37 @@ class ImageUtils {
|
|||
private const val TAG = "[Image Utils]"
|
||||
|
||||
@WorkerThread
|
||||
fun getRoundBitmapFromUri(
|
||||
fun getBitmap(
|
||||
context: Context,
|
||||
fromPictureUri: Uri?
|
||||
path: String?
|
||||
): Bitmap? {
|
||||
var bm: Bitmap? = null
|
||||
if (fromPictureUri != null) {
|
||||
bm = try {
|
||||
Log.d("$TAG Trying to create Bitmap from path [$path]")
|
||||
if (path != null) {
|
||||
try {
|
||||
val fromPictureUri = Uri.parse(path)
|
||||
if (fromPictureUri == null) {
|
||||
Log.e("$TAG Failed to parse path [$path] as URI")
|
||||
return null
|
||||
}
|
||||
|
||||
// We make a copy to ensure Bitmap will be Software and not Hardware, required for shortcuts
|
||||
ImageDecoder.decodeBitmap(
|
||||
return ImageDecoder.decodeBitmap(
|
||||
ImageDecoder.createSource(context.contentResolver, fromPictureUri)
|
||||
).copy(
|
||||
Bitmap.Config.ARGB_8888,
|
||||
true
|
||||
)
|
||||
} catch (fnfe: FileNotFoundException) {
|
||||
Log.e("$TAG File [$path] not found: $fnfe")
|
||||
return null
|
||||
} catch (e: Exception) {
|
||||
Log.e("$TAG Failed to get bitmap from URI [$fromPictureUri]: $e")
|
||||
Log.e("$TAG Failed to get bitmap using path [$path]: $e")
|
||||
return null
|
||||
}
|
||||
}
|
||||
if (bm != null) {
|
||||
val roundBm = getRoundBitmap(bm)
|
||||
if (roundBm != null) {
|
||||
bm.recycle()
|
||||
return roundBm
|
||||
}
|
||||
}
|
||||
return bm
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
private fun getRoundBitmap(bitmap: Bitmap): Bitmap? {
|
||||
val output =
|
||||
Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(output)
|
||||
val color = -0xbdbdbe
|
||||
val paint = Paint()
|
||||
val rect =
|
||||
Rect(0, 0, bitmap.width, bitmap.height)
|
||||
paint.isAntiAlias = true
|
||||
canvas.drawARGB(0, 0, 0, 0)
|
||||
paint.color = color
|
||||
canvas.drawCircle(
|
||||
bitmap.width / 2.toFloat(),
|
||||
bitmap.height / 2.toFloat(),
|
||||
bitmap.width / 2.toFloat(),
|
||||
paint
|
||||
)
|
||||
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
|
||||
canvas.drawBitmap(bitmap, rect, rect, paint)
|
||||
return output
|
||||
Log.e("$TAG Can't get bitmap from null URI")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue