From cfdf6017f3113fabf66cc2e4b218259217656f35 Mon Sep 17 00:00:00 2001 From: Carey Metcalfe Date: Sun, 25 Sep 2016 10:33:55 -0400 Subject: [PATCH] Add delete button to notifications This commit adds a delete buttons to new message notifications. The option is available in both single and multi-recipient notifications. It also changes the size of the button icons (for Android versions that support them) to a more standard size (24dp). --- AndroidManifest.xml | 8 +++ res/drawable-hdpi/ic_reply_white_24dp.png | Bin 0 -> 253 bytes res/drawable-mdpi/ic_reply_white_24dp.png | Bin 0 -> 186 bytes res/drawable-xhdpi/ic_reply_white_24dp.png | Bin 0 -> 306 bytes res/drawable-xxhdpi/ic_reply_white_24dp.png | Bin 0 -> 436 bytes res/drawable-xxxhdpi/ic_reply_white_24dp.png | Bin 0 -> 579 bytes res/values/strings.xml | 1 + .../notifications/DeleteMessageReceiver.java | 60 ++++++++++++++++++ .../notifications/MessageNotifier.java | 6 +- .../MultipleRecipientNotificationBuilder.java | 11 +++- .../notifications/NotificationState.java | 30 ++++++++- .../SingleRecipientNotificationBuilder.java | 20 ++++-- 12 files changed, 123 insertions(+), 13 deletions(-) create mode 100644 res/drawable-hdpi/ic_reply_white_24dp.png create mode 100644 res/drawable-mdpi/ic_reply_white_24dp.png create mode 100644 res/drawable-xhdpi/ic_reply_white_24dp.png create mode 100644 res/drawable-xxhdpi/ic_reply_white_24dp.png create mode 100644 res/drawable-xxxhdpi/ic_reply_white_24dp.png create mode 100644 src/org/smssecure/smssecure/notifications/DeleteMessageReceiver.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c57c8280..1ff5d5f8 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -331,6 +331,14 @@ + + + + + + diff --git a/res/drawable-hdpi/ic_reply_white_24dp.png b/res/drawable-hdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..0424c2bd6d6eaa5fcd3398f71b6e230ffc1caa7b GIT binary patch literal 253 zcmV zU~Fdwq%m1M4)uK)mzoQzo=rJT_^F%Fw{vzaQvoP=Gs*64?5z`yC5|0te ztglo_JlM#YTZ56ps3l~=R%Q4bDkjod4_PXH*Zy-CV1eOQf08V!00000NkvXXu0mjf DTghfP literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/ic_reply_white_24dp.png b/res/drawable-mdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..862114b82dafbbf8ca125d02ce7b723e901cf396 GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iMo$;V5R22v2@MvKutno2LKY{^$HJeV;W&5y zd7zR&QKbLh*2~7ZpEmt@I literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/ic_reply_white_24dp.png b/res/drawable-xhdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..885623e4d0bb82cbb39424905a689b9bc6af22c1 GIT binary patch literal 306 zcmV-20nPr2P) zzY0NN7>7?uDP=Jjlqgb0Zh^@tcYxg;Sd=SZ;sR_Ynd}Az17%Q>tQLPtJ%&RLN}ZhF zoX28{P=t|1-fkT|O<6C-?kx7!_{n(kXXy{Yr1VCN3 zwvc59OoWRUan?XgxH^(xM@_qC=3M_tt`m97U@*LJ14+y<45uXsEdT%j07*qoM6N<$ Ef@&9ni~s-t literal 0 HcmV?d00001 diff --git a/res/drawable-xxhdpi/ic_reply_white_24dp.png b/res/drawable-xxhdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..de0dad2047bd788a1a8fb8481e55a65bb3f80058 GIT binary patch literal 436 zcmV;l0ZaagP)KfTYNQj|)JTUktC6o+dq?9H~EB^BF0Ts(zKIf z5J4hr@>BtIUWa@1)q^5EM0qG9O*%bF6Jn|4P8~ZRHV|gNh&14Q97BLv9^V(QOAM?S z;xf1Rj-bRyk1kR<(zwXblU5P{#AL?8G_eO<2@TF^;k1r#T3s%un+$WFQVbIJv?AhJ emStJizv~TwJ`C-NfL~|;0000uF!KmdtKp{iiQvMxf>2_d&JP>CcpFGJ|%{xxY)28x!eL{dJk`Fa!>K&N3VGZ{N^_u4!fXoj~TUKm5B^COvaK6>~ z%nyx)*5T6*UK3%rJj%4a(q;C=>hs?|^@;_jS)7)=XXrKc6JL37pW>cJ=WA2LZytYr zJn|{`{`bq;S&y4c&oJ7}+1HqD(u#}siQU!g zF8R52*8bq;$a@AWj?2{_m$P1B{9@7Z;@Lf=b>GgsK6p8lVZr&h_3G*23=Nh0-Rnge zL^MjUnheIa3Vz$geeFfLe6(07KI|wm+6>nf*QD9)?aA05( dXkhrm;9=?%ov5mF5|}s`JYD@<);T3K0RT(&^4|ae literal 0 HcmV?d00001 diff --git a/res/values/strings.xml b/res/values/strings.xml index 340ff8e7..9992d611 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -426,6 +426,7 @@ Failed to deliver message. Error delivering message. Mark all as read + Delete all Mark read Media message Message received by %s. diff --git a/src/org/smssecure/smssecure/notifications/DeleteMessageReceiver.java b/src/org/smssecure/smssecure/notifications/DeleteMessageReceiver.java new file mode 100644 index 00000000..eecca4d9 --- /dev/null +++ b/src/org/smssecure/smssecure/notifications/DeleteMessageReceiver.java @@ -0,0 +1,60 @@ +package org.smssecure.smssecure.notifications; + +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; +import android.support.annotation.Nullable; +import android.support.v4.app.NotificationManagerCompat; +import android.util.Log; + +import org.smssecure.smssecure.crypto.MasterSecret; +import org.smssecure.smssecure.database.DatabaseFactory; + +public class DeleteMessageReceiver extends MasterSecretBroadcastReceiver { + + private static final String TAG = DeleteMessageReceiver.class.getSimpleName(); + public static final String DELETE_ACTION = "org.smssecure.smssecure.notifications.DELETE_MSGS"; + public static final String MSG_IDS_EXTRA = "msg_ids"; + public static final String MSG_IS_MMS_EXTRA = "msg_is_mms"; + public static final String THREAD_IDS_EXTRA = "thread_ids"; + public static final String NOTIFICATION_ID_EXTRA = "notification_id"; + + @Override + protected void onReceive(final Context context, Intent intent, + @Nullable final MasterSecret masterSecret) + { + if (!DELETE_ACTION.equals(intent.getAction())) + return; + + final long[] messageIds = intent.getLongArrayExtra(MSG_IDS_EXTRA); + final boolean[] messageIsMms = intent.getBooleanArrayExtra(MSG_IS_MMS_EXTRA); + final long[] threadIds = intent.getLongArrayExtra(THREAD_IDS_EXTRA); + + if (messageIds == null || messageIsMms == null || threadIds == null || + messageIds.length != messageIsMms.length){ + Log.e(TAG, "Bad extras received"); + return; + } + + NotificationManagerCompat.from(context).cancel(intent.getIntExtra(NOTIFICATION_ID_EXTRA, -1)); + + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + for (int i = 0; i < messageIds.length; i++) { + if (messageIsMms[i]) { + DatabaseFactory.getMmsDatabase(context).delete(messageIds[i]); + } else { + DatabaseFactory.getSmsDatabase(context).deleteMessage(messageIds[i]); + } + } + for (long threadId : threadIds) { + DatabaseFactory.getThreadDatabase(context).setRead(threadId); + } + + MessageNotifier.updateNotification(context, masterSecret); + return null; + } + }.execute(); + } +} diff --git a/src/org/smssecure/smssecure/notifications/MessageNotifier.java b/src/org/smssecure/smssecure/notifications/MessageNotifier.java index df873880..14a2cf9b 100644 --- a/src/org/smssecure/smssecure/notifications/MessageNotifier.java +++ b/src/org/smssecure/smssecure/notifications/MessageNotifier.java @@ -295,7 +295,8 @@ public class MessageNotifier { builder.addActions(masterSecret, notificationState.getMarkAsReadIntent(context, notificationId), notificationState.getQuickReplyIntent(context, notifications.get(0).getRecipients()), - notificationState.getRemoteReplyIntent(context, notifications.get(0).getRecipients())); + notificationState.getRemoteReplyIntent(context, notifications.get(0).getRecipients()), + notificationState.getDeleteMessageIntent(context, notificationId)); ListIterator iterator = notifications.listIterator(notifications.size()); @@ -333,7 +334,8 @@ public class MessageNotifier { long timestamp = notifications.get(0).getTimestamp(); if (timestamp != 0) builder.setWhen(timestamp); - builder.addActions(notificationState.getMarkAsReadIntent(context, SUMMARY_NOTIFICATION_ID)); + builder.addActions(notificationState.getMarkAsReadIntent(context, SUMMARY_NOTIFICATION_ID), + notificationState.getDeleteMessageIntent(context, SUMMARY_NOTIFICATION_ID)); ListIterator iterator = notifications.listIterator(0); diff --git a/src/org/smssecure/smssecure/notifications/MultipleRecipientNotificationBuilder.java b/src/org/smssecure/smssecure/notifications/MultipleRecipientNotificationBuilder.java index 721f796f..b7d75773 100644 --- a/src/org/smssecure/smssecure/notifications/MultipleRecipientNotificationBuilder.java +++ b/src/org/smssecure/smssecure/notifications/MultipleRecipientNotificationBuilder.java @@ -47,12 +47,17 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu } } - public void addActions(PendingIntent markAsReadIntent) { - NotificationCompat.Action markAllAsReadAction = new NotificationCompat.Action(R.drawable.check, + public void addActions(PendingIntent markAsReadIntent, PendingIntent deleteAllIntent) { + NotificationCompat.Action markAllAsReadAction = new NotificationCompat.Action(R.drawable.ic_check_white_24dp, context.getString(R.string.MessageNotifier_mark_all_as_read), markAsReadIntent); + NotificationCompat.Action deleteAllAction = new NotificationCompat.Action(R.drawable.ic_delete_white_24dp, + context.getString(R.string.MessageNotifier_delete_all), + deleteAllIntent); addAction(markAllAsReadAction); - extend(new NotificationCompat.WearableExtender().addAction(markAllAsReadAction)); + addAction(deleteAllAction); + extend(new NotificationCompat.WearableExtender().addAction(markAllAsReadAction) + .addAction(deleteAllAction)); } public void addMessageBody(@NonNull Recipient sender, @Nullable CharSequence body) { diff --git a/src/org/smssecure/smssecure/notifications/NotificationState.java b/src/org/smssecure/smssecure/notifications/NotificationState.java index e2c6b99a..d0b43bfc 100644 --- a/src/org/smssecure/smssecure/notifications/NotificationState.java +++ b/src/org/smssecure/smssecure/notifications/NotificationState.java @@ -102,7 +102,6 @@ public class NotificationState { int index = 0; for (long thread : threads) { - Log.w("NotificationState", "Added thread: " + thread); threadArray[index++] = thread; } @@ -115,6 +114,33 @@ public class NotificationState { return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } + public PendingIntent getDeleteMessageIntent(Context context, int notificationId){ + + long[] idArray = new long[notificationCount]; + boolean[] isMmsArray = new boolean[notificationCount]; + long[] threadArray = new long[threads.size()]; + int index = 0; + + for (NotificationItem notificationItem : notifications) { + isMmsArray[index] = notificationItem.isMms(); + idArray[index++] = notificationItem.getId(); + } + index = 0; + for (long thread : threads) { + threadArray[index++] = thread; + } + + Intent intent = new Intent(DeleteMessageReceiver.DELETE_ACTION); + intent.setClass(context, DeleteMessageReceiver.class); + intent.setData((Uri.parse("custom://"+System.currentTimeMillis()))); + intent.putExtra(DeleteMessageReceiver.MSG_IDS_EXTRA, idArray); + intent.putExtra(DeleteMessageReceiver.MSG_IS_MMS_EXTRA, isMmsArray); + intent.putExtra(DeleteMessageReceiver.THREAD_IDS_EXTRA, threadArray); + intent.putExtra(DeleteMessageReceiver.NOTIFICATION_ID_EXTRA, notificationId); + + return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + public PendingIntent getRemoteReplyIntent(Context context, Recipients recipients) { if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications!"); @@ -130,7 +156,7 @@ public class NotificationState { public PendingIntent getQuickReplyIntent(Context context, Recipients recipients) { if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications! " + threads.size()); - Intent intent = new Intent(context, ConversationPopupActivity.class); + Intent intent = new Intent(context, ConversationPopupActivity.class); intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds()); intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, (long)threads.toArray()[0]); intent.setData((Uri.parse("custom://"+System.currentTimeMillis()))); diff --git a/src/org/smssecure/smssecure/notifications/SingleRecipientNotificationBuilder.java b/src/org/smssecure/smssecure/notifications/SingleRecipientNotificationBuilder.java index 8f4d0e0e..4fda318f 100644 --- a/src/org/smssecure/smssecure/notifications/SingleRecipientNotificationBuilder.java +++ b/src/org/smssecure/smssecure/notifications/SingleRecipientNotificationBuilder.java @@ -102,19 +102,23 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil public void addActions(@Nullable MasterSecret masterSecret, @NonNull PendingIntent markReadIntent, @NonNull PendingIntent quickReplyIntent, - @NonNull PendingIntent wearableReplyIntent) + @NonNull PendingIntent wearableReplyIntent, + @NonNull PendingIntent deleteIntent) { - Action markAsReadAction = new Action(R.drawable.check, + Action markAsReadAction = new Action(R.drawable.ic_check_white_24dp, context.getString(R.string.MessageNotifier_mark_read), markReadIntent); + Action deleteAction = new Action(R.drawable.ic_delete_white_24dp, + context.getString(R.string.delete), + deleteIntent); if (masterSecret != null) { - Action replyAction = new Action(R.drawable.ic_reply_white_36dp, + Action replyAction = new Action(R.drawable.ic_reply_white_24dp, context.getString(R.string.MessageNotifier_reply), quickReplyIntent); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - replyAction = new Action.Builder(R.drawable.ic_reply_white_36dp, + replyAction = new Action.Builder(R.drawable.ic_reply_white_24dp, context.getString(R.string.MessageNotifier_reply), wearableReplyIntent) .addRemoteInput(new RemoteInput.Builder(MessageNotifier.EXTRA_REMOTE_REPLY) @@ -131,13 +135,17 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil addAction(markAsReadAction); addAction(replyAction); + addAction(deleteAction); extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction) - .addAction(wearableReplyAction)); + .addAction(wearableReplyAction) + .addAction(deleteAction)); } else { addAction(markAsReadAction); + addAction(deleteAction); - extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction)); + extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction) + .addAction(deleteAction)); } } -- GitLab