mirror of https://github.com/M66B/FairEmail.git
Bring back polling
This commit is contained in:
parent
5cca576e28
commit
9cafc1223d
12
FAQ.md
12
FAQ.md
|
@ -49,13 +49,13 @@ See also [this FAQ](#FAQ16).
|
|||
Valid security certificates are officially signed (not self signed) and have matching a host name.
|
||||
|
||||
<a name="FAQ5"></a>
|
||||
**(5) What does 'no IDLE support' mean?**
|
||||
~~**(5) What does 'no IDLE support' mean?**~~
|
||||
|
||||
Without [IMAP IDLE](https://en.wikipedia.org/wiki/IMAP_IDLE) emails need to be periodically fetched,
|
||||
which is a waste of battery power and internet bandwidth and will delay notification of new emails.
|
||||
Since the goal of FairEmail is to offer safe and fast email, providers without IMAP IDLE are not supported.
|
||||
You should consider this a problem of the provider, not of the app.
|
||||
Almost all email providers offer IMAP IDLE, with as notable exception Yahoo!
|
||||
~~Without [IMAP IDLE](https://en.wikipedia.org/wiki/IMAP_IDLE) emails need to be periodically fetched,~~
|
||||
~~which is a waste of battery power and internet bandwidth and will delay notification of new emails.~~
|
||||
~~Since the goal of FairEmail is to offer safe and fast email, providers without IMAP IDLE are not supported.~~
|
||||
~~You should consider this a problem of the provider, not of the app.~~
|
||||
~~Almost all email providers offer IMAP IDLE, with as notable exception Yahoo!~~
|
||||
|
||||
<a name="FAQ6"></a>
|
||||
**(6) How can I login to Gmail / G suite?**
|
||||
|
|
5
SETUP.md
5
SETUP.md
|
@ -7,11 +7,6 @@ You'll need to add at least one account to receive email and at least one identi
|
|||
|
||||
An internet connection is required to add accounts and identities.
|
||||
|
||||
Your email provider should support IMAP with the IDLE and UIDPLUS extensions.
|
||||
All up-to-date email providers do, with as notable exception Yahoo!
|
||||
IMAP IDLE is required to limit battery usage,
|
||||
see [this FAQ](https://github.com/M66B/open-source-email/blob/master/FAQ.md#FAQ5) for more details.
|
||||
|
||||
Your email provider should support secure connections.
|
||||
If your provider doesn't support secure connections and you care at least a little about your privacy,
|
||||
you are strongly advised to switch to another provider.
|
||||
|
|
|
@ -110,6 +110,7 @@ public class FragmentAccount extends FragmentEx {
|
|||
private ImageButton ibPro;
|
||||
private CheckBox cbSynchronize;
|
||||
private CheckBox cbPrimary;
|
||||
private EditText etInterval;
|
||||
private Button btnCheck;
|
||||
|
||||
private ProgressBar pbCheck;
|
||||
|
@ -173,6 +174,7 @@ public class FragmentAccount extends FragmentEx {
|
|||
|
||||
cbSynchronize = view.findViewById(R.id.cbSynchronize);
|
||||
cbPrimary = view.findViewById(R.id.cbPrimary);
|
||||
etInterval = view.findViewById(R.id.etInterval);
|
||||
|
||||
btnCheck = view.findViewById(R.id.btnCheck);
|
||||
pbCheck = view.findViewById(R.id.pbCheck);
|
||||
|
@ -429,9 +431,6 @@ public class FragmentAccount extends FragmentEx {
|
|||
throw ex;
|
||||
}
|
||||
|
||||
if (!istore.hasCapability("IDLE"))
|
||||
throw new MessagingException(getContext().getString(R.string.title_no_idle));
|
||||
|
||||
if (!istore.hasCapability("UIDPLUS"))
|
||||
throw new MessagingException(getContext().getString(R.string.title_no_uidplus));
|
||||
|
||||
|
@ -567,6 +566,7 @@ public class FragmentAccount extends FragmentEx {
|
|||
args.putInt("color", color);
|
||||
args.putString("signature", Html.toHtml(etSignature.getText()));
|
||||
args.putBoolean("primary", cbPrimary.isChecked());
|
||||
args.putString("interval", etInterval.getText().toString());
|
||||
|
||||
args.putParcelable("drafts", drafts);
|
||||
args.putParcelable("sent", sent);
|
||||
|
@ -588,6 +588,7 @@ public class FragmentAccount extends FragmentEx {
|
|||
String signature = args.getString("signature");
|
||||
boolean synchronize = args.getBoolean("synchronize");
|
||||
boolean primary = args.getBoolean("primary");
|
||||
String interval = args.getString("interval");
|
||||
|
||||
EntityFolder drafts = args.getParcelable("drafts");
|
||||
EntityFolder sent = args.getParcelable("sent");
|
||||
|
@ -603,6 +604,8 @@ public class FragmentAccount extends FragmentEx {
|
|||
throw new Throwable(getContext().getString(R.string.title_no_user));
|
||||
if (TextUtils.isEmpty(password))
|
||||
throw new Throwable(getContext().getString(R.string.title_no_password));
|
||||
if (TextUtils.isEmpty(interval))
|
||||
interval = "9";
|
||||
if (synchronize && drafts == null)
|
||||
throw new Throwable(getContext().getString(R.string.title_no_drafts));
|
||||
|
||||
|
@ -653,7 +656,7 @@ public class FragmentAccount extends FragmentEx {
|
|||
account.synchronize = synchronize;
|
||||
account.primary = (account.synchronize && primary);
|
||||
account.store_sent = false;
|
||||
account.poll_interval = 9;
|
||||
account.poll_interval = Integer.parseInt(interval);
|
||||
|
||||
if (!synchronize)
|
||||
account.error = null;
|
||||
|
@ -874,6 +877,7 @@ public class FragmentAccount extends FragmentEx {
|
|||
|
||||
cbSynchronize.setChecked(account == null ? true : account.synchronize);
|
||||
cbPrimary.setChecked(account == null ? true : account.primary);
|
||||
etInterval.setText(Long.toString(account == null ? 9 : account.poll_interval));
|
||||
|
||||
color = (account == null || account.color == null ? Color.TRANSPARENT : account.color);
|
||||
|
||||
|
|
|
@ -642,6 +642,8 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
db.folder().setFolderState(folder.id, null);
|
||||
db.account().setAccountState(account.id, "connecting");
|
||||
Helper.connect(this, istore, account);
|
||||
final boolean capIdle = istore.hasCapability("IDLE");
|
||||
Log.i(Helper.TAG, account.name + " idle=" + capIdle);
|
||||
db.account().setAccountState(account.id, "connected");
|
||||
db.account().setAccountError(account.id, null);
|
||||
|
||||
|
@ -813,15 +815,18 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
try {
|
||||
Thread.sleep(account.poll_interval * 60 * 1000L);
|
||||
|
||||
Log.i(Helper.TAG, folder.name + " request NOOP");
|
||||
ifolder.doCommand(new IMAPFolder.ProtocolCommand() {
|
||||
public Object doCommand(IMAPProtocol p) throws ProtocolException {
|
||||
Log.i(Helper.TAG, ifolder.getName() + " start NOOP");
|
||||
p.simpleCommand("NOOP", null);
|
||||
Log.i(Helper.TAG, ifolder.getName() + " end NOOP");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (capIdle) {
|
||||
Log.i(Helper.TAG, folder.name + " request NOOP");
|
||||
ifolder.doCommand(new IMAPFolder.ProtocolCommand() {
|
||||
public Object doCommand(IMAPProtocol p) throws ProtocolException {
|
||||
Log.i(Helper.TAG, ifolder.getName() + " start NOOP");
|
||||
p.simpleCommand("NOOP", null);
|
||||
Log.i(Helper.TAG, ifolder.getName() + " end NOOP");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} else
|
||||
synchronizeMessages(account, folder, ifolder, state);
|
||||
|
||||
} catch (InterruptedException ex) {
|
||||
Log.w(Helper.TAG, folder.name + " noop " + ex.toString());
|
||||
|
@ -845,32 +850,34 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
noops.add(noop);
|
||||
|
||||
// Receive folder events
|
||||
Thread idle = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Log.i(Helper.TAG, folder.name + " start idle");
|
||||
while (state.running && ifolder.isOpen()) {
|
||||
//Log.i(Helper.TAG, folder.name + " do idle");
|
||||
ifolder.idle(false);
|
||||
//Log.i(Helper.TAG, folder.name + " done idle");
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex));
|
||||
reportError(account.name, folder.name, ex);
|
||||
if (capIdle) {
|
||||
Thread idle = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Log.i(Helper.TAG, folder.name + " start idle");
|
||||
while (state.running && ifolder.isOpen()) {
|
||||
Log.i(Helper.TAG, folder.name + " do idle");
|
||||
ifolder.idle(false);
|
||||
//Log.i(Helper.TAG, folder.name + " done idle");
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
Log.e(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex));
|
||||
reportError(account.name, folder.name, ex);
|
||||
|
||||
db.folder().setFolderError(folder.id, Helper.formatThrowable(ex));
|
||||
db.folder().setFolderError(folder.id, Helper.formatThrowable(ex));
|
||||
|
||||
synchronized (state) {
|
||||
state.notifyAll();
|
||||
synchronized (state) {
|
||||
state.notifyAll();
|
||||
}
|
||||
} finally {
|
||||
Log.i(Helper.TAG, folder.name + " end idle");
|
||||
}
|
||||
} finally {
|
||||
Log.i(Helper.TAG, folder.name + " end idle");
|
||||
}
|
||||
}
|
||||
}, "sync.idle." + folder.id);
|
||||
idle.start();
|
||||
idlers.add(idle);
|
||||
}, "sync.idle." + folder.id);
|
||||
idle.start();
|
||||
idlers.add(idle);
|
||||
}
|
||||
}
|
||||
|
||||
backoff = CONNECT_BACKOFF_START;
|
||||
|
|
|
@ -173,7 +173,6 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvUser" />
|
||||
|
||||
|
||||
<!-- password -->
|
||||
|
||||
<TextView
|
||||
|
@ -318,6 +317,29 @@
|
|||
android:text="@string/title_primary_account"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cbSynchronize" />
|
||||
|
||||
<!-- port -->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvInterval"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_poll_interval"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cbPrimary" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etInterval"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="9"
|
||||
android:inputType="number"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvInterval" />
|
||||
|
||||
<!-- check -->
|
||||
|
||||
<Button
|
||||
|
@ -327,7 +349,7 @@
|
|||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_check"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cbPrimary" />
|
||||
app:layout_constraintTop_toBottomOf="@id/etInterval" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pbCheck"
|
||||
|
@ -347,7 +369,7 @@
|
|||
android:layout_marginTop="12dp"
|
||||
android:src="@drawable/baseline_delete_24"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cbPrimary" />
|
||||
app:layout_constraintTop_toBottomOf="@id/etInterval" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDrafts"
|
||||
|
@ -498,7 +520,7 @@
|
|||
android:id="@+id/grpAdvanced"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:constraint_referenced_ids="tvName,etName,btnColor,vwColor,ibColorDefault,tvSignature,etSignature,ibPro,cbSynchronize,cbPrimary" />
|
||||
app:constraint_referenced_ids="tvName,etName,btnColor,vwColor,ibColorDefault,tvSignature,etSignature,ibPro,cbSynchronize,cbPrimary,tvInterval,etInterval" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/grpFolders"
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
<string name="title_synchronize_identity">Synchronize (send messages)</string>
|
||||
<string name="title_primary_account">Primary (default account)</string>
|
||||
<string name="title_primary_identity">Primary (default identity)</string>
|
||||
<string name="title_poll_interval">Poll interval (minutes)</string>
|
||||
<string name="title_check">Check</string>
|
||||
<string name="title_no_name">Name missing</string>
|
||||
<string name="title_no_email">Email address missing</string>
|
||||
|
@ -119,7 +120,6 @@
|
|||
<string name="title_no_user">User name missing</string>
|
||||
<string name="title_no_password">Password missing</string>
|
||||
<string name="title_no_drafts">Drafts folder missing</string>
|
||||
<string name="title_no_idle">IMAP IDLE not supported, see the FAQ</string>
|
||||
<string name="title_no_uidplus">IMAP UIDPLUS not supported, see the FAQ</string>
|
||||
<string name="title_account_delete">Delete this account permanently?</string>
|
||||
<string name="title_identity_delete">Delete this identity permanently?</string>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
starttls="false" />
|
||||
</provider>
|
||||
<!-- no IMAP IDLE -->
|
||||
<!--provider
|
||||
<provider
|
||||
name="Yahoo!"
|
||||
link="https://help.yahoo.com/kb/SLN4075.html">
|
||||
<imap
|
||||
|
@ -46,7 +46,7 @@
|
|||
host="smtp.mail.yahoo.com"
|
||||
port="465"
|
||||
starttls="false" />
|
||||
</provider-->
|
||||
</provider>
|
||||
<provider
|
||||
name="Posteo.de"
|
||||
link="https://posteo.de/en/help/how-do-i-set-up-posteo-in-an-email-client-pop3-imap-and-smtp">
|
||||
|
@ -81,7 +81,7 @@
|
|||
starttls="false" />
|
||||
</provider>
|
||||
<!-- no IMAP IDLE -->
|
||||
<!--provider
|
||||
<provider
|
||||
name="SFR.fr"
|
||||
link="https://assistance.sfr.fr/service-et-accessoire/sfr-mail/serveurs-messagerie-sfr.html">
|
||||
<imap
|
||||
|
@ -91,7 +91,7 @@
|
|||
host="smtp.sfr.fr"
|
||||
port="465"
|
||||
starttls="false" />
|
||||
</provider-->
|
||||
</provider>
|
||||
<provider
|
||||
name="infomaniak"
|
||||
link="https://www.infomaniak.com/fr/support/faq/1075/configurer-une-adresse-email-configuration-logiciel-de-messagerie-parametres-courrier">
|
||||
|
|
Loading…
Reference in New Issue