Added custom heads up notification for incoming calls + fixed incoming call activity not showing up on Android < 24

This commit is contained in:
Sylvain Berfini 2019-09-12 16:31:55 +02:00
parent 74261a1830
commit fe880d7774
7 changed files with 240 additions and 88 deletions

View file

@ -155,9 +155,11 @@ public final class LinphoneService extends Service {
if (state == Call.State.IncomingReceived
|| state == State.IncomingEarlyMedia) {
// Now we rely on the fullscreen intent of the call incoming
// notification
// if (!mLinphoneManager.getCallGsmON()) onIncomingReceived();
// Starting SDK 24 (Android 7.0) we rely on the fullscreen intent of the
// call incoming notification
if (Version.sdkStrictlyBelow(Version.API24_NOUGAT_70)) {
if (!mLinphoneManager.getCallGsmON()) onIncomingReceived();
}
} else if (state == State.OutgoingInit) {
onOutgoingStarted();
} else if (state == State.Connected) {

View file

@ -36,6 +36,7 @@ import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.widget.RemoteViews;
import org.linphone.R;
import org.linphone.notifications.Notifiable;
import org.linphone.notifications.NotifiableMessage;
@ -94,36 +95,65 @@ class ApiTwentyFourPlus {
public static Notification createInCallNotification(
Context context,
int callId,
boolean showAnswerAction,
String msg,
int iconID,
Bitmap contactIcon,
String contactName,
PendingIntent intent) {
Notification.Builder builder =
new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.addAction(Compatibility.getCallDeclineAction(context, callId));
return new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.addAction(Compatibility.getCallDeclineAction(context, callId))
.build();
}
if (showAnswerAction) {
builder.setFullScreenIntent(intent, true);
builder.addAction(Compatibility.getCallAnswerAction(context, callId));
public static Notification createIncomingCallNotification(
Context context,
int callId,
Bitmap contactIcon,
String contactName,
String sipUri,
PendingIntent intent) {
RemoteViews notificationLayoutHeadsUp =
new RemoteViews(
context.getPackageName(), R.layout.call_incoming_notification_heads_up);
notificationLayoutHeadsUp.setTextViewText(R.id.caller, contactName);
notificationLayoutHeadsUp.setTextViewText(R.id.sip_uri, sipUri);
notificationLayoutHeadsUp.setTextViewText(
R.id.incoming_call_info, context.getString(R.string.incall_notif_incoming));
if (contactIcon != null) {
notificationLayoutHeadsUp.setImageViewBitmap(R.id.caller_picture, contactIcon);
}
return builder.build();
return new Notification.Builder(context)
.setStyle(new Notification.DecoratedCustomViewStyle())
.setSmallIcon(R.drawable.topbar_call_notification)
.setAutoCancel(false)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.addAction(Compatibility.getCallDeclineAction(context, callId))
.addAction(Compatibility.getCallAnswerAction(context, callId))
.setCustomHeadsUpContentView(notificationLayoutHeadsUp)
.setFullScreenIntent(intent, true)
.build();
}
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {

View file

@ -75,36 +75,56 @@ class ApiTwentyOnePlus {
public static Notification createInCallNotification(
Context context,
boolean isIncoming,
String msg,
int iconID,
Bitmap contactIcon,
String contactName,
PendingIntent intent) {
Notification.Builder builder =
new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setOngoing(true)
.setLights(
ContextCompat.getColor(context, R.color.notification_led_color),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setShowWhen(true);
return new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setOngoing(true)
.setLights(
ContextCompat.getColor(context, R.color.notification_led_color),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setShowWhen(true)
.build();
}
if (isIncoming) {
builder.setFullScreenIntent(intent, true);
}
public static Notification createIncomingCallNotification(
Context context,
Bitmap contactIcon,
String contactName,
String sipUri,
PendingIntent intent) {
return builder.build();
return new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(context.getString(R.string.incall_notif_incoming))
.setSmallIcon(R.drawable.topbar_call_notification)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setOngoing(true)
.setLights(
ContextCompat.getColor(context, R.color.notification_led_color),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setShowWhen(true)
.setFullScreenIntent(intent, true)
.build();
}
public static Notification createNotification(

View file

@ -35,6 +35,7 @@ import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Build;
import android.provider.Settings;
import android.widget.RemoteViews;
import org.linphone.R;
import org.linphone.core.tools.Log;
import org.linphone.notifications.Notifiable;
@ -143,41 +144,67 @@ class ApiTwentySixPlus {
public static Notification createInCallNotification(
Context context,
int callId,
boolean isIncoming,
String msg,
int iconID,
Bitmap contactIcon,
String contactName,
PendingIntent intent) {
Notification.Builder builder =
new Notification.Builder(
context,
isIncoming
? context.getString(R.string.notification_channel_id)
: context.getString(
R.string.notification_service_channel_id))
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(
isIncoming ? Notification.PRIORITY_HIGH : Notification.PRIORITY_LOW)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.addAction(Compatibility.getCallDeclineAction(context, callId));
return new Notification.Builder(
context, context.getString(R.string.notification_service_channel_id))
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_LOW)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.addAction(Compatibility.getCallDeclineAction(context, callId))
.build();
}
if (isIncoming) {
builder.setFullScreenIntent(intent, true);
builder.addAction(Compatibility.getCallAnswerAction(context, callId));
public static Notification createIncomingCallNotification(
Context context,
int callId,
Bitmap contactIcon,
String contactName,
String sipUri,
PendingIntent intent) {
RemoteViews notificationLayoutHeadsUp =
new RemoteViews(
context.getPackageName(), R.layout.call_incoming_notification_heads_up);
notificationLayoutHeadsUp.setTextViewText(R.id.caller, contactName);
notificationLayoutHeadsUp.setTextViewText(R.id.sip_uri, sipUri);
notificationLayoutHeadsUp.setTextViewText(
R.id.incoming_call_info, context.getString(R.string.incall_notif_incoming));
if (contactIcon != null) {
notificationLayoutHeadsUp.setImageViewBitmap(R.id.caller_picture, contactIcon);
}
return builder.build();
return new Notification.Builder(
context, context.getString(R.string.notification_channel_id))
.setStyle(new Notification.DecoratedCustomViewStyle())
.setSmallIcon(R.drawable.topbar_call_notification)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setAutoCancel(false)
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.setFullScreenIntent(intent, true)
.addAction(Compatibility.getCallDeclineAction(context, callId))
.addAction(Compatibility.getCallAnswerAction(context, callId))
.setCustomHeadsUpContentView(notificationLayoutHeadsUp)
.build();
}
public static Notification createNotification(

View file

@ -112,7 +112,6 @@ public class Compatibility {
public static Notification createInCallNotification(
Context context,
int callId,
boolean isIncoming,
String msg,
int iconID,
Bitmap contactIcon,
@ -120,13 +119,31 @@ public class Compatibility {
PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createInCallNotification(
context, callId, isIncoming, msg, iconID, contactIcon, contactName, intent);
context, callId, msg, iconID, contactIcon, contactName, intent);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.createInCallNotification(
context, callId, isIncoming, msg, iconID, contactIcon, contactName, intent);
context, callId, msg, iconID, contactIcon, contactName, intent);
}
return ApiTwentyOnePlus.createInCallNotification(
context, isIncoming, msg, iconID, contactIcon, contactName, intent);
context, msg, iconID, contactIcon, contactName, intent);
}
public static Notification createIncomingCallNotification(
Context context,
int callId,
Bitmap contactIcon,
String contactName,
String sipUri,
PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createIncomingCallNotification(
context, callId, contactIcon, contactName, sipUri, intent);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.createIncomingCallNotification(
context, callId, contactIcon, contactName, sipUri, intent);
}
return ApiTwentyOnePlus.createIncomingCallNotification(
context, contactIcon, contactName, sipUri, intent);
}
public static Notification createNotification(

View file

@ -614,21 +614,32 @@ public class NotificationsManager {
+ callNotifIntentClass);
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
Uri pictureUri = contact != null ? contact.getPhotoUri() : null;
Uri pictureUri = contact != null ? contact.getThumbnailUri() : null;
Bitmap bm = ImageUtils.getRoundBitmapFromUri(mContext, pictureUri);
String name = LinphoneUtils.getAddressDisplayName(address);
boolean isIncoming = callNotifIntentClass == CallIncomingActivity.class;
Notification notification =
Compatibility.createInCallNotification(
mContext,
notif.getNotificationId(),
isIncoming,
mContext.getString(notificationTextId),
iconId,
bm,
name,
pendingIntent);
Notification notification;
if (isIncoming) {
notification =
Compatibility.createIncomingCallNotification(
mContext,
notif.getNotificationId(),
bm,
name,
addressAsString,
pendingIntent);
} else {
notification =
Compatibility.createInCallNotification(
mContext,
notif.getNotificationId(),
mContext.getString(notificationTextId),
iconId,
bm,
name,
pendingIntent);
}
// Don't use incoming call notification as foreground service notif !
if (!isServiceNotificationDisplayed() && !isIncoming) {

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical">
<TextView
android:id="@+id/caller"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/TextAppearance.Material.Notification.Title"/>
<TextView
android:id="@+id/sip_uri"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/primary_color"
style="@android:style/TextAppearance.Material.Notification.Line2"/>
<TextView
android:id="@+id/incoming_call_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/TextAppearance.Material.Notification.Info"/>
</LinearLayout>
<ImageView
android:id="@+id/caller_picture"
android:layout_width="50dp"
android:layout_height="50dp"
android:adjustViewBounds="true"
android:src="@drawable/avatar"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginRight="20dp" />
</RelativeLayout>