From 6fb2f4f2162a2ffaf83c832fc35070cf103c3d92 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 25 Aug 2016 15:20:06 +0200 Subject: use N style stacked notifications --- .../messenger/services/NotificationService.java | 166 +++++++++++---------- .../messenger/services/XmppConnectionService.java | 7 +- 2 files changed, 91 insertions(+), 82 deletions(-) (limited to 'src/main/java/de') diff --git a/src/main/java/de/pixart/messenger/services/NotificationService.java b/src/main/java/de/pixart/messenger/services/NotificationService.java index f0ba9d51c..88b2ee1be 100644 --- a/src/main/java/de/pixart/messenger/services/NotificationService.java +++ b/src/main/java/de/pixart/messenger/services/NotificationService.java @@ -28,6 +28,7 @@ import java.util.Calendar; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -44,6 +45,7 @@ import de.pixart.messenger.utils.UIHelper; public class NotificationService { + private static final String CONVERSATIONS_GROUP = "de.pixart.messenger"; private final XmppConnectionService mXmppConnectionService; private final LinkedHashMap> notifications = new LinkedHashMap<>(); @@ -55,7 +57,6 @@ public class NotificationService { private Conversation mOpenConversation; private boolean mIsInForeground; private long mLastNotification; - private Resources resources; public NotificationService(final XmppConnectionService service) { this.mXmppConnectionService = service; @@ -187,10 +188,6 @@ public class NotificationService { .getSystemService(Context.NOTIFICATION_SERVICE); final SharedPreferences preferences = mXmppConnectionService.getPreferences(); - final String ringtone = preferences.getString("notification_ringtone", null); - final boolean vibrate = preferences.getBoolean("vibrate_on_notification", true); - final boolean led = preferences.getBoolean("led", true); - if (notifications.size() == 0) { notificationManager.cancel(NOTIFICATION_ID); } else { @@ -199,33 +196,45 @@ public class NotificationService { } final Builder mBuilder; if (notifications.size() == 1) { - mBuilder = buildSingleConversations(notify); + mBuilder = buildSingleConversations(notifications.values().iterator().next()); + modifyForSoundVibrationAndLight(mBuilder, notify, preferences); + notificationManager.notify(NOTIFICATION_ID, mBuilder.build()); } else { mBuilder = buildMultipleConversation(); - } - mBuilder.setNumber(mXmppConnectionService.unreadCount()); - if (notify && !isQuietHours()) { - if (vibrate) { - final int dat = 70; - final long[] pattern = {0, 3 * dat, dat, dat}; - mBuilder.setVibrate(pattern); - } - if (ringtone != null) { - mBuilder.setSound(Uri.parse(ringtone)); + modifyForSoundVibrationAndLight(mBuilder, notify, preferences); + notificationManager.notify(NOTIFICATION_ID, mBuilder.build()); + for(Map.Entry> entry : notifications.entrySet()) { + Builder singleBuilder = buildSingleConversations(entry.getValue()); + singleBuilder.setGroup(CONVERSATIONS_GROUP); + modifyForSoundVibrationAndLight(singleBuilder,notify,preferences); + notificationManager.notify(entry.getKey().hashCode() % 435301 ,singleBuilder.build()); } } - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mBuilder.setCategory(Notification.CATEGORY_MESSAGE); + } + } + + + private void modifyForSoundVibrationAndLight(Builder mBuilder, boolean notify, SharedPreferences preferences) { + final String ringtone = preferences.getString("notification_ringtone", null); + final boolean vibrate = preferences.getBoolean("vibrate_on_notification", true); + final boolean led = preferences.getBoolean("led", true); + if (notify && !isQuietHours()) { + if (vibrate) { + final int dat = 70; + final long[] pattern = {0, 3 * dat, dat, dat}; + mBuilder.setVibrate(pattern); } - setNotificationColor(mBuilder); - mBuilder.setDefaults(0); - mBuilder.setSmallIcon(R.drawable.ic_notification); - mBuilder.setDeleteIntent(createDeleteIntent()); - if (led) { - mBuilder.setLights(0xff0080FF, 2000, 3000); + if (ringtone != null) { + mBuilder.setSound(Uri.parse(ringtone)); } - final Notification notification = mBuilder.build(); - notificationManager.notify(NOTIFICATION_ID, notification); + } + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mBuilder.setCategory(Notification.CATEGORY_MESSAGE); + } + setNotificationColor(mBuilder); + mBuilder.setDefaults(0); + if (led) { + mBuilder.setLights(0xff0080FF, 2000, 3000); } } @@ -266,13 +275,15 @@ public class NotificationService { if (conversation != null) { mBuilder.setContentIntent(createContentIntent(conversation)); } + mBuilder.setGroupSummary(true); + mBuilder.setGroup(CONVERSATIONS_GROUP); + mBuilder.setDeleteIntent(createDeleteIntent(null)); + mBuilder.setSmallIcon(R.drawable.ic_notification); return mBuilder; } - private Builder buildSingleConversations(final boolean notify) { - final Builder mBuilder = new NotificationCompat.Builder( - mXmppConnectionService); - final ArrayList messages = notifications.values().iterator().next(); + private Builder buildSingleConversations(final ArrayList messages) { + final Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService); if (messages.size() >= 1) { final Conversation conversation = messages.get(0).getConversation(); mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService() @@ -284,11 +295,9 @@ public class NotificationService { } else { Message message; if ((message = getImage(messages)) != null) { - modifyForImage(mBuilder, message, messages, notify); - } else if (conversation.getMode() == Conversation.MODE_MULTI) { - modifyForConference(mBuilder, conversation, messages, notify); + modifyForImage(mBuilder, message, messages); } else { - modifyForTextOnly(mBuilder, messages, notify); + modifyForTextOnly(mBuilder, messages); } if ((message = getFirstDownloadableMessage(messages)) != null) { mBuilder.addAction( @@ -305,13 +314,16 @@ public class NotificationService { createShowLocationIntent(message)); } } + mBuilder.setWhen(conversation.getLatestMessage().getTimeSent()); + mBuilder.setSmallIcon(R.drawable.ic_notification); + mBuilder.setDeleteIntent(createDeleteIntent(conversation)); mBuilder.setContentIntent(createContentIntent(conversation)); } return mBuilder; } private void modifyForImage(final Builder builder, final Message message, - final ArrayList messages, final boolean notify) { + final ArrayList messages) { try { final Bitmap bitmap = mXmppConnectionService.getFileBackend() .getThumbnail(message, getPixel(200), false); @@ -334,36 +346,25 @@ public class NotificationService { } builder.setStyle(bigPictureStyle); } catch (final FileNotFoundException e) { - modifyForTextOnly(builder, messages, notify); + modifyForTextOnly(builder, messages); } } - private void modifyForTextOnly(final Builder builder, - final ArrayList messages, final boolean notify) { - builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); - builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first); - if (notify) { - builder.setTicker(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(messages.size() - 1)).first); - } - } - - private void modifyForConference(Builder builder, Conversation conversation, List messages, boolean notify) { - final Message first = messages.get(0); - final Message last = messages.get(messages.size() - 1); - final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); - style.setBigContentTitle(conversation.getName()); - - for(Message message : messages) { - if (message.hasMeCommand()) { - style.addLine(UIHelper.getMessagePreview(mXmppConnectionService,message).first); - } else { - style.addLine(Html.fromHtml("" + UIHelper.getMessageDisplayName(message) + ": " + UIHelper.getMessagePreview(mXmppConnectionService, message).first)); + private void modifyForTextOnly(final Builder builder, final ArrayList messages) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle(mXmppConnectionService.getString(R.string.me)); + Conversation conversation = messages.get(0).getConversation(); + if (conversation.getMode() == Conversation.MODE_MULTI) { + messagingStyle.setConversationTitle(conversation.getName()); } - } - builder.setContentText((first.hasMeCommand() ? "" :UIHelper.getMessageDisplayName(first)+ ": ") +UIHelper.getMessagePreview(mXmppConnectionService, first).first); - builder.setStyle(style); - if (notify) { - builder.setTicker((last.hasMeCommand() ? "" : UIHelper.getMessageDisplayName(last) + ": ") + UIHelper.getMessagePreview(mXmppConnectionService,last).first); + for (Message message : messages) { + String sender = message.getStatus() == Message.STATUS_RECEIVED ? UIHelper.getMessageDisplayName(message) : null; + messagingStyle.addMessage(message.getBody().trim(), message.getTimeSent(), sender); + } + builder.setStyle(messagingStyle); + } else { + builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); + builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first); } } @@ -424,18 +425,16 @@ public class NotificationService { private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) { final Intent viewConversationIntent = new Intent(mXmppConnectionService,ConversationActivity.class); viewConversationIntent.setAction(ConversationActivity.ACTION_VIEW_CONVERSATION); - if (conversationUuid != null) { - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, conversationUuid); - } + viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, conversationUuid); if (downloadMessageUuid != null) { viewConversationIntent.putExtra(ConversationActivity.EXTRA_DOWNLOAD_UUID, downloadMessageUuid); return PendingIntent.getActivity(mXmppConnectionService, - 57, + conversationUuid.hashCode() % 389782, viewConversationIntent, PendingIntent.FLAG_UPDATE_CURRENT); } else { return PendingIntent.getActivity(mXmppConnectionService, - 58, + conversationUuid.hashCode() % 936236, viewConversationIntent, PendingIntent.FLAG_UPDATE_CURRENT); } @@ -449,10 +448,13 @@ public class NotificationService { return createContentIntent(conversation.getUuid(), null); } - private PendingIntent createDeleteIntent() { - final Intent intent = new Intent(mXmppConnectionService, - XmppConnectionService.class); + private PendingIntent createDeleteIntent(Conversation conversation) { + final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); intent.setAction(XmppConnectionService.ACTION_CLEAR_NOTIFICATION); + if (conversation != null) { + intent.putExtra("uuid", conversation.getUuid()); + return PendingIntent.getService(mXmppConnectionService, conversation.getUuid().hashCode() % 47528, intent, 0); + } return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); } @@ -557,18 +559,20 @@ public class NotificationService { } mBuilder.setContentIntent(createOpenConversationsIntent()); mBuilder.setWhen(0); - mBuilder.setPriority(Config.SHOW_CONNECTED_ACCOUNTS ? NotificationCompat.PRIORITY_DEFAULT : NotificationCompat.PRIORITY_MIN); - final int cancelIcon; - cancelIcon = R.drawable.ic_cancel_white_24dp; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mBuilder.setCategory(Notification.CATEGORY_SERVICE); - } - if (accounts.size() > 0 && mAccount.getStatus() == Account.State.ONLINE) { - mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); - } else { - mBuilder.setSmallIcon(R.drawable.ic_unlink_white_24dp); - } - if (Config.SHOW_DISABLE_FOREGROUND && !Config.USE_ALWAYS_FOREGROUND) { + mBuilder.setPriority(Config.SHOW_CONNECTED_ACCOUNTS ? NotificationCompat.PRIORITY_DEFAULT : NotificationCompat.PRIORITY_MIN); + if (accounts.size() > 0 && mAccount.getStatus() == Account.State.ONLINE) { + mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); + } else { + mBuilder.setSmallIcon(R.drawable.ic_unlink_white_24dp); + } + if (Config.SHOW_DISABLE_FOREGROUND && !Config.USE_ALWAYS_FOREGROUND) { + final int cancelIcon; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mBuilder.setCategory(Notification.CATEGORY_SERVICE); + cancelIcon = R.drawable.ic_cancel_white_24dp; + } else { + cancelIcon = R.drawable.ic_action_cancel; + } mBuilder.addAction(cancelIcon, mXmppConnectionService.getString(R.string.disable_foreground_service), createDisableForeground()); diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index 33c0c1223..13ffae27e 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -543,7 +543,12 @@ public class XmppConnectionService extends Service { logoutAndSave(true); return START_NOT_STICKY; case ACTION_CLEAR_NOTIFICATION: - mNotificationService.clear(); + final Conversation c = findConversationByUuid(intent.getStringExtra("uuid")); + if (c != null) { + mNotificationService.clear(c); + } else { + mNotificationService.clear(); + } break; case ACTION_TRY_AGAIN: resetAllAttemptCounts(false); -- cgit v1.2.3