Fixed custom incoming call notification layout not working on some Xiaomi devices...
This commit is contained in:
parent
9572da70d4
commit
b48b9e42ed
4 changed files with 133 additions and 37 deletions
|
@ -22,10 +22,7 @@ package org.linphone.compatibility
|
|||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.annotation.TargetApi
|
||||
import android.app.Activity
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PictureInPictureParams
|
||||
import android.app.*
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.media.AudioAttributes
|
||||
|
@ -33,10 +30,19 @@ import android.os.VibrationEffect
|
|||
import android.os.Vibrator
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.linphone.LinphoneApplication
|
||||
import org.linphone.R
|
||||
import org.linphone.contact.Contact
|
||||
import org.linphone.core.Call
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.notifications.NotificationsManager
|
||||
import org.linphone.telecom.NativeCallWrapper
|
||||
import org.linphone.utils.ImageUtils
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
||||
@TargetApi(26)
|
||||
class Api26Compatibility {
|
||||
|
@ -128,6 +134,43 @@ class Api26Compatibility {
|
|||
return WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
|
||||
}
|
||||
|
||||
fun createIncomingCallNotificationBuilder(
|
||||
context: Context,
|
||||
call: Call,
|
||||
notificationsManager: NotificationsManager
|
||||
): NotificationCompat.Builder {
|
||||
val contact: Contact? = LinphoneApplication.coreContext.contactsManager.findContactByAddress(call.remoteAddress)
|
||||
val pictureUri = contact?.getContactThumbnailPictureUri()
|
||||
val roundPicture = ImageUtils.getRoundBitmapFromUri(context, pictureUri)
|
||||
val displayName = contact?.fullName ?: LinphoneUtils.getDisplayName(call.remoteAddress)
|
||||
val address = LinphoneUtils.getDisplayableAddress(call.remoteAddress)
|
||||
|
||||
val notificationLayoutHeadsUp = RemoteViews(context.packageName, R.layout.call_incoming_notification_heads_up)
|
||||
notificationLayoutHeadsUp.setTextViewText(R.id.caller, displayName)
|
||||
notificationLayoutHeadsUp.setTextViewText(R.id.sip_uri, address)
|
||||
notificationLayoutHeadsUp.setTextViewText(R.id.incoming_call_info, context.getString(R.string.incoming_call_notification_title))
|
||||
|
||||
if (roundPicture != null) {
|
||||
notificationLayoutHeadsUp.setImageViewBitmap(R.id.caller_picture, roundPicture)
|
||||
}
|
||||
|
||||
return NotificationCompat.Builder(context, context.getString(R.string.notification_channel_incoming_call_id))
|
||||
.setStyle(NotificationCompat.DecoratedCustomViewStyle())
|
||||
.addPerson(notificationsManager.getPerson(contact, displayName, roundPicture))
|
||||
.setSmallIcon(R.drawable.topbar_call_notification)
|
||||
.setContentTitle(displayName)
|
||||
.setContentText(context.getString(R.string.incoming_call_notification_title))
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setAutoCancel(false)
|
||||
.setShowWhen(true)
|
||||
.setOngoing(true)
|
||||
.setColor(ContextCompat.getColor(context, R.color.primary_color))
|
||||
.setCustomHeadsUpContentView(notificationLayoutHeadsUp)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
fun eventVibration(vibrator: Vibrator) {
|
||||
val effect = VibrationEffect.createWaveform(longArrayOf(0L, 100L, 100L), intArrayOf(0, VibrationEffect.DEFAULT_AMPLITUDE, 0), -1)
|
||||
|
|
|
@ -25,15 +25,20 @@ import android.content.Intent
|
|||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Vibrator
|
||||
import android.telephony.TelephonyManager
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import java.util.*
|
||||
import org.linphone.core.Call
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.Content
|
||||
import org.linphone.mediastream.Version
|
||||
import org.linphone.notifications.NotificationsManager
|
||||
import org.linphone.telecom.NativeCallWrapper
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
|
@ -165,6 +170,17 @@ class Compatibility {
|
|||
return WindowManager.LayoutParams.TYPE_PHONE
|
||||
}
|
||||
|
||||
fun createIncomingCallNotificationBuilder(
|
||||
context: Context,
|
||||
call: Call,
|
||||
notificationsManager: NotificationsManager
|
||||
): NotificationCompat.Builder {
|
||||
if (Build.MANUFACTURER.lowercase(Locale.getDefault()) == "xiaomi") {
|
||||
return XiaomiCompatibility.createIncomingCallNotificationBuilder(context, call, notificationsManager)
|
||||
}
|
||||
return Api26Compatibility.createIncomingCallNotificationBuilder(context, call, notificationsManager)
|
||||
}
|
||||
|
||||
/* Call */
|
||||
|
||||
fun canDrawOverlay(context: Context): Boolean {
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-android
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.linphone.compatibility
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.app.*
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.linphone.LinphoneApplication
|
||||
import org.linphone.R
|
||||
import org.linphone.contact.Contact
|
||||
import org.linphone.core.Call
|
||||
import org.linphone.notifications.NotificationsManager
|
||||
import org.linphone.utils.ImageUtils
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
||||
@TargetApi(26)
|
||||
class XiaomiCompatibility {
|
||||
companion object {
|
||||
fun createIncomingCallNotificationBuilder(
|
||||
context: Context,
|
||||
call: Call,
|
||||
notificationsManager: NotificationsManager
|
||||
): NotificationCompat.Builder {
|
||||
val contact: Contact? = LinphoneApplication.coreContext.contactsManager.findContactByAddress(call.remoteAddress)
|
||||
val pictureUri = contact?.getContactThumbnailPictureUri()
|
||||
val roundPicture = ImageUtils.getRoundBitmapFromUri(context, pictureUri)
|
||||
val displayName = contact?.fullName ?: LinphoneUtils.getDisplayName(call.remoteAddress)
|
||||
val address = LinphoneUtils.getDisplayableAddress(call.remoteAddress)
|
||||
|
||||
return NotificationCompat.Builder(context, context.getString(R.string.notification_channel_incoming_call_id))
|
||||
.addPerson(notificationsManager.getPerson(contact, displayName, roundPicture))
|
||||
.setSmallIcon(R.drawable.topbar_call_notification)
|
||||
.setLargeIcon(roundPicture ?: BitmapFactory.decodeResource(context.resources, R.drawable.avatar))
|
||||
.setContentTitle(displayName)
|
||||
.setContentText(address)
|
||||
.setSubText(context.getString(R.string.incoming_call_notification_title))
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setAutoCancel(false)
|
||||
.setShowWhen(true)
|
||||
.setOngoing(true)
|
||||
.setColor(ContextCompat.getColor(context, R.color.primary_color))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,7 +28,6 @@ import android.graphics.Bitmap
|
|||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.app.Person
|
||||
|
@ -397,7 +396,7 @@ class NotificationsManager(private val context: Context) {
|
|||
return notifiable
|
||||
}
|
||||
|
||||
private fun getPerson(contact: Contact?, displayName: String, picture: Bitmap?): Person {
|
||||
fun getPerson(contact: Contact?, displayName: String, picture: Bitmap?): Person {
|
||||
return if (contact != null) {
|
||||
contact.getPerson()
|
||||
} else {
|
||||
|
@ -419,19 +418,12 @@ class NotificationsManager(private val context: Context) {
|
|||
return
|
||||
}
|
||||
|
||||
val address = LinphoneUtils.getDisplayableAddress(call.remoteAddress)
|
||||
val notifiable = getNotifiableForCall(call)
|
||||
|
||||
if (notifiable.notificationId == currentForegroundServiceNotificationId) {
|
||||
Log.w("[Notifications Manager] Incoming call notification already displayed by foreground service [${notifiable.notificationId}], skipping")
|
||||
return
|
||||
}
|
||||
|
||||
val contact: Contact? = coreContext.contactsManager.findContactByAddress(call.remoteAddress)
|
||||
val pictureUri = contact?.getContactThumbnailPictureUri()
|
||||
val roundPicture = ImageUtils.getRoundBitmapFromUri(context, pictureUri)
|
||||
val displayName = contact?.fullName ?: LinphoneUtils.getDisplayName(call.remoteAddress)
|
||||
|
||||
val incomingCallNotificationIntent = Intent(context, IncomingCallActivity::class.java)
|
||||
incomingCallNotificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
|
@ -441,33 +433,11 @@ class NotificationsManager(private val context: Context) {
|
|||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val notificationLayoutHeadsUp = RemoteViews(context.packageName, R.layout.call_incoming_notification_heads_up)
|
||||
notificationLayoutHeadsUp.setTextViewText(R.id.caller, displayName)
|
||||
notificationLayoutHeadsUp.setTextViewText(R.id.sip_uri, address)
|
||||
notificationLayoutHeadsUp.setTextViewText(R.id.incoming_call_info, context.getString(R.string.incoming_call_notification_title))
|
||||
|
||||
if (roundPicture != null) {
|
||||
notificationLayoutHeadsUp.setImageViewBitmap(R.id.caller_picture, roundPicture)
|
||||
}
|
||||
|
||||
val builder = NotificationCompat.Builder(context, context.getString(R.string.notification_channel_incoming_call_id))
|
||||
.setStyle(NotificationCompat.DecoratedCustomViewStyle())
|
||||
.addPerson(getPerson(contact, displayName, roundPicture))
|
||||
.setSmallIcon(R.drawable.topbar_call_notification)
|
||||
.setContentTitle(displayName)
|
||||
.setContentText(context.getString(R.string.incoming_call_notification_title))
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setAutoCancel(false)
|
||||
.setShowWhen(true)
|
||||
.setOngoing(true)
|
||||
.setColor(ContextCompat.getColor(context, R.color.primary_color))
|
||||
val builder = Compatibility.createIncomingCallNotificationBuilder(context, call, this)
|
||||
builder
|
||||
.setFullScreenIntent(pendingIntent, true)
|
||||
.addAction(getCallDeclineAction(notifiable))
|
||||
.addAction(getCallAnswerAction(notifiable))
|
||||
.setCustomHeadsUpContentView(notificationLayoutHeadsUp)
|
||||
|
||||
if (!corePreferences.preventInterfaceFromShowingUp) {
|
||||
builder.setContentIntent(pendingIntent)
|
||||
|
|
Loading…
Reference in a new issue