Compare commits

...

12 Commits
1.78 ... 1.80

Author SHA1 Message Date
M66B
e4cb13b9ec Revert "Hide battery optimization setup"
This reverts commit 7a55f8b8ed.
2018-10-10 08:36:13 +00:00
M66B
9ecdfaafa4 Fixed stopping idlers 2018-10-10 08:07:37 +00:00
M66B
7a55f8b8ed Hide battery optimization setup 2018-10-10 08:00:59 +00:00
M66B
681a8a31e2 Yield wake lock 2018-10-10 08:00:42 +00:00
M66B
0d340d1865 1.80 release 2018-10-10 07:33:15 +00:00
M66B
155506ce81 Keep alive 2018-10-10 07:26:04 +00:00
M66B
bf310662c1 Reset search 2018-10-09 20:31:26 +00:00
M66B
2f0babc479 Use alarm manager to keep alive 2018-10-09 20:31:18 +00:00
M66B
b19f496ce0 Use timers 2018-10-08 06:24:30 +00:00
M66B
1140ae3bf8 1.79 release 2018-10-07 18:47:05 +00:00
M66B
b75088833e Fixed synchronization 2018-10-07 18:43:44 +00:00
M66B
8f784c8954 Add keep alive wait to log 2018-10-07 17:34:59 +00:00
11 changed files with 581 additions and 579 deletions

Binary file not shown.

11
FAQ.md
View File

