diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/services/NotificationService.java')
-rw-r--r-- | src/main/java/eu/siacs/conversations/services/NotificationService.java | 232 |
1 files changed, 164 insertions, 68 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 00765deb..7b2e16df 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.services; +import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.regex.Matcher; @@ -11,16 +12,22 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.Bitmap; import android.net.Uri; import android.os.PowerManager; +import android.os.SystemClock; import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationCompat.BigPictureStyle; +import android.support.v4.app.NotificationCompat.Builder; import android.support.v4.app.TaskStackBuilder; import android.text.Html; import android.util.DisplayMetrics; +import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationActivity; @@ -30,9 +37,10 @@ public class NotificationService { private LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<String, ArrayList<Message>>(); - public int NOTIFICATION_ID = 0x2342; + public static int NOTIFICATION_ID = 0x2342; private Conversation mOpenConversation; private boolean mIsInForeground; + private long mLastNotification; public NotificationService(XmppConnectionService service) { this.mXmppConnectionService = service; @@ -58,7 +66,8 @@ public class NotificationService { } Account account = message.getConversation().getAccount(); updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) - && !account.inGracePeriod()); + && !account.inGracePeriod() + && !this.inMiniGracePeriod(account)); } } @@ -89,74 +98,14 @@ public class NotificationService { if (notifications.size() == 0) { notificationManager.cancel(NOTIFICATION_ID); } else { - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( - mXmppConnectionService); - mBuilder.setSmallIcon(R.drawable.ic_notification); + if (notify) { + this.markLastNotification(); + } + Builder mBuilder; if (notifications.size() == 1) { - ArrayList<Message> messages = notifications.values().iterator() - .next(); - if (messages.size() >= 1) { - Conversation conversation = messages.get(0) - .getConversation(); - mBuilder.setLargeIcon(mXmppConnectionService - .getAvatarService().get(conversation, getPixel(64))); - mBuilder.setContentTitle(conversation.getName()); - StringBuilder text = new StringBuilder(); - for (int i = 0; i < messages.size(); ++i) { - text.append(messages.get(i).getReadableBody( - mXmppConnectionService)); - if (i != messages.size() - 1) { - text.append("\n"); - } - } - mBuilder.setStyle(new NotificationCompat.BigTextStyle() - .bigText(text.toString())); - mBuilder.setContentText(messages.get(0).getReadableBody( - mXmppConnectionService)); - if (notify) { - mBuilder.setTicker(messages.get(messages.size() - 1) - .getReadableBody(mXmppConnectionService)); - } - mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); - } else { - notificationManager.cancel(NOTIFICATION_ID); - return; - } + mBuilder = buildSingleConversations(notify); } else { - NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); - style.setBigContentTitle(notifications.size() - + " " - + mXmppConnectionService - .getString(R.string.unread_conversations)); - StringBuilder names = new StringBuilder(); - Conversation conversation = null; - for (ArrayList<Message> messages : notifications.values()) { - if (messages.size() > 0) { - conversation = messages.get(0).getConversation(); - String name = conversation.getName(); - style.addLine(Html.fromHtml("<b>" - + name - + "</b> " - + messages.get(0).getReadableBody( - mXmppConnectionService))); - names.append(name); - names.append(", "); - } - } - if (names.length() >= 2) { - names.delete(names.length() - 2, names.length()); - } - mBuilder.setContentTitle(notifications.size() - + " " - + mXmppConnectionService - .getString(R.string.unread_conversations)); - mBuilder.setContentText(names.toString()); - mBuilder.setStyle(style); - if (conversation != null) { - mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); - } + mBuilder = buildMultipleConversation(); } if (notify) { if (vibrate) { @@ -168,6 +117,7 @@ public class NotificationService { mBuilder.setSound(Uri.parse(ringtone)); } } + mBuilder.setSmallIcon(R.drawable.ic_notification); mBuilder.setDeleteIntent(createDeleteIntent()); mBuilder.setLights(0xffffffff, 2000, 4000); Notification notification = mBuilder.build(); @@ -175,6 +125,142 @@ public class NotificationService { } } + private Builder buildMultipleConversation() { + Builder mBuilder = new NotificationCompat.Builder( + mXmppConnectionService); + NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); + style.setBigContentTitle(notifications.size() + + " " + + mXmppConnectionService + .getString(R.string.unread_conversations)); + StringBuilder names = new StringBuilder(); + Conversation conversation = null; + for (ArrayList<Message> messages : notifications.values()) { + if (messages.size() > 0) { + conversation = messages.get(0).getConversation(); + String name = conversation.getName(); + style.addLine(Html.fromHtml("<b>" + name + "</b> " + + getReadableBody(messages.get(0)))); + names.append(name); + names.append(", "); + } + } + if (names.length() >= 2) { + names.delete(names.length() - 2, names.length()); + } + mBuilder.setContentTitle(notifications.size() + + " " + + mXmppConnectionService + .getString(R.string.unread_conversations)); + mBuilder.setContentText(names.toString()); + mBuilder.setStyle(style); + if (conversation != null) { + mBuilder.setContentIntent(createContentIntent(conversation + .getUuid())); + } + return mBuilder; + } + + private Builder buildSingleConversations(boolean notify) { + Builder mBuilder = new NotificationCompat.Builder( + mXmppConnectionService); + ArrayList<Message> messages = notifications.values().iterator().next(); + if (messages.size() >= 1) { + Conversation conversation = messages.get(0).getConversation(); + mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService() + .get(conversation, getPixel(64))); + mBuilder.setContentTitle(conversation.getName()); + Message message; + if ((message = getImage(messages)) != null) { + modifyForImage(mBuilder, message, messages, notify); + } else { + modifyForTextOnly(mBuilder, messages, notify); + } + mBuilder.setContentIntent(createContentIntent(conversation + .getUuid())); + } + return mBuilder; + + } + + private void modifyForImage(Builder builder, Message message, + ArrayList<Message> messages, boolean notify) { + try { + Bitmap bitmap = mXmppConnectionService.getFileBackend() + .getThumbnail(message, getPixel(288), false); + ArrayList<Message> tmp = new ArrayList<Message>(); + for (Message msg : messages) { + if (msg.getType() == Message.TYPE_TEXT + && msg.getDownloadable() == null) { + tmp.add(msg); + } + } + BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(); + bigPictureStyle.bigPicture(bitmap); + if (tmp.size() > 0) { + bigPictureStyle.setSummaryText(getMergedBodies(tmp)); + builder.setContentText(getReadableBody(tmp.get(0))); + } else { + builder.setContentText(mXmppConnectionService.getString(R.string.image_file)); + } + builder.setStyle(bigPictureStyle); + } catch (FileNotFoundException e) { + modifyForTextOnly(builder, messages, notify); + } + } + + private void modifyForTextOnly(Builder builder, + ArrayList<Message> messages, boolean notify) { + builder.setStyle(new NotificationCompat.BigTextStyle() + .bigText(getMergedBodies(messages))); + builder.setContentText(getReadableBody(messages.get(0))); + if (notify) { + builder.setTicker(getReadableBody(messages.get(messages.size() - 1))); + } + } + + private Message getImage(ArrayList<Message> messages) { + for (Message message : messages) { + if (message.getType() == Message.TYPE_IMAGE + && message.getDownloadable() == null + && message.getEncryption() != Message.ENCRYPTION_PGP) { + return message; + } + } + return null; + } + + private String getMergedBodies(ArrayList<Message> messages) { + StringBuilder text = new StringBuilder(); + for (int i = 0; i < messages.size(); ++i) { + text.append(getReadableBody(messages.get(i))); + if (i != messages.size() - 1) { + text.append("\n"); + } + } + return text.toString(); + } + + private String getReadableBody(Message message) { + if (message.getDownloadable() != null + && (message.getDownloadable().getStatus() == Downloadable.STATUS_OFFER || message + .getDownloadable().getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE)) { + return mXmppConnectionService.getText( + R.string.image_offered_for_download).toString(); + } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { + return mXmppConnectionService.getText( + R.string.encrypted_message_received).toString(); + } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { + return mXmppConnectionService.getText(R.string.decryption_failed) + .toString(); + } else if (message.getType() == Message.TYPE_IMAGE) { + return mXmppConnectionService.getText(R.string.image_file) + .toString(); + } else { + return message.getBody().trim(); + } + } + private PendingIntent createContentIntent(String conversationUuid) { TaskStackBuilder stackBuilder = TaskStackBuilder .create(mXmppConnectionService); @@ -234,4 +320,14 @@ public class NotificationService { .getDisplayMetrics(); return ((int) (dp * metrics.density)); } + + private void markLastNotification() { + this.mLastNotification = SystemClock.elapsedRealtime(); + } + + private boolean inMiniGracePeriod(Account account) { + int miniGrace = account.getStatus() == Account.STATUS_ONLINE ? Config.MINI_GRACE_PERIOD + : Config.MINI_GRACE_PERIOD * 2; + return SystemClock.elapsedRealtime() < (this.mLastNotification + miniGrace); + } } |