aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/services/NotificationService.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/services/NotificationService.java')
-rw-r--r--src/main/java/eu/siacs/conversations/services/NotificationService.java213
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);