Use Android 12 CallStyle notification for incoming calls
This commit is contained in:
parent
b48b9e42ed
commit
58e2fc98aa
5 changed files with 116 additions and 35 deletions
|
@ -34,11 +34,13 @@ 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.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
import org.linphone.R
|
||||
import org.linphone.contact.Contact
|
||||
import org.linphone.core.Call
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.notifications.Notifiable
|
||||
import org.linphone.notifications.NotificationsManager
|
||||
import org.linphone.telecom.NativeCallWrapper
|
||||
import org.linphone.utils.ImageUtils
|
||||
|
@ -134,12 +136,14 @@ class Api26Compatibility {
|
|||
return WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
|
||||
}
|
||||
|
||||
fun createIncomingCallNotificationBuilder(
|
||||
fun createIncomingCallNotification(
|
||||
context: Context,
|
||||
call: Call,
|
||||
notifiable: Notifiable,
|
||||
pendingIntent: PendingIntent,
|
||||
notificationsManager: NotificationsManager
|
||||
): NotificationCompat.Builder {
|
||||
val contact: Contact? = LinphoneApplication.coreContext.contactsManager.findContactByAddress(call.remoteAddress)
|
||||
): Notification {
|
||||
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)
|
||||
|
@ -154,7 +158,7 @@ class Api26Compatibility {
|
|||
notificationLayoutHeadsUp.setImageViewBitmap(R.id.caller_picture, roundPicture)
|
||||
}
|
||||
|
||||
return NotificationCompat.Builder(context, context.getString(R.string.notification_channel_incoming_call_id))
|
||||
val builder = 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)
|
||||
|
@ -168,7 +172,16 @@ class Api26Compatibility {
|
|||
.setShowWhen(true)
|
||||
.setOngoing(true)
|
||||
.setColor(ContextCompat.getColor(context, R.color.primary_color))
|
||||
.setFullScreenIntent(pendingIntent, true)
|
||||
.addAction(notificationsManager.getCallDeclineAction(notifiable))
|
||||
.addAction(notificationsManager.getCallAnswerAction(notifiable))
|
||||
.setCustomHeadsUpContentView(notificationLayoutHeadsUp)
|
||||
|
||||
if (!corePreferences.preventInterfaceFromShowingUp) {
|
||||
builder.setContentIntent(pendingIntent)
|
||||
}
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
|
|
|
@ -20,7 +20,20 @@
|
|||
package org.linphone.compatibility
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.app.Notification
|
||||
import android.app.PendingIntent
|
||||
import android.app.Person
|
||||
import android.content.Context
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
import org.linphone.R
|
||||
import org.linphone.contact.Contact
|
||||
import org.linphone.core.Call
|
||||
import org.linphone.notifications.Notifiable
|
||||
import org.linphone.notifications.NotificationsManager
|
||||
import org.linphone.utils.ImageUtils
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
||||
@TargetApi(31)
|
||||
class Api31Compatibility {
|
||||
|
@ -28,5 +41,47 @@ class Api31Compatibility {
|
|||
fun getUpdateCurrentPendingIntentFlag(): Int {
|
||||
return PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
||||
}
|
||||
|
||||
fun createIncomingCallNotification(
|
||||
context: Context,
|
||||
call: Call,
|
||||
notifiable: Notifiable,
|
||||
pendingIntent: PendingIntent,
|
||||
notificationsManager: NotificationsManager
|
||||
): Notification {
|
||||
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 person = notificationsManager.getPerson(contact, displayName, roundPicture)
|
||||
val caller = Person.Builder()
|
||||
.setName(person.name)
|
||||
.setIcon(person.icon?.toIcon(context))
|
||||
.setUri(person.uri)
|
||||
.setKey(person.key)
|
||||
.setImportant(person.isImportant)
|
||||
.build()
|
||||
val declineIntent = notificationsManager.getCallDeclinePendingIntent(notifiable)
|
||||
val answerIntent = notificationsManager.getCallAnswerPendingIntent(notifiable)
|
||||
val builder = Notification.Builder(context, context.getString(R.string.notification_channel_incoming_call_id))
|
||||
.setStyle(Notification.CallStyle.forIncomingCall(caller, declineIntent, answerIntent))
|
||||
.setSmallIcon(R.drawable.topbar_call_notification)
|
||||
.setCategory(Notification.CATEGORY_CALL)
|
||||
.setVisibility(Notification.VISIBILITY_PUBLIC)
|
||||
.setPriority(Notification.PRIORITY_HIGH)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setAutoCancel(false)
|
||||
.setShowWhen(true)
|
||||
.setOngoing(true)
|
||||
.setColor(ContextCompat.getColor(context, R.color.primary_color))
|
||||
.setFullScreenIntent(pendingIntent, true)
|
||||
|
||||
if (!corePreferences.preventInterfaceFromShowingUp) {
|
||||
builder.setContentIntent(pendingIntent)
|
||||
}
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package org.linphone.compatibility
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Notification
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
|
@ -30,7 +32,6 @@ 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.*
|
||||
|
@ -38,6 +39,7 @@ import org.linphone.core.Call
|
|||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.Content
|
||||
import org.linphone.mediastream.Version
|
||||
import org.linphone.notifications.Notifiable
|
||||
import org.linphone.notifications.NotificationsManager
|
||||
import org.linphone.telecom.NativeCallWrapper
|
||||
|
||||
|
@ -170,15 +172,19 @@ class Compatibility {
|
|||
return WindowManager.LayoutParams.TYPE_PHONE
|
||||
}
|
||||
|
||||
fun createIncomingCallNotificationBuilder(
|
||||
fun createIncomingCallNotification(
|
||||
context: Context,
|
||||
call: Call,
|
||||
notifiable: Notifiable,
|
||||
pendingIntent: PendingIntent,
|
||||
notificationsManager: NotificationsManager
|
||||
): NotificationCompat.Builder {
|
||||
if (Build.MANUFACTURER.lowercase(Locale.getDefault()) == "xiaomi") {
|
||||
return XiaomiCompatibility.createIncomingCallNotificationBuilder(context, call, notificationsManager)
|
||||
): Notification {
|
||||
if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12)) {
|
||||
return Api31Compatibility.createIncomingCallNotification(context, call, notifiable, pendingIntent, notificationsManager)
|
||||
} else if (Build.MANUFACTURER.lowercase(Locale.getDefault()) == "xiaomi") {
|
||||
return XiaomiCompatibility.createIncomingCallNotification(context, call, notifiable, pendingIntent, notificationsManager)
|
||||
}
|
||||
return Api26Compatibility.createIncomingCallNotificationBuilder(context, call, notificationsManager)
|
||||
return Api26Compatibility.createIncomingCallNotification(context, call, notifiable, pendingIntent, notificationsManager)
|
||||
}
|
||||
|
||||
/* Call */
|
||||
|
|
|
@ -25,10 +25,12 @@ 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.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
import org.linphone.R
|
||||
import org.linphone.contact.Contact
|
||||
import org.linphone.core.Call
|
||||
import org.linphone.notifications.Notifiable
|
||||
import org.linphone.notifications.NotificationsManager
|
||||
import org.linphone.utils.ImageUtils
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
@ -36,18 +38,20 @@ import org.linphone.utils.LinphoneUtils
|
|||
@TargetApi(26)
|
||||
class XiaomiCompatibility {
|
||||
companion object {
|
||||
fun createIncomingCallNotificationBuilder(
|
||||
fun createIncomingCallNotification(
|
||||
context: Context,
|
||||
call: Call,
|
||||
notifiable: Notifiable,
|
||||
pendingIntent: PendingIntent,
|
||||
notificationsManager: NotificationsManager
|
||||
): NotificationCompat.Builder {
|
||||
val contact: Contact? = LinphoneApplication.coreContext.contactsManager.findContactByAddress(call.remoteAddress)
|
||||
): Notification {
|
||||
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 address = LinphoneUtils.getDisplayableAddress(call.remoteAddress)
|
||||
|
||||
return NotificationCompat.Builder(context, context.getString(R.string.notification_channel_incoming_call_id))
|
||||
val builder = 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))
|
||||
|
@ -62,6 +66,15 @@ class XiaomiCompatibility {
|
|||
.setShowWhen(true)
|
||||
.setOngoing(true)
|
||||
.setColor(ContextCompat.getColor(context, R.color.primary_color))
|
||||
.setFullScreenIntent(pendingIntent, true)
|
||||
.addAction(notificationsManager.getCallDeclineAction(notifiable))
|
||||
.addAction(notificationsManager.getCallAnswerAction(notifiable))
|
||||
|
||||
if (!corePreferences.preventInterfaceFromShowingUp) {
|
||||
builder.setContentIntent(pendingIntent)
|
||||
}
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ import org.linphone.utils.FileUtils
|
|||
import org.linphone.utils.ImageUtils
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
||||
private class Notifiable(val notificationId: Int) {
|
||||
class Notifiable(val notificationId: Int) {
|
||||
val messages: ArrayList<NotifiableMessage> = arrayListOf()
|
||||
|
||||
var isGroup: Boolean = false
|
||||
|
@ -66,7 +66,7 @@ private class Notifiable(val notificationId: Int) {
|
|||
var dismissNotificationUponReadChatRoom: Boolean = true
|
||||
}
|
||||
|
||||
private class NotifiableMessage(
|
||||
class NotifiableMessage(
|
||||
var message: String,
|
||||
val contact: Contact?,
|
||||
val sender: String,
|
||||
|
@ -433,17 +433,7 @@ class NotificationsManager(private val context: Context) {
|
|||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val builder = Compatibility.createIncomingCallNotificationBuilder(context, call, this)
|
||||
builder
|
||||
.setFullScreenIntent(pendingIntent, true)
|
||||
.addAction(getCallDeclineAction(notifiable))
|
||||
.addAction(getCallAnswerAction(notifiable))
|
||||
|
||||
if (!corePreferences.preventInterfaceFromShowingUp) {
|
||||
builder.setContentIntent(pendingIntent)
|
||||
}
|
||||
|
||||
val notification = builder.build()
|
||||
val notification = Compatibility.createIncomingCallNotification(context, call, notifiable, pendingIntent, this)
|
||||
Log.i("[Notifications Manager] Notifying incoming call notification [${notifiable.notificationId}]")
|
||||
notify(notifiable.notificationId, notification)
|
||||
|
||||
|
@ -851,43 +841,47 @@ class NotificationsManager(private val context: Context) {
|
|||
|
||||
/* Notifications actions */
|
||||
|
||||
private fun getCallAnswerAction(notifiable: Notifiable): NotificationCompat.Action {
|
||||
fun getCallAnswerPendingIntent(notifiable: Notifiable): PendingIntent {
|
||||
val answerIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||
answerIntent.action = INTENT_ANSWER_CALL_NOTIF_ACTION
|
||||
answerIntent.putExtra(INTENT_NOTIF_ID, notifiable.notificationId)
|
||||
answerIntent.putExtra(INTENT_REMOTE_ADDRESS, notifiable.remoteAddress)
|
||||
|
||||
val answerPendingIntent = PendingIntent.getBroadcast(
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
notifiable.notificationId,
|
||||
answerIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
}
|
||||
|
||||
fun getCallAnswerAction(notifiable: Notifiable): NotificationCompat.Action {
|
||||
return NotificationCompat.Action.Builder(
|
||||
R.drawable.call_audio_start,
|
||||
context.getString(R.string.incoming_call_notification_answer_action_label),
|
||||
answerPendingIntent
|
||||
getCallAnswerPendingIntent(notifiable)
|
||||
).build()
|
||||
}
|
||||
|
||||
private fun getCallDeclineAction(notifiable: Notifiable): NotificationCompat.Action {
|
||||
fun getCallDeclinePendingIntent(notifiable: Notifiable): PendingIntent {
|
||||
val hangupIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||
hangupIntent.action = INTENT_HANGUP_CALL_NOTIF_ACTION
|
||||
hangupIntent.putExtra(INTENT_NOTIF_ID, notifiable.notificationId)
|
||||
hangupIntent.putExtra(INTENT_REMOTE_ADDRESS, notifiable.remoteAddress)
|
||||
|
||||
val hangupPendingIntent = PendingIntent.getBroadcast(
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
notifiable.notificationId,
|
||||
hangupIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
}
|
||||
|
||||
fun getCallDeclineAction(notifiable: Notifiable): NotificationCompat.Action {
|
||||
return NotificationCompat.Action.Builder(
|
||||
R.drawable.call_hangup,
|
||||
context.getString(R.string.incoming_call_notification_hangup_action_label),
|
||||
hangupPendingIntent
|
||||
getCallDeclinePendingIntent(notifiable)
|
||||
).build()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue