diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index c0d1d54417..f3a0078d12 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -1715,8 +1715,12 @@ class Core { return notifications; boolean pro = Helper.isPro(context); + boolean canGroup = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean flags = prefs.getBoolean("flags", true); + boolean notify_group = (prefs.getBoolean("notify_group", true) && canGroup); + boolean notify_preview = prefs.getBoolean("notify_preview", true); boolean notify_trash = prefs.getBoolean("notify_trash", true); boolean notify_archive = prefs.getBoolean("notify_archive", true); boolean notify_reply = prefs.getBoolean("notify_reply", false); @@ -1730,70 +1734,62 @@ class Core { for (TupleMessageEx message : messages) messageContact.put(message, ContactInfo.get(context, message.from, false)); - // Build pending intents - Intent summary = new Intent(context, ActivityView.class).setAction("unified"); - PendingIntent piSummary = PendingIntent.getActivity(context, ActivityView.REQUEST_UNIFIED, summary, PendingIntent.FLAG_UPDATE_CURRENT); + if (notify_group) { + // Build pending intents + Intent summary = new Intent(context, ActivityView.class).setAction("unified"); + PendingIntent piSummary = PendingIntent.getActivity(context, ActivityView.REQUEST_UNIFIED, summary, PendingIntent.FLAG_UPDATE_CURRENT); - Intent clear = new Intent(context, ServiceUI.class).setAction("clear"); - PendingIntent piClear = PendingIntent.getService(context, ServiceUI.PI_CLEAR, clear, PendingIntent.FLAG_UPDATE_CURRENT); + Intent clear = new Intent(context, ServiceUI.class).setAction("clear"); + PendingIntent piClear = PendingIntent.getService(context, ServiceUI.PI_CLEAR, clear, PendingIntent.FLAG_UPDATE_CURRENT); - // Build title - String title = context.getResources().getQuantityString( - R.plurals.title_notification_unseen, messages.size(), messages.size()); + // Build title + String title = context.getResources().getQuantityString( + R.plurals.title_notification_unseen, messages.size(), messages.size()); - // Build notification - NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "notification"); - builder - .setSmallIcon(R.drawable.baseline_email_white_24) - .setContentTitle(title) - .setContentIntent(piSummary) - .setNumber(messages.size()) - .setShowWhen(false) - .setDeleteIntent(piClear) - .setPriority(NotificationCompat.PRIORITY_DEFAULT) - .setCategory(NotificationCompat.CATEGORY_STATUS) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setGroup(group) - .setGroupSummary(true); + // Build notification + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "notification"); + builder + .setSmallIcon(R.drawable.baseline_email_white_24) + .setContentTitle(title) + .setContentIntent(piSummary) + .setNumber(messages.size()) + .setShowWhen(false) + .setDeleteIntent(piClear) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setCategory(NotificationCompat.CATEGORY_STATUS) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setGroup(group) + .setGroupSummary(true); - Notification pub = builder.build(); - builder - .setVisibility(NotificationCompat.VISIBILITY_PRIVATE) - .setPublicVersion(pub); + Notification pub = builder.build(); + builder + .setVisibility(NotificationCompat.VISIBILITY_PRIVATE) + .setPublicVersion(pub); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - boolean light = prefs.getBoolean("light", false); - String sound = prefs.getString("sound", null); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + setNotificationSoundAndLight(context, builder); + builder.setOnlyAlertOnce(true); + } else + builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN); - if (light) - builder.setLights(Color.GREEN, 1000, 1000); + DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT); + StringBuilder sb = new StringBuilder(); + for (EntityMessage message : messages) { + sb.append("").append(messageContact.get(message).getDisplayName(true)).append(""); + if (!TextUtils.isEmpty(message.subject)) + sb.append(": ").append(message.subject); + sb.append(" ").append(df.format(message.received)); + sb.append("
"); + } - Uri uri = (sound == null ? null : Uri.parse(sound)); - if (uri == null || "file".equals(uri.getScheme())) - uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); - builder.setSound(uri); + builder.setStyle(new NotificationCompat.BigTextStyle() + .bigText(HtmlHelper.fromHtml(sb.toString())) + .setSummaryText(title)); - builder.setOnlyAlertOnce(true); - } else - builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN); - - DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT); - StringBuilder sb = new StringBuilder(); - for (EntityMessage message : messages) { - sb.append("").append(messageContact.get(message).getDisplayName(true)).append(""); - if (!TextUtils.isEmpty(message.subject)) - sb.append(": ").append(message.subject); - sb.append(" ").append(df.format(message.received)); - sb.append("
"); + notifications.add(builder.build()); } - builder.setStyle(new NotificationCompat.BigTextStyle() - .bigText(HtmlHelper.fromHtml(sb.toString())) - .setSummaryText(title)); - - notifications.add(builder.build()); - - boolean preview = prefs.getBoolean("notify_preview", true); + // Message notifications for (TupleMessageEx message : messages) { ContactInfo info = messageContact.get(message); @@ -1844,10 +1840,11 @@ class Core { .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setCategory(NotificationCompat.CATEGORY_MESSAGE) .setVisibility(NotificationCompat.VISIBILITY_PRIVATE) - .setGroup(group) - .setGroupSummary(false) .setOnlyAlertOnce(true); + if (notify_group) + mbuilder.setGroup(group).setGroupSummary(false); + if (notify_trash) { Intent trash = new Intent(context, ServiceUI.class).setAction("trash:" + message.id); PendingIntent piTrash = PendingIntent.getService(context, ServiceUI.PI_TRASH, trash, PendingIntent.FLAG_UPDATE_CURRENT); @@ -1901,7 +1898,7 @@ class Core { if (!TextUtils.isEmpty(message.subject)) mbuilder.setContentText(message.subject); - if (message.content && preview) + if (message.content && notify_preview) try { String body = Helper.readText(message.getFile(context)); StringBuilder sbm = new StringBuilder(); @@ -1934,10 +1931,15 @@ class Core { mbuilder.setColorized(true); } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) - mbuilder.setSound(null); - else - mbuilder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (notify_group) + mbuilder.setSound(null); + else + setNotificationSoundAndLight(context, mbuilder); + } else { + if (notify_group) + mbuilder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN); + } notifications.add(mbuilder.build()); } @@ -1945,6 +1947,20 @@ class Core { return notifications; } + private static void setNotificationSoundAndLight(Context context, NotificationCompat.Builder builder) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean light = prefs.getBoolean("light", false); + String sound = prefs.getString("sound", null); + + if (light) + builder.setLights(Color.GREEN, 1000, 1000); + + Uri uri = (sound == null ? null : Uri.parse(sound)); + if (uri == null || "file".equals(uri.getScheme())) + uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + builder.setSound(uri); + } + static void reportError(Context context, EntityAccount account, EntityFolder folder, Throwable ex) { // FolderClosedException: can happen when no connectivity diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java index 4500894962..0e15f849e0 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java @@ -45,6 +45,7 @@ import androidx.preference.PreferenceManager; import static android.app.Activity.RESULT_OK; public class FragmentOptionsNotifications extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener { + private SwitchCompat swNotifyGroup; private SwitchCompat swNotifyPreview; private CheckBox cbNotifyActionTrash; private CheckBox cbNotifyActionArchive; @@ -57,7 +58,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared private Group grpNotification; private final static String[] RESET_OPTIONS = new String[]{ - "notify_preview", "notify_trash", "notify_archive", "notify_reply", "notify_flag", "notify_seen", "light", "sound" + "notify_group", "notify_preview", "notify_trash", "notify_archive", "notify_reply", "notify_flag", "notify_seen", "light", "sound" }; @Override @@ -70,6 +71,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared // Get controls + swNotifyGroup = view.findViewById(R.id.swNotifyGroup); swNotifyPreview = view.findViewById(R.id.swNotifyPreview); cbNotifyActionTrash = view.findViewById(R.id.cbNotifyActionTrash); cbNotifyActionArchive = view.findViewById(R.id.cbNotifyActionArchive); @@ -87,6 +89,13 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + swNotifyGroup.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("notify_group", checked).apply(); + } + }); + swNotifyPreview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { @@ -194,6 +203,8 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared private void setOptions() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + swNotifyGroup.setChecked(prefs.getBoolean("notify_group", true)); + swNotifyGroup.setVisibility(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? View.VISIBLE : View.GONE); swNotifyPreview.setChecked(prefs.getBoolean("notify_preview", true)); cbNotifyActionTrash.setChecked(prefs.getBoolean("notify_trash", true)); cbNotifyActionArchive.setChecked(prefs.getBoolean("notify_archive", true)); diff --git a/app/src/main/res/layout/fragment_options_notifications.xml b/app/src/main/res/layout/fragment_options_notifications.xml index c6622ec9c0..af8d899a2e 100644 --- a/app/src/main/res/layout/fragment_options_notifications.xml +++ b/app/src/main/res/layout/fragment_options_notifications.xml @@ -18,13 +18,23 @@ android:layout_height="wrap_content" android:padding="12dp"> + + Prefix subject only once on replying or forwarding Confirm sending messages + Group new message notifications Show message preview in notifications Notification actions Trash