diff --git a/FAQ.md b/FAQ.md
index 04bfc97316..3319e33f69 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -138,7 +138,7 @@ FairEmail follows all the best practices for an email client as described in [th
* [(20) Can I get a refund?](#user-content-faq20)
* [(21) How do I enable the notification light?](#user-content-faq21)
* [(22) What does account/folder error ... mean?](#user-content-faq22)
-* [(23) Why do I get 'Too many simultaneous connections' or 'Maximum number of connections ... exceeded' ?](#user-content-faq23)
+* [(23) Why do I get alert .. ?](#user-content-faq23)
* [(24) What is browse messages on the server?](#user-content-faq24)
* [(25) Why can't I select/open/save an image, attachment or a file?](#user-content-faq25)
* [(26) Can I help to translate FairEmail in my own language?](#user-content-faq26)
@@ -842,27 +842,34 @@ When in doubt, you can ask for [support](#user-content-support).
-**(23) Why do I get 'Too many simultaneous connections' or 'Maximum number of connections ... exceeded' ?**
+**(23) Why do I get alert ... ?**
-The message *Too many simultaneous connections* is sent by the email server
-when there are too many folder connections for the same email account at the same time.
+*General*
+
+Alerts are warning messages sent by email servers.
+
+*Too many simultaneous connections* or *Maximum number of connections exceeded*
+
+This alert will be sent when there are too many folder connections for the same email account at the same time.
Possible causes are:
* There are multiple email clients connected to the same account
* The same email client is connected multiple times to the same account
-* The previous connection was terminated abruptly for example by abruptly losing internet connectivity, for example when turning on flight mode
+* Previous connections were terminated abruptly for example by abruptly losing internet connectivity
-If only FairEmail is connecting to the email server, first try to wait half an hour to see if the problem resolves itself,
-else enable the folder setting *Poll instead of synchronize* for some folders (long press folder in the folder list > Edit properties).
+First try to wait some time to see if the problem resolves itself,
+else try to enable the folder setting *Poll instead of synchronize* for some folders (long press folder in the folder list, edit properties).
The poll interval can be configured in the account settings.
-You also might want to disable *Browse messages on the server* in the advanced account settings (Setup > Step 1 > Manage > Tap account > Advanced).
-
The maximum number of simultaneous folder connections for Gmail is 15,
so you can synchronize at most 15 folders simultaneously on *all* your devices at the same time.
+For this reason Gmail user folders are set to poll by default.
See [here](https://support.google.com/mail/answer/7126229) for details.
+When using a Dovecot server,
+you might want to change the setting [mail_max_userip_connections](https://doc.dovecot.org/settings/dovecot_core_settings/#mail-max-userip-connections).
+
diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java
index 509b5dbaa2..4d2cb059d9 100644
--- a/app/src/main/java/eu/faircode/email/ActivityView.java
+++ b/app/src/main/java/eu/faircode/email/ActivityView.java
@@ -106,11 +106,12 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
static final int REQUEST_UNIFIED = 1;
static final int REQUEST_FOLDER = 2;
static final int REQUEST_WHY = 3;
- static final int REQUEST_THREAD = 4;
- static final int REQUEST_OUTBOX = 5;
- static final int REQUEST_ERROR = 6;
- static final int REQUEST_UPDATE = 7;
- static final int REQUEST_WIDGET = 8;
+ static final int REQUEST_ALERT = 4;
+ static final int REQUEST_THREAD = 5;
+ static final int REQUEST_OUTBOX = 6;
+ static final int REQUEST_ERROR = 7;
+ static final int REQUEST_UPDATE = 8;
+ static final int REQUEST_WIDGET = 9;
static final String ACTION_VIEW_FOLDERS = BuildConfig.APPLICATION_ID + ".VIEW_FOLDERS";
static final String ACTION_VIEW_MESSAGES = BuildConfig.APPLICATION_ID + ".VIEW_MESSAGES";
@@ -826,6 +827,12 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
Helper.viewFAQ(this, 2);
}
+ } else if ("alert".equals(action)) {
+ if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
+ getSupportFragmentManager().popBackStack("unified", 0);
+
+ Helper.viewFAQ(this, 23);
+
} else if ("outbox".equals(action))
onMenuOutbox();
diff --git a/app/src/main/java/eu/faircode/email/ApplicationEx.java b/app/src/main/java/eu/faircode/email/ApplicationEx.java
index 95511559d7..3362918a79 100644
--- a/app/src/main/java/eu/faircode/email/ApplicationEx.java
+++ b/app/src/main/java/eu/faircode/email/ApplicationEx.java
@@ -244,14 +244,14 @@ public class ApplicationEx extends Application {
nm.createNotificationChannel(update);
}
- // Warn
+ // Warnings
NotificationChannel warning = new NotificationChannel(
"warning", getString(R.string.channel_warning),
NotificationManager.IMPORTANCE_HIGH);
warning.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
nm.createNotificationChannel(warning);
- // Error
+ // Errors
NotificationChannel error = new NotificationChannel(
"error",
getString(R.string.channel_error),
@@ -259,6 +259,14 @@ public class ApplicationEx extends Application {
error.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
nm.createNotificationChannel(error);
+ // Server alerts
+ NotificationChannel alerts = new NotificationChannel(
+ "alerts",
+ getString(R.string.channel_alert),
+ NotificationManager.IMPORTANCE_HIGH);
+ alerts.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
+ nm.createNotificationChannel(alerts);
+
// Contacts grouping
NotificationChannelGroup group = new NotificationChannelGroup(
"contacts",
diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java
index deda3e152c..47a4da39ba 100644
--- a/app/src/main/java/eu/faircode/email/Core.java
+++ b/app/src/main/java/eu/faircode/email/Core.java
@@ -3191,27 +3191,13 @@ class Core {
.setPriority(NotificationCompat.PRIORITY_MAX)
.setOnlyAlertOnce(true)
.setCategory(NotificationCompat.CATEGORY_ERROR)
- .setVisibility(NotificationCompat.VISIBILITY_SECRET);
-
- builder.setStyle(new NotificationCompat.BigTextStyle()
- .bigText(Log.formatThrowable(ex, "\n", false)));
+ .setVisibility(NotificationCompat.VISIBILITY_SECRET)
+ .setStyle(new NotificationCompat.BigTextStyle()
+ .bigText(Log.formatThrowable(ex, "\n", false)));
return builder;
}
- static class AlertException extends Throwable {
- private String alert;
-
- AlertException(String alert) {
- this.alert = alert;
- }
-
- @Override
- public String getMessage() {
- return alert;
- }
- }
-
static class State {
private ConnectionHelper.NetworkState networkState;
private Thread thread;
diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java
index e30b685274..0a4659b7b0 100644
--- a/app/src/main/java/eu/faircode/email/Helper.java
+++ b/app/src/main/java/eu/faircode/email/Helper.java
@@ -273,7 +273,7 @@ public class Helper {
if (question == 0)
view(context, Uri.parse(FAQ_URI), false);
else
- view(context, Uri.parse(Helper.FAQ_URI + "#user-content-faq" + question), false);
+ view(context, Uri.parse(FAQ_URI + "#user-content-faq" + question), false);
}
static Intent getIntentOpenKeychain() {
diff --git a/app/src/main/java/eu/faircode/email/Log.java b/app/src/main/java/eu/faircode/email/Log.java
index 99b0b86e49..e75126b549 100644
--- a/app/src/main/java/eu/faircode/email/Log.java
+++ b/app/src/main/java/eu/faircode/email/Log.java
@@ -552,9 +552,6 @@ public class Log {
("Not connected".equals(ex.getMessage()) ||
"This operation is not allowed on a closed folder".equals(ex.getMessage())))
return null;
-
- if (ex instanceof Core.AlertException)
- return ex.getMessage();
}
StringBuilder sb = new StringBuilder();
diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
index 2a4063fd4d..8a1977ed1c 100644
--- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
+++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
@@ -707,6 +707,31 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
return builder;
}
+ private NotificationCompat.Builder getNotificationAlert(String account, String message) {
+ // Build pending intent
+ Intent alert = new Intent(this, ActivityView.class);
+ alert.setAction("alert");
+ PendingIntent piAlert = PendingIntent.getActivity(this, ActivityView.REQUEST_ALERT, alert, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ // Build notification
+ NotificationCompat.Builder builder =
+ new NotificationCompat.Builder(this, "alerts")
+ .setSmallIcon(R.drawable.baseline_warning_white_24)
+ .setContentTitle(getString(R.string.title_notification_alert, account))
+ .setContentText(message)
+ .setContentIntent(piAlert)
+ .setAutoCancel(false)
+ .setShowWhen(true)
+ .setPriority(NotificationCompat.PRIORITY_MAX)
+ .setOnlyAlertOnce(true)
+ .setCategory(NotificationCompat.CATEGORY_ERROR)
+ .setVisibility(NotificationCompat.VISIBILITY_SECRET)
+ .setStyle(new NotificationCompat.BigTextStyle()
+ .bigText(message));
+
+ return builder;
+ }
+
private void setUnseen(Integer unseen) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean badge = prefs.getBoolean("badge", true);
@@ -779,21 +804,11 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
try {
wlFolder.acquire();
- String message = e.getMessage();
- Log.w(account.name + " alert: " + message);
- EntityLog.log(
- ServiceSynchronize.this, account.name + " " +
- Log.formatThrowable(new Core.AlertException(message), false));
- db.account().setAccountError(account.id, message);
+ EntityLog.log(ServiceSynchronize.this, account.name + " " + e.getMessage());
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify("alert:" + account.id, 1,
- Core.getNotificationError(
- ServiceSynchronize.this, "warning", account.name,
- new Core.AlertException(message))
- .build());
-
- state.error(null);
+ getNotificationAlert(account.name, e.getMessage()).build());
} finally {
wlFolder.release();
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 23015c11d0..cd3717d777 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -15,6 +15,7 @@
Updates
Warnings
Errors
+ Server alerts
Contacts
@@ -87,6 +88,7 @@
Waiting for suitable connection
Sending messages
\'%1$s\' failed
+ \'%1$s\' server alert
%1$s (%2$s)