@@ -8,11 +8,12 @@ At the bottom you can find how to ask other questions, request features and repo
<a name="FAQ1"></a>
**(1) Which permissions are needed and why?**
* Full network access (INTERNET): to send and receive email
* View network connections (ACCESS_NETWORK_STATE): to monitor internet connectivity changes
* Run at startup (RECEIVE_BOOT_COMPLETED): to start monitoring on device start
* In-app billing (BILLING): to allow in-app purchases
* Foreground service (FOREGROUND_SERVICE): to run a foreground service on Android 9 Pie and later, see also the next question
* have full network access (INTERNET): to send and receive email
* view network connections (ACCESS_NETWORK_STATE): to monitor internet connectivity changes
* run at startup (RECEIVE_BOOT_COMPLETED): to start monitoring on device start
* in-app billing (BILLING): to allow in-app purchases
* foreground service (FOREGROUND_SERVICE): to run a foreground service on Android 9 Pie and later, see also the next question
* prevent device from sleeping (WAKE_LOCK): to keep the device awake while synchronizing messages
* Optional: read your contacts (READ_CONTACTS): to autocomplete addresses and to show photos
* Optional: find accounts on the device (GET_ACCOUNTS): to use [OAuth](https://en.wikipedia.org/wiki/OAuth) instead of passwords

View File

@@ -6,8 +6,8 @@ android {
applicationId "eu.faircode.email"
minSdkVersion 23
targetSdkVersion 28
versionCode 78
versionName "1.78"
versionCode 80
versionName "1.80"
archivesBaseName = "FairEmail-v$versionName"
javaCompileOptions {

View File

@@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.vending.BILLING" />
<application

View File

@@ -91,6 +91,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
@Override
public void run() {
Log.i(Helper.TAG, "Boundary close");
DB.getInstance(context).message().deleteFoundMessages();
try {
if (istore != null)
istore.close();

View File

@@ -124,9 +124,8 @@ public interface DaoFolder {
", synchronize = :synchronize" +
", unified = :unified" +
", `after` = :after" +
", `poll_interval` = :poll_interval" +
" WHERE id = :id")
int setFolderProperties(long id, String name, String display, boolean hide, boolean synchronize, boolean unified, int after, Integer poll_interval);
int setFolderProperties(long id, String name, String display, boolean hide, boolean synchronize, boolean unified, int after);
@Query("UPDATE folder SET name = :name WHERE account = :account AND name = :old")
int renameFolder(long account, String old, String name);

View File

@@ -224,9 +224,6 @@ public interface DaoMessage {
@Query("UPDATE message SET headers = :headers WHERE id = :id")
int setMessageHeaders(long id, String headers);
@Query("UPDATE message SET avatar = :avatar WHERE id = :id")
int setMessageAvatar(long id, String avatar);
@Query("DELETE FROM message WHERE id = :id")
int deleteMessage(long id);
@@ -241,4 +238,7 @@ public interface DaoMessage {
@Query("DELETE FROM message WHERE folder = :folder AND received < :received AND NOT uid IS NULL")
int deleteMessagesBefore(long folder, long received);
@Query("DELETE FROM message WHERE ui_found")
int deleteFoundMessages();
}

View File

@@ -60,7 +60,7 @@ public class EntityFolder implements Serializable {
public String type;
@NonNull
public Boolean synchronize;
public Integer poll_interval;
public Integer poll_interval; // obsolete
@NonNull
public Integer after; // days
public String display;

View File

@@ -44,7 +44,6 @@ import javax.mail.Session;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.Group;
import androidx.lifecycle.Observer;
public class FragmentFolder extends FragmentEx {
@@ -55,12 +54,10 @@ public class FragmentFolder extends FragmentEx {
private CheckBox cbSynchronize;
private CheckBox cbUnified;
private EditText etAfter;
private EditText etInterval;
private Button btnSave;
private ImageButton ibDelete;
private ProgressBar pbSave;
private ProgressBar pbWait;
private Group grpInterval;
private long id = -1;
private long account = -1;
@@ -89,12 +86,10 @@ public class FragmentFolder extends FragmentEx {
cbSynchronize = view.findViewById(R.id.cbSynchronize);
cbUnified = view.findViewById(R.id.cbUnified);
etAfter = view.findViewById(R.id.etAfter);
etInterval = view.findViewById(R.id.etInterval);
btnSave = view.findViewById(R.id.btnSave);
ibDelete = view.findViewById(R.id.ibDelete);
pbSave = view.findViewById(R.id.pbSave);
pbWait = view.findViewById(R.id.pbWait);
grpInterval = view.findViewById(R.id.grpInterval);
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
@@ -113,7 +108,6 @@ public class FragmentFolder extends FragmentEx {
args.putBoolean("unified", cbUnified.isChecked());
args.putBoolean("synchronize", cbSynchronize.isChecked());
args.putString("after", etAfter.getText().toString());
args.putString("interval", etInterval.getText().toString());
new SimpleTask<Void>() {
@Override
@@ -126,12 +120,10 @@ public class FragmentFolder extends FragmentEx {
boolean unified = args.getBoolean("unified");
boolean synchronize = args.getBoolean("synchronize");
String after = args.getString("after");
String interval = args.getString("interval");
if (TextUtils.isEmpty(display) || display.equals(name))
display = null;
int days = (TextUtils.isEmpty(after) ? EntityFolder.DEFAULT_USER_SYNC : Integer.parseInt(after));
Integer poll_interval = (TextUtils.isEmpty(interval) ? null : Integer.parseInt(interval));
IMAPStore istore = null;
DB db = DB.getInstance(getContext());
@@ -165,7 +157,6 @@ public class FragmentFolder extends FragmentEx {
create.unified = unified;
create.synchronize = synchronize;
create.after = days;
create.poll_interval = poll_interval;
db.folder().insertFolder(create);
} else {
Log.i(Helper.TAG, "Renaming folder=" + name);
@@ -180,7 +171,7 @@ public class FragmentFolder extends FragmentEx {
if (folder != null) {
Log.i(Helper.TAG, "Updating folder=" + name);
db.folder().setFolderProperties(id, name, display, hide, synchronize, unified, days, poll_interval);
db.folder().setFolderProperties(id, name, display, hide, synchronize, unified, days);
if (!synchronize)
db.folder().setFolderError(id, null);
}
@@ -303,7 +294,6 @@ public class FragmentFolder extends FragmentEx {
ibDelete.setVisibility(View.GONE);
pbSave.setVisibility(View.GONE);
pbWait.setVisibility(View.VISIBLE);
grpInterval.setVisibility(View.GONE);
return view;
}
@@ -330,7 +320,6 @@ public class FragmentFolder extends FragmentEx {
cbUnified.setChecked(folder == null ? false : folder.unified);
cbSynchronize.setChecked(folder == null || folder.synchronize);
etAfter.setText(Integer.toString(folder == null ? EntityFolder.DEFAULT_USER_SYNC : folder.after));
etInterval.setText(folder == null || folder.poll_interval == null ? null : Integer.toString(folder.poll_interval));
}
// Consider previous save as cancelled
@@ -341,57 +330,5 @@ public class FragmentFolder extends FragmentEx {
ibDelete.setVisibility(folder == null || !EntityFolder.USER.equals(folder.type) ? View.GONE : View.VISIBLE);
}
});
Bundle args = new Bundle();
args.putLong("id", id);
args.putLong("account", account);
new SimpleTask<Boolean>() {
@Override
protected Boolean onLoad(Context context, Bundle args) throws Throwable {
long fid = args.getLong("id");
long aid = args.getLong("account");
IMAPStore istore = null;
DB db = DB.getInstance(getContext());
try {
db.beginTransaction();
EntityAccount account;
if (fid < 0)
account = db.account().getAccount(aid);
else {
EntityFolder folder = db.folder().getFolder(fid);
account = db.account().getAccount(folder.account);
}
db.setTransactionSuccessful();
Properties props = MessageHelper.getSessionProperties(account.auth_type);
Session isession = Session.getInstance(props, null);
istore = (IMAPStore) isession.getStore("imaps");
istore.connect(account.host, account.port, account.user, account.password);
return istore.hasCapability("IDLE");
} finally {
db.endTransaction();
if (istore != null)
istore.close();
}
}
@Override
protected void onLoaded(Bundle args, Boolean capIdle) {
grpInterval.setVisibility(capIdle ? View.GONE : View.VISIBLE);
}
@Override
protected void onException(Bundle args, Throwable ex) {
grpInterval.setVisibility(View.VISIBLE);
if (BuildConfig.DEBUG)
Helper.unexpectedError(getContext(), ex);
}
}.load(this, args);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -102,26 +102,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvAfter" />
<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/etAfter" />
<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" />
<Button
android:id="@+id/btnSave"
android:layout_width="wrap_content"
@@ -129,7 +109,7 @@
android:layout_marginTop="12dp"
android:text="@string/title_save"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etInterval" />
app:layout_constraintTop_toBottomOf="@id/etAfter" />
<ImageButton
android:id="@+id/ibDelete"
@@ -138,7 +118,7 @@
android:layout_marginTop="12dp"
android:src="@drawable/baseline_delete_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/etInterval" />
app:layout_constraintTop_toBottomOf="@id/etAfter" />
<ProgressBar
android:id="@+id/pbSave"
@@ -161,11 +141,5 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Group
android:id="@+id/grpInterval"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="tvInterval,etInterval" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>