add basic notification

This commit is contained in:
adbenitez 2025-09-09 13:22:20 +02:00
parent 0157510c5d
commit 4fc115b93d
3 changed files with 129 additions and 25 deletions

View file

@ -13,6 +13,7 @@ import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.media.AudioAttributes; import android.media.AudioAttributes;
import android.media.RingtoneManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
@ -202,6 +203,7 @@ public class NotificationCenter {
public static final String CH_MSG_VERSION = "5"; public static final String CH_MSG_VERSION = "5";
public static final String CH_PERMANENT = "dc_foreground_notification_ch"; public static final String CH_PERMANENT = "dc_foreground_notification_ch";
public static final String CH_GENERIC = "ch_generic"; public static final String CH_GENERIC = "ch_generic";
public static final String CH_CALLS_PREFIX = "call_chan";
private boolean notificationChannelsSupported() { private boolean notificationChannelsSupported() {
return Build.VERSION.SDK_INT >= 26; return Build.VERSION.SDK_INT >= 26;
@ -333,10 +335,93 @@ public class NotificationCenter {
return channelId; return channelId;
} }
private String getCallNotificationChannel(NotificationManagerCompat notificationManager, ChatData chatData, String name) {
String channelId = CH_CALLS_PREFIX + "-" + chatData.accountId + "-"+ chatData.chatId;
if (notificationChannelsSupported()) {
try {
name = "(calls) " + name;
// check if there is already a channel with the given name
List<NotificationChannel> channels = notificationManager.getNotificationChannels();
boolean channelExists = false;
for (int i = 0; i < channels.size(); i++) {
String currChannelId = channels.get(i).getId();
if (currChannelId.startsWith(CH_CALLS_PREFIX)) {
// this is one of the calls channels handled here ...
if (currChannelId.equals(channelId)) {
// ... this is the actually required channel, fine :)
// update the name to reflect localize changes and chat renames
channelExists = true;
channels.get(i).setName(name);
}
}
}
// create a the channel
if(!channelExists) {
NotificationChannel channel = new NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("Informs about incoming calls.");
channel.setShowBadge(true);
Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
channel.setSound(ringtone,
new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.build());
notificationManager.createNotificationChannel(channel);
}
} catch(Exception e) {
Log.e(TAG, "Error in getCallNotificationChannel()", e);
}
}
return channelId;
}
// add notifications & co. // add notifications & co.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
public void addCallNotification(int accId, int chatId, int callId) {
Util.runOnAnyBackgroundThread(() -> {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
DcContext dcContext = context.dcAccounts.getAccount(accId);
DcChat dcChat = dcContext.getChat(chatId);
String name = dcChat.getName();
ChatData chatData = new ChatData(accId, chatId);
String notificationChannel = getCallNotificationChannel(notificationManager, chatData, name);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, notificationChannel)
.setSmallIcon(R.drawable.icon_notification)
.setColor(context.getResources().getColor(R.color.delta_primary))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setOngoing(true)
.setOnlyAlertOnce(false)
.setTicker(name)
.setContentTitle(name)
.setContentText("Incoming Call")
;
// .setDeleteIntenta(getMarkAsReadIntent(chatData, msgId, false))
// .setContentIntent(getOpenChatIntent(chatData));
Bitmap bitmap = getAvatar(dcChat);
if (bitmap != null) {
builder.setLargeIcon(bitmap);
}
Notification notif = builder.build();
notif.flags = notif.flags | Notification.FLAG_INSISTENT;
// add notification, we use one notification per chat,
// esp. older android are not that great at grouping
try {
notificationManager.notify(String.valueOf(accId), ID_MSG_OFFSET + chatId, notif);
} catch (Exception e) {
Log.e(TAG, "cannot add notification", e);
}
});
}
public void notifyMessage(int accountId, int chatId, int msgId) { public void notifyMessage(int accountId, int chatId, int msgId) {
Util.runOnAnyBackgroundThread(() -> { Util.runOnAnyBackgroundThread(() -> {
DcContext dcContext = context.dcAccounts.getAccount(accountId); DcContext dcContext = context.dcAccounts.getAccount(accountId);
@ -495,31 +580,11 @@ public class NotificationCenter {
} }
// set avatar // set avatar
Recipient recipient = new Recipient(context, dcChat);
if (privacy.isDisplayContact()) { if (privacy.isDisplayContact()) {
try { Bitmap bitmap = getAvatar(dcChat);
Drawable drawable; if (bitmap != null) {
ContactPhoto contactPhoto = recipient.getContactPhoto(context); builder.setLargeIcon(bitmap);
if (contactPhoto != null) { }
drawable = GlideApp.with(context.getApplicationContext())
.load(contactPhoto)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.circleCrop()
.submit(context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_height))
.get();
} else {
drawable = recipient.getFallbackContactPhoto().asDrawable(context, recipient.getFallbackAvatarColor());
}
if (drawable != null) {
int wh = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size);
Bitmap bitmap = BitmapUtil.createFromDrawable(drawable, wh, wh);
if (bitmap != null) {
builder.setLargeIcon(bitmap);
}
}
} catch (Exception e) { Log.w(TAG, e); }
} }
// add buttons that allow some actions without opening Delta Chat. // add buttons that allow some actions without opening Delta Chat.
@ -619,6 +684,32 @@ public class NotificationCenter {
} }
} }
public Bitmap getAvatar(DcChat dcChat) {
Recipient recipient = new Recipient(context, dcChat);
try {
Drawable drawable;
ContactPhoto contactPhoto = recipient.getContactPhoto(context);
if (contactPhoto != null) {
drawable = GlideApp.with(context.getApplicationContext())
.load(contactPhoto)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.circleCrop()
.submit(context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_height))
.get();
} else {
drawable = recipient.getFallbackContactPhoto().asDrawable(context, recipient.getFallbackAvatarColor());
}
if (drawable != null) {
int wh = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size);
return BitmapUtil.createFromDrawable(drawable, wh, wh);
}
} catch (Exception e) { Log.w(TAG, e); }
return null;
}
public void removeNotifications(int accountId, int chatId) { public void removeNotifications(int accountId, int chatId) {
boolean removeSummary; boolean removeSummary;
synchronized (inboxes) { synchronized (inboxes) {

View file

@ -46,6 +46,17 @@ public class CallIntegrationService extends ConnectionService {
}; };
} }
@Override
public Connection onCreateIncomingConnection(final PhoneAccountHandle phoneAccountHandle, final ConnectionRequest request) {
Log.d(TAG, "onCreateIncomingConnection()");
return new Connection() {
@Override
public void onAnswer() {
super.onAnswer();
}
};
}
private static PhoneAccountHandle getHandle(final Context context, int accountId) { private static PhoneAccountHandle getHandle(final Context context, int accountId) {
final ComponentName componentName = new ComponentName(context, CallIntegrationService.class); final ComponentName componentName = new ComponentName(context, CallIntegrationService.class);
return new PhoneAccountHandle(componentName, accountId+""); return new PhoneAccountHandle(componentName, accountId+"");

View file

@ -35,10 +35,12 @@ public class VideochatUtil {
int accId = dcContext.getAccountId(); int accId = dcContext.getAccountId();
int chatId = dcMsg.getChatId(); int chatId = dcMsg.getChatId();
String hash = "#offer=" + payload; String hash = "#offer=" + payload;
DcHelper.getNotificationCenter(activity).addCallNotification(accId, chatId, callId);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
CallIntegrationService.addNewIncomingCall(activity, accId, chatId, callId, payload); CallIntegrationService.addNewIncomingCall(activity, accId, chatId, callId, payload);
} }
openCall(activity, dcMsg.getChatId(), callId, hash); //openCall(activity, chatId, callId, hash);
} }
private static void openCall(Activity activity, int chatId, int callId, String hash) { private static void openCall(Activity activity, int chatId, int callId, String hash) {