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 | 213 |
1 files changed, 144 insertions, 69 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index a30cf2f1..2ea0904f 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 android.annotation.SuppressLint; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -8,6 +9,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Build; import android.os.PowerManager; import android.os.SystemClock; import android.support.v4.app.NotificationCompat; @@ -18,9 +20,13 @@ import android.text.Html; import android.util.DisplayMetrics; import android.util.Log; +import org.json.JSONArray; +import org.json.JSONObject; + import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Calendar; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.regex.Matcher; @@ -30,16 +36,15 @@ 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.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.ManageAccountActivity; import eu.siacs.conversations.ui.TimePreference; +import eu.siacs.conversations.utils.UIHelper; public class NotificationService { - private XmppConnectionService mXmppConnectionService; + private final XmppConnectionService mXmppConnectionService; private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>(); @@ -51,7 +56,7 @@ public class NotificationService { private boolean mIsInForeground; private long mLastNotification; - public NotificationService(XmppConnectionService service) { + public NotificationService(final XmppConnectionService service) { this.mXmppConnectionService = service; } @@ -65,6 +70,24 @@ public class NotificationService { ); } + public void notifyPebble(final Message message) { + final Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION"); + + final Conversation conversation = message.getConversation(); + final JSONObject jsonData = new JSONObject(new HashMap<String, String>(2) {{ + put("title", conversation.getName()); + put("body", message.getBody()); + }}); + final String notificationData = new JSONArray().put(jsonData).toString(); + + i.putExtra("messageType", "PEBBLE_ALERT"); + i.putExtra("sender", "Conversations"); /* XXX: Shouldn't be hardcoded, e.g., AbstractGenerator.APP_NAME); */ + i.putExtra("notificationData", notificationData); + + mXmppConnectionService.sendBroadcast(i); + } + + public boolean notificationsEnabled() { return mXmppConnectionService.getPreferences().getBoolean("show_notification", true); } @@ -88,18 +111,33 @@ public class NotificationService { return mXmppConnectionService.getPreferences().getBoolean("always_notify_in_conference", false); } + @SuppressLint("NewApi") + @SuppressWarnings("deprecation") + private boolean isInteractive() { + final PowerManager pm = (PowerManager) mXmppConnectionService + .getSystemService(Context.POWER_SERVICE); + + final boolean isScreenOn; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + isScreenOn = pm.isScreenOn(); + } else { + isScreenOn = pm.isInteractive(); + } + + return isScreenOn; + } + public void push(final Message message) { if (!notify(message)) { return; } - final PowerManager pm = (PowerManager) mXmppConnectionService - .getSystemService(Context.POWER_SERVICE); - final boolean isScreenOn = pm.isScreenOn(); - if (this.mIsInForeground && isScreenOn - && this.mOpenConversation == message.getConversation()) { + final boolean isScreenOn = isInteractive(); + + if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) { return; - } + } + synchronized (notifications) { final String conversationUuid = message.getConversationUuid(); if (notifications.containsKey(conversationUuid)) { @@ -110,11 +148,14 @@ public class NotificationService { notifications.put(conversationUuid, mList); } final Account account = message.getConversation().getAccount(); - updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) - && !account.inGracePeriod() - && !this.inMiniGracePeriod(account)); + final boolean doNotify = (!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) + && !account.inGracePeriod() + && !this.inMiniGracePeriod(account); + updateNotification(doNotify); + if (doNotify) { + notifyPebble(message); + } } - } public void clear() { @@ -131,6 +172,10 @@ public class NotificationService { } } + private void setNotificationColor(final Builder mBuilder) { + mBuilder.setColor(mXmppConnectionService.getResources().getColor(R.color.primary)); + } + private void updateNotification(final boolean notify) { final NotificationManager notificationManager = (NotificationManager) mXmppConnectionService .getSystemService(Context.NOTIFICATION_SERVICE); @@ -161,6 +206,10 @@ public class NotificationService { mBuilder.setSound(Uri.parse(ringtone)); } } + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mBuilder.setCategory(Notification.CATEGORY_MESSAGE); + } + setNotificationColor(mBuilder); mBuilder.setSmallIcon(R.drawable.ic_notification); mBuilder.setDeleteIntent(createDeleteIntent()); mBuilder.setLights(0xffffffff, 2000, 4000); @@ -172,19 +221,19 @@ public class NotificationService { private Builder buildMultipleConversation() { final Builder mBuilder = new NotificationCompat.Builder( mXmppConnectionService); - NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); + final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); style.setBigContentTitle(notifications.size() + " " + mXmppConnectionService .getString(R.string.unread_conversations)); final StringBuilder names = new StringBuilder(); Conversation conversation = null; - for (ArrayList<Message> messages : notifications.values()) { + for (final ArrayList<Message> messages : notifications.values()) { if (messages.size() > 0) { conversation = messages.get(0).getConversation(); - String name = conversation.getName(); + final String name = conversation.getName(); style.addLine(Html.fromHtml("<b>" + name + "</b> " - + getReadableBody(messages.get(0)))); + + UIHelper.getMessagePreview(mXmppConnectionService,messages.get(0)).first)); names.append(name); names.append(", "); } @@ -199,8 +248,7 @@ public class NotificationService { mBuilder.setContentText(names.toString()); mBuilder.setStyle(style); if (conversation != null) { - mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); + mBuilder.setContentIntent(createContentIntent(conversation)); } return mBuilder; } @@ -214,14 +262,22 @@ public class NotificationService { mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService() .get(conversation, getPixel(64))); mBuilder.setContentTitle(conversation.getName()); - final Message message; + Message message; if ((message = getImage(messages)) != null) { modifyForImage(mBuilder, message, messages, notify); } else { modifyForTextOnly(mBuilder, messages, notify); } - mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); + if ((message = getFirstDownloadableMessage(messages)) != null) { + mBuilder.addAction( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? + R.drawable.ic_file_download_white_24dp : R.drawable.ic_action_download, + mXmppConnectionService.getResources().getString(R.string.download_x_file, + UIHelper.getFileDescriptionString(mXmppConnectionService, message)), + createDownloadIntent(message) + ); + } + mBuilder.setContentIntent(createContentIntent(conversation)); } return mBuilder; } @@ -242,9 +298,11 @@ public class NotificationService { bigPictureStyle.bigPicture(bitmap); if (tmp.size() > 0) { bigPictureStyle.setSummaryText(getMergedBodies(tmp)); - builder.setContentText(getReadableBody(tmp.get(0))); + builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService,tmp.get(0)).first); } else { - builder.setContentText(mXmppConnectionService.getString(R.string.image_file)); + builder.setContentText(mXmppConnectionService.getString( + R.string.received_x_file, + UIHelper.getFileDescriptionString(mXmppConnectionService,message))); } builder.setStyle(bigPictureStyle); } catch (final FileNotFoundException e) { @@ -254,15 +312,14 @@ public class NotificationService { private void modifyForTextOnly(final Builder builder, final ArrayList<Message> messages, final boolean notify) { - builder.setStyle(new NotificationCompat.BigTextStyle() - .bigText(getMergedBodies(messages))); - builder.setContentText(getReadableBody(messages.get(0))); + builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); + builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService,messages.get(0)).first); if (notify) { - builder.setTicker(getReadableBody(messages.get(messages.size() - 1))); + builder.setTicker(UIHelper.getMessagePreview(mXmppConnectionService,messages.get(messages.size() - 1)).first); } } - private Message getImage(final ArrayList<Message> messages) { + private Message getImage(final Iterable<Message> messages) { for (final Message message : messages) { if (message.getType() == Message.TYPE_IMAGE && message.getDownloadable() == null @@ -273,10 +330,20 @@ public class NotificationService { return null; } - private String getMergedBodies(final ArrayList<Message> messages) { + private Message getFirstDownloadableMessage(final Iterable<Message> messages) { + for (final Message message : messages) { + if ((message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) && + message.getDownloadable() != null) { + return message; + } + } + return null; + } + + private CharSequence getMergedBodies(final ArrayList<Message> messages) { final StringBuilder text = new StringBuilder(); for (int i = 0; i < messages.size(); ++i) { - text.append(getReadableBody(messages.get(i))); + text.append(UIHelper.getMessagePreview(mXmppConnectionService,messages.get(i)).first); if (i != messages.size() - 1) { text.append("\n"); } @@ -284,52 +351,39 @@ public class NotificationService { return text.toString(); } - private String getReadableBody(final Message message) { - if (message.getDownloadable() != null - && (message.getDownloadable().getStatus() == Downloadable.STATUS_OFFER || message - .getDownloadable().getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE)) { - if (message.getType() == Message.TYPE_FILE) { - return mXmppConnectionService.getString(R.string.file_offered_for_download); - } else { - 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_FILE) { - DownloadableFile file = mXmppConnectionService.getFileBackend().getFile(message); - return mXmppConnectionService.getString(R.string.file,file.getMimeType()); - } else if (message.getType() == Message.TYPE_IMAGE) { - return mXmppConnectionService.getText(R.string.image_file) - .toString(); - } else { - return message.getBody().trim(); - } - } - - private PendingIntent createContentIntent(final String conversationUuid) { + private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) { final TaskStackBuilder stackBuilder = TaskStackBuilder .create(mXmppConnectionService); stackBuilder.addParentStack(ConversationActivity.class); final Intent viewConversationIntent = new Intent(mXmppConnectionService, ConversationActivity.class); - viewConversationIntent.setAction(Intent.ACTION_VIEW); + if (downloadMessageUuid != null) { + viewConversationIntent.setAction(ConversationActivity.ACTION_DOWNLOAD); + } else { + viewConversationIntent.setAction(Intent.ACTION_VIEW); + } if (conversationUuid != null) { - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, - conversationUuid); + viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, conversationUuid); viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); } + if (downloadMessageUuid != null) { + viewConversationIntent.putExtra(ConversationActivity.MESSAGE, downloadMessageUuid); + } stackBuilder.addNextIntent(viewConversationIntent); return stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); } + private PendingIntent createDownloadIntent(final Message message) { + return createContentIntent(message.getConversationUuid(), message.getUuid()); + } + + private PendingIntent createContentIntent(final Conversation conversation) { + return createContentIntent(conversation.getUuid(), null); + } + private PendingIntent createDeleteIntent() { final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); @@ -393,15 +447,32 @@ public class NotificationService { public Notification createForegroundNotification() { final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService); - mBuilder.setSmallIcon(R.drawable.ic_stat_communication_import_export); + mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.conversations_foreground_service)); - mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_disable)); - mBuilder.setContentIntent(createDisableForeground()); + mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_open_conversations)); + mBuilder.setContentIntent(createOpenConversationsIntent()); mBuilder.setWhen(0); mBuilder.setPriority(NotificationCompat.PRIORITY_MIN); + final int cancelIcon; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mBuilder.setCategory(Notification.CATEGORY_SERVICE); + mBuilder.setSmallIcon(R.drawable.ic_import_export_white_48dp); + cancelIcon = R.drawable.ic_cancel_white_24dp; + } else { + mBuilder.setSmallIcon(R.drawable.ic_stat_communication_import_export); + cancelIcon = R.drawable.ic_action_cancel; + } + mBuilder.addAction(cancelIcon, + mXmppConnectionService.getString(R.string.disable_foreground_service), + createDisableForeground()); + setNotificationColor(mBuilder); return mBuilder.build(); } + private PendingIntent createOpenConversationsIntent() { + return PendingIntent.getActivity(mXmppConnectionService, 0, new Intent(mXmppConnectionService,ConversationActivity.class),0); + } + public void updateErrorNotification() { final NotificationManager mNotificationManager = (NotificationManager) mXmppConnectionService.getSystemService(Context.NOTIFICATION_SERVICE); final List<Account> errors = new ArrayList<>(); @@ -422,9 +493,13 @@ public class NotificationService { mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_fix)); } mBuilder.setOngoing(true); - mBuilder.setLights(0xffffffff, 2000, 4000); - mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); - TaskStackBuilder stackBuilder = TaskStackBuilder.create(mXmppConnectionService); + //mBuilder.setLights(0xffffffff, 2000, 4000); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mBuilder.setSmallIcon(R.drawable.ic_warning_white_36dp); + } else { + mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); + } + final TaskStackBuilder stackBuilder = TaskStackBuilder.create(mXmppConnectionService); stackBuilder.addParentStack(ConversationActivity.class); final Intent manageAccountsIntent = new Intent(mXmppConnectionService,ManageAccountActivity.class); |