diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java
index ad3f6aa126..57ac10b3fe 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptions.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java
@@ -63,6 +63,7 @@ import static android.app.Activity.RESULT_OK;
public class FragmentOptions extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener {
private SwitchCompat swEnabled;
+ private Spinner spPollInterval;
private SwitchCompat swSchedule;
private TextView tvScheduleStart;
private TextView tvScheduleEnd;
@@ -130,7 +131,7 @@ public class FragmentOptions extends FragmentBase implements SharedPreferences.O
};
private final static String[] ADVANCED_OPTIONS = new String[]{
- "enabled", "schedule_start", "schedule_end",
+ "enabled", "poll_interval", "schedule", "schedule_start", "schedule_end",
"metered", "download", "roaming",
"startup", "date", "threading", "avatars", "identicons", "circular", "name_email", "subject_italic", "flags", "preview",
"addresses", "monospaced", "autohtml", "autoimages", "actionbar",
@@ -152,6 +153,7 @@ public class FragmentOptions extends FragmentBase implements SharedPreferences.O
// Get controls
swEnabled = view.findViewById(R.id.swEnabled);
+ spPollInterval = view.findViewById(R.id.spPollInterval);
swSchedule = view.findViewById(R.id.swSchedule);
tvScheduleStart = view.findViewById(R.id.tvScheduleStart);
tvScheduleEnd = view.findViewById(R.id.tvScheduleEnd);
@@ -220,10 +222,35 @@ public class FragmentOptions extends FragmentBase implements SharedPreferences.O
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("enabled", checked).apply();
+ spPollInterval.setEnabled(checked);
+ swSchedule.setEnabled(checked);
ServiceSynchronize.reload(getContext(), true, "enabled=" + checked);
}
});
+ spPollInterval.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> adapterView, View view, int position, long id) {
+ Object tag = adapterView.getTag();
+ int current = (tag == null ? 0 : (Integer) tag);
+ int[] values = getResources().getIntArray(R.array.pollIntervalValues);
+ int value = values[position];
+ if (value != current) {
+ adapterView.setTag(value);
+ prefs.edit().putInt("poll_interval", value).apply();
+ WorkerPoll.init(getContext());
+ ServiceSynchronize.reload(getContext(), "poll");
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ prefs.edit().remove("poll_interval").apply();
+ WorkerPoll.init(getContext());
+ ServiceSynchronize.reload(getContext(), "poll");
+ }
+ });
+
swSchedule.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
@@ -238,10 +265,7 @@ public class FragmentOptions extends FragmentBase implements SharedPreferences.O
fragmentTransaction.commit();
}
} else {
- SharedPreferences.Editor editor = prefs.edit();
- editor.putBoolean("schedule", false);
- editor.putBoolean("enabled", true);
- editor.apply();
+ prefs.edit().putBoolean("schedule", false).apply();
ServiceSynchronize.reload(getContext(), "schedule=" + checked);
}
}
@@ -675,8 +699,19 @@ public class FragmentOptions extends FragmentBase implements SharedPreferences.O
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
swEnabled.setChecked(prefs.getBoolean("enabled", true));
- swSchedule.setChecked(prefs.getBoolean("schedule", false));
+ spPollInterval.setEnabled(swEnabled.isChecked());
+ swSchedule.setEnabled(swEnabled.isChecked());
+
+ int pollInterval = prefs.getInt("poll_interval", 0);
+ int[] pollIntervalValues = getResources().getIntArray(R.array.pollIntervalValues);
+ for (int pos = 0; pos < pollIntervalValues.length; pos++)
+ if (pollIntervalValues[pos] == pollInterval) {
+ spPollInterval.setTag(pollInterval);
+ spPollInterval.setSelection(pos);
+ break;
+ }
+ swSchedule.setChecked(prefs.getBoolean("schedule", false));
tvScheduleStart.setText(formatHour(getContext(), prefs.getInt("schedule_start", 0)));
tvScheduleEnd.setText(formatHour(getContext(), prefs.getInt("schedule_end", 0)));
diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
index 983e9babad..c86221ac22 100644
--- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
+++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
@@ -384,8 +384,9 @@ public class ServiceSynchronize extends LifecycleService {
private boolean isEnabled() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean enabled = prefs.getBoolean("enabled", true);
+ int pollInterval = prefs.getInt("poll_interval", 0);
boolean oneshot = prefs.getBoolean("oneshot", false);
- return (enabled || oneshot);
+ return ((enabled && pollInterval == 0) || oneshot);
}
private void start() {
@@ -1197,10 +1198,14 @@ public class ServiceSynchronize extends LifecycleService {
// Restore schedule
schedule(context);
+ // Initialize polling
+ WorkerPoll.init(context);
+
// Conditionally init service
boolean enabled = prefs.getBoolean("enabled", true);
+ int pollInterval = prefs.getInt("poll_interval", 0);
int accounts = db.account().getSynchronizingAccounts().size();
- if (enabled && accounts > 0)
+ if (enabled && pollInterval == 0 && accounts > 0)
ContextCompat.startForegroundService(context,
new Intent(context, ServiceSynchronize.class)
.setAction("init"));
@@ -1307,8 +1312,14 @@ public class ServiceSynchronize extends LifecycleService {
static void process(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean enabled = prefs.getBoolean("enabled", true);
+ if (!enabled)
+ onshot(context);
+ }
+
+ static void onshot(Context context) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean oneshot = prefs.getBoolean("oneshot", false);
- if (!enabled && !oneshot) {
+ if (!oneshot) {
prefs.edit().putBoolean("oneshot", true).apply();
ContextCompat.startForegroundService(context,
new Intent(context, ServiceSynchronize.class)
diff --git a/app/src/main/java/eu/faircode/email/WorkerPoll.java b/app/src/main/java/eu/faircode/email/WorkerPoll.java
new file mode 100644
index 0000000000..8cb4d1d8f3
--- /dev/null
+++ b/app/src/main/java/eu/faircode/email/WorkerPoll.java
@@ -0,0 +1,54 @@
+package eu.faircode.email;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import androidx.annotation.NonNull;
+import androidx.work.ExistingPeriodicWorkPolicy;
+import androidx.work.PeriodicWorkRequest;
+import androidx.work.WorkManager;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+
+import java.util.concurrent.TimeUnit;
+
+public class WorkerPoll extends Worker {
+ public WorkerPoll(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+ super(context, workerParams);
+ Log.i("Instance " + getName());
+ }
+
+ @NonNull
+ @Override
+ public Result doWork() {
+ Log.i("Running " + getName());
+ ServiceSynchronize.onshot(getApplicationContext());
+ return Result.success();
+ }
+
+ static void init(Context context) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean enabled = prefs.getBoolean("enabled", true);
+ int pollInterval = prefs.getInt("poll_interval", 0);
+ if (enabled && pollInterval > 0) {
+ Log.i("Queuing " + getName() + " every " + pollInterval + " minutes");
+ PeriodicWorkRequest workRequest =
+ new PeriodicWorkRequest.Builder(WorkerPoll.class, pollInterval, TimeUnit.MINUTES)
+ .build();
+ WorkManager.getInstance(context)
+ .enqueueUniquePeriodicWork(getName(), ExistingPeriodicWorkPolicy.REPLACE, workRequest);
+
+ Log.i("Queued " + getName());
+ } else {
+
+ Log.i("Cancelling " + getName());
+ WorkManager.getInstance(context).cancelUniqueWork(getName());
+ Log.i("Cancelled " + getName());
+ }
+ }
+
+ private static String getName() {
+ return WorkerPoll.class.getSimpleName();
+ }
+}
diff --git a/app/src/main/res/layout/fragment_options.xml b/app/src/main/res/layout/fragment_options.xml
index 06943203e8..e7cefa3432 100644
--- a/app/src/main/res/layout/fragment_options.xml
+++ b/app/src/main/res/layout/fragment_options.xml
@@ -64,6 +64,16 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swEnabled" />
+
+
Please describe what you were doing when the app crashed:
FairEmail %1$s issue
+
+ - Always
+ - Half hour
+ - Hour
+ - 2 hours
+ - 4 hours
+
+
+
+ - 0
+ - 30
+ - 60
+ - 120
+ - 240
+
+
- unified
- folders