From bff23c2e232e8f9a4e64553215130079b7fc5a4f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Sep 2014 15:21:56 +0200 Subject: new notification service. first draft --- .../conversations/services/EventReceiver.java | 3 +- .../conversations/services/ImageProvider.java | 2 +- .../services/NotificationService.java | 165 +++++++++++++++++++++ .../services/XmppConnectionService.java | 19 ++- 4 files changed, 177 insertions(+), 12 deletions(-) create mode 100644 src/eu/siacs/conversations/services/NotificationService.java (limited to 'src/eu/siacs/conversations/services') diff --git a/src/eu/siacs/conversations/services/EventReceiver.java b/src/eu/siacs/conversations/services/EventReceiver.java index e2445b2a9..dfbe9db76 100644 --- a/src/eu/siacs/conversations/services/EventReceiver.java +++ b/src/eu/siacs/conversations/services/EventReceiver.java @@ -15,7 +15,8 @@ public class EventReceiver extends BroadcastReceiver { } else { mIntentForService.setAction("other"); } - if (intent.getAction().equals("ui") || DatabaseBackend.getInstance(context).hasEnabledAccounts()) { + if (intent.getAction().equals("ui") + || DatabaseBackend.getInstance(context).hasEnabledAccounts()) { context.startService(mIntentForService); } } diff --git a/src/eu/siacs/conversations/services/ImageProvider.java b/src/eu/siacs/conversations/services/ImageProvider.java index af8ab4b2c..ac78a4540 100644 --- a/src/eu/siacs/conversations/services/ImageProvider.java +++ b/src/eu/siacs/conversations/services/ImageProvider.java @@ -31,7 +31,7 @@ public class ImageProvider extends ContentProvider { if (uuids == null) { throw new FileNotFoundException(); } - String[] uuidsSplited = uuids.split("/",2); + String[] uuidsSplited = uuids.split("/", 2); if (uuidsSplited.length != 3) { throw new FileNotFoundException(); } diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java new file mode 100644 index 000000000..b004d1c58 --- /dev/null +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -0,0 +1,165 @@ +package eu.siacs.conversations.services; + +import java.util.ArrayList; +import java.util.LinkedHashMap; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.TaskStackBuilder; +import android.text.Html; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.ui.ConversationActivity; + +public class NotificationService { + + private XmppConnectionService mXmppConnectionService; + private NotificationManager mNotificationManager; + + private LinkedHashMap> notifications = new LinkedHashMap>(); + + public int NOTIFICATION_ID = 0x2342; + + public NotificationService(XmppConnectionService service) { + this.mXmppConnectionService = service; + this.mNotificationManager = (NotificationManager) service + .getSystemService(Context.NOTIFICATION_SERVICE); + } + + public synchronized void push(Message message) { + String conversationUuid = message.getConversationUuid(); + if (notifications.containsKey(conversationUuid)) { + notifications.get(conversationUuid).add(message); + } else { + ArrayList mList = new ArrayList(); + mList.add(message); + notifications.put(conversationUuid, mList); + } + updateNotification(true); + } + + public void clear() { + notifications.clear(); + updateNotification(false); + } + + public void clear(Conversation conversation) { + notifications.remove(conversation.getUuid()); + updateNotification(false); + } + + private void updateNotification(boolean notify) { + SharedPreferences preferences = mXmppConnectionService.getPreferences(); + + String ringtone = preferences.getString("notification_ringtone", null); + boolean vibrate = preferences.getBoolean("vibrate_on_notification", + true); + + if (notifications.size() == 0) { + mNotificationManager.cancel(NOTIFICATION_ID); + } else { + NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( + mXmppConnectionService); + mBuilder.setSmallIcon(R.drawable.ic_notification); + if (notifications.size() == 1) { + ArrayList messages = notifications.values().iterator() + .next(); + if (messages.size() >= 1) { + Conversation conversation = messages.get(0) + .getConversation(); + mBuilder.setLargeIcon(conversation.getImage( + mXmppConnectionService, 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)); + mBuilder.setTicker(messages.get(messages.size() - 1) + .getReadableBody(mXmppConnectionService)); + mBuilder.setContentIntent(createContentIntent(conversation + .getUuid())); + } else { + mNotificationManager.cancel(NOTIFICATION_ID); + return; + } + } else { + NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); + style.setBigContentTitle(notifications.size() + + " " + + mXmppConnectionService + .getString(R.string.unread_conversations)); + StringBuilder names = new StringBuilder(); + for (ArrayList messages : notifications.values()) { + if (messages.size() > 0) { + String name = messages.get(0).getConversation() + .getName(); + style.addLine(Html.fromHtml("" + + name + + " " + + 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 (notify) { + if (vibrate) { + int dat = 70; + long[] pattern = { 0, 3 * dat, dat, dat }; + mBuilder.setVibrate(pattern); + } + mBuilder.setLights(0xffffffff, 2000, 4000); + if (ringtone != null) { + mBuilder.setSound(Uri.parse(ringtone)); + } + } + Notification notification = mBuilder.build(); + mNotificationManager.notify(NOTIFICATION_ID, notification); + } + } + + private PendingIntent createContentIntent(String conversationUuid) { + TaskStackBuilder stackBuilder = TaskStackBuilder + .create(mXmppConnectionService); + stackBuilder.addParentStack(ConversationActivity.class); + + Intent viewConversationIntent = new Intent(mXmppConnectionService, + ConversationActivity.class); + viewConversationIntent.setAction(Intent.ACTION_VIEW); + viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, + conversationUuid); + viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); + + stackBuilder.addNextIntent(viewConversationIntent); + + PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, + PendingIntent.FLAG_UPDATE_CURRENT); + return resultPendingIntent; + } +} diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index badf1df52..2ca11286f 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -93,6 +93,8 @@ public class XmppConnectionService extends Service { private MemorizingTrustManager mMemorizingTrustManager; + private NotificationService mNotificationService; + private MessageParser mMessageParser = new MessageParser(this); private PresenceParser mPresenceParser = new PresenceParser(this); private IqParser mIqParser = new IqParser(this); @@ -401,6 +403,7 @@ public class XmppConnectionService extends Service { this.mRandom = new SecureRandom(); this.mMemorizingTrustManager = new MemorizingTrustManager( getApplicationContext()); + this.mNotificationService = new NotificationService(this); this.databaseBackend = DatabaseBackend .getInstance(getApplicationContext()); this.fileBackend = new FileBackend(getApplicationContext()); @@ -1268,7 +1271,7 @@ public class XmppConnectionService extends Service { } } } - notifyUi(conversation, false); + updateConversationUi(); } public boolean renewSymmetricKey(Conversation conversation) { @@ -1577,15 +1580,6 @@ public class XmppConnectionService extends Service { return getPreferences().getBoolean("indicate_received", false); } - public void notifyUi(Conversation conversation, boolean notify) { - if (mOnConversationUpdate != null) { - mOnConversationUpdate.onConversationUpdate(); - } else { - UIHelper.updateNotification(getApplicationContext(), - getConversations(), conversation, notify); - } - } - public void updateConversationUi() { if (mOnConversationUpdate != null) { mOnConversationUpdate.onConversationUpdate(); @@ -1624,6 +1618,7 @@ public class XmppConnectionService extends Service { public void markRead(Conversation conversation) { conversation.markRead(); + mNotificationService.clear(conversation); String id = conversation.popLatestMarkableMessageId(); if (confirmMessages() && id != null) { Account account = conversation.getAccount(); @@ -1758,4 +1753,8 @@ public class XmppConnectionService extends Service { } return contacts; } + + public void pushNotification(Message message) { + this.mNotificationService.push(message); + } } -- cgit v1.2.3