mirror of https://github.com/M66B/FairEmail.git
Notify on demand
This commit is contained in:
parent
9659f88bc9
commit
917c02f46d
4
FAQ.md
4
FAQ.md
|
@ -1295,10 +1295,6 @@ you can enable on demand synchronization in the account settings.
|
|||
When enabled FairEmail will not keep a connection to the email server anymore,
|
||||
instead you can manually synchronize messages by either using pull-down-to-refresh or by using the folder menu *Synchronize now*.
|
||||
|
||||
Note that globally disabling FairEmail with the advanced option *Synchronize*,
|
||||
by using [a schedule](#user-content-faq78) or by using [a quick settings tile](#user-content-faq30)
|
||||
will remove the associated [status bar notification](#user-content-faq2), but will also disable new message notifications.
|
||||
|
||||
<br />
|
||||
|
||||
## Support
|
||||
|
|
|
@ -13,7 +13,9 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.text.TextUtils;
|
||||
import android.util.LongSparseArray;
|
||||
|
||||
import com.sun.mail.iap.ConnectionException;
|
||||
import com.sun.mail.iap.Response;
|
||||
|
@ -1387,7 +1389,94 @@ class Core {
|
|||
}
|
||||
}
|
||||
|
||||
static List<Notification> getNotificationUnseen(Context context, long account, String accountName, List<TupleMessageEx> messages) {
|
||||
static void notify(Context context, List<TupleMessageEx> messages) {
|
||||
Log.i("Notify messages=" + messages.size());
|
||||
|
||||
Widget.update(context, messages.size());
|
||||
|
||||
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
LongSparseArray<List<Long>> notifying = new LongSparseArray<>();
|
||||
LongSparseArray<String> accountName = new LongSparseArray<>();
|
||||
LongSparseArray<List<TupleMessageEx>> accountMessages = new LongSparseArray<>();
|
||||
|
||||
// Existing
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
for (StatusBarNotification notification : nm.getActiveNotifications()) {
|
||||
Bundle args = notification.getNotification().extras;
|
||||
long id = args.getLong("id", 0);
|
||||
long account = args.getLong("account", 0);
|
||||
Log.i("Notify showing=" + id);
|
||||
if (id != 0) {
|
||||
if (notifying.indexOfKey(account) < 0) {
|
||||
notifying.put(account, new ArrayList<Long>());
|
||||
accountMessages.put(account, new ArrayList<TupleMessageEx>());
|
||||
}
|
||||
notifying.get(account).add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Current
|
||||
for (TupleMessageEx message : messages) {
|
||||
long account = (message.accountNotify ? message.account : 0);
|
||||
accountName.put(account, account > 0 ? message.accountName : null);
|
||||
if (accountMessages.indexOfKey(account) < 0) {
|
||||
notifying.put(account, new ArrayList<Long>());
|
||||
accountMessages.put(account, new ArrayList<TupleMessageEx>());
|
||||
}
|
||||
accountMessages.get(account).add(message);
|
||||
}
|
||||
|
||||
// Difference
|
||||
for (int i = 0; i < accountMessages.size(); i++) {
|
||||
long account = accountMessages.keyAt(i);
|
||||
List<Notification> notifications = getNotificationUnseen(
|
||||
context, account, accountName.get(account), accountMessages.get(account));
|
||||
|
||||
List<Long> all = new ArrayList<>();
|
||||
List<Long> added = new ArrayList<>();
|
||||
List<Long> removed = notifying.get(account);
|
||||
for (Notification notification : notifications) {
|
||||
Long id = notification.extras.getLong("id", 0);
|
||||
if (id != 0) {
|
||||
all.add(id);
|
||||
if (removed.contains(id)) {
|
||||
removed.remove(id);
|
||||
Log.i("Notify removing=" + id);
|
||||
} else {
|
||||
removed.remove(-id);
|
||||
added.add(id);
|
||||
Log.i("Notify adding=" + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int headers = 0;
|
||||
for (Long id : added)
|
||||
if (id < 0)
|
||||
headers++;
|
||||
|
||||
Log.i("Notify account=" + account +
|
||||
" count=" + notifications.size() + " all=" + all.size() +
|
||||
" added=" + added.size() + " removed=" + removed.size() + " headers=" + headers);
|
||||
|
||||
if (notifications.size() == 0 ||
|
||||
(Build.VERSION.SDK_INT < Build.VERSION_CODES.O && headers > 0))
|
||||
nm.cancel("unseen:" + account + ":0", 1);
|
||||
|
||||
for (Long id : removed)
|
||||
nm.cancel("unseen:" + account + ":" + Math.abs(id), 1);
|
||||
|
||||
for (Notification notification : notifications) {
|
||||
long id = notification.extras.getLong("id", 0);
|
||||
if ((id == 0 && added.size() + removed.size() > 0) || added.contains(id))
|
||||
nm.notify("unseen:" + account + ":" + Math.abs(id), 1, notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Notification> getNotificationUnseen(Context context, long account, String accountName, List<TupleMessageEx> messages) {
|
||||
List<Notification> notifications = new ArrayList<>();
|
||||
|
||||
if (messages.size() == 0)
|
||||
|
@ -1496,6 +1585,7 @@ class Core {
|
|||
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("id", message.content ? message.id : -message.id);
|
||||
args.putLong("account", message.accountNotify ? message.account : 0);
|
||||
|
||||
Intent thread = new Intent(context, ActivityView.class);
|
||||
thread.setAction("thread:" + message.thread);
|
||||
|
|
|
@ -207,7 +207,7 @@ public interface DaoMessage {
|
|||
" WHERE message.id = :id")
|
||||
LiveData<TupleMessageEx> liveMessage(long id);
|
||||
|
||||
@Query("SELECT message.*" +
|
||||
String notify = "SELECT message.*" +
|
||||
", account.name AS accountName, IFNULL(identity.color, account.color) AS accountColor, account.notify AS accountNotify" +
|
||||
", folder.name AS folderName, folder.display AS folderDisplay, folder.type AS folderType" +
|
||||
", identity.name AS identityName, identity.email AS identityEmail, identity.synchronize AS identitySynchronize" +
|
||||
|
@ -227,9 +227,14 @@ public interface DaoMessage {
|
|||
" AND NOT message.ui_seen" +
|
||||
" AND NOT message.ui_hide" +
|
||||
" AND NOT message.ui_ignored" +
|
||||
" ORDER BY message.received")
|
||||
" ORDER BY message.received";
|
||||
|
||||
@Query(notify)
|
||||
LiveData<List<TupleMessageEx>> liveUnseenNotify();
|
||||
|
||||
@Query(notify)
|
||||
List<TupleMessageEx> getUnseenNotify();
|
||||
|
||||
@Query("SELECT COUNT(message.id) FROM message" +
|
||||
" JOIN account ON account.id = message.account" +
|
||||
" JOIN folder ON folder.id = message.folder" +
|
||||
|
|
|
@ -36,7 +36,6 @@ import android.os.Build;
|
|||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.LongSparseArray;
|
||||
|
||||
import com.sun.mail.imap.IMAPFolder;
|
||||
import com.sun.mail.imap.IMAPMessage;
|
||||
|
@ -126,79 +125,9 @@ public class ServiceSynchronize extends LifecycleService {
|
|||
});
|
||||
|
||||
db.message().liveUnseenNotify().observe(this, new Observer<List<TupleMessageEx>>() {
|
||||
private LongSparseArray<List<Integer>> notifying = new LongSparseArray<>();
|
||||
|
||||
@Override
|
||||
public void onChanged(final List<TupleMessageEx> messages) {
|
||||
Log.i("Notification messages=" + messages.size());
|
||||
|
||||
Widget.update(ServiceSynchronize.this, messages.size());
|
||||
|
||||
LongSparseArray<String> accountName = new LongSparseArray<>();
|
||||
LongSparseArray<List<TupleMessageEx>> accountMessages = new LongSparseArray<>();
|
||||
|
||||
for (int i = 0; i < notifying.size(); i++)
|
||||
accountMessages.put(notifying.keyAt(i), new ArrayList<TupleMessageEx>());
|
||||
|
||||
for (TupleMessageEx message : messages) {
|
||||
long account = (message.accountNotify ? message.account : 0);
|
||||
accountName.put(account, account > 0 ? message.accountName : null);
|
||||
if (accountMessages.indexOfKey(account) < 0)
|
||||
accountMessages.put(account, new ArrayList<TupleMessageEx>());
|
||||
accountMessages.get(account).add(message);
|
||||
if (notifying.indexOfKey(account) < 0)
|
||||
notifying.put(account, new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
for (int i = 0; i < accountMessages.size(); i++) {
|
||||
long account = accountMessages.keyAt(i);
|
||||
List<Notification> notifications = Core.getNotificationUnseen(
|
||||
ServiceSynchronize.this, account, accountName.get(account), accountMessages.get(account));
|
||||
|
||||
List<Integer> all = new ArrayList<>();
|
||||
List<Integer> added = new ArrayList<>();
|
||||
List<Integer> removed = notifying.get(account);
|
||||
for (Notification notification : notifications) {
|
||||
Integer id = (int) notification.extras.getLong("id", 0);
|
||||
if (id != 0) {
|
||||
all.add(id);
|
||||
if (removed.contains(id)) {
|
||||
removed.remove(id);
|
||||
Log.i("Notification removing=" + id);
|
||||
} else {
|
||||
removed.remove(Integer.valueOf(-id));
|
||||
added.add(id);
|
||||
Log.i("Notification adding=" + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int headers = 0;
|
||||
for (Integer id : added)
|
||||
if (id < 0)
|
||||
headers++;
|
||||
|
||||
Log.i("Notification account=" + account +
|
||||
" notifications=" + notifications.size() + " all=" + all.size() +
|
||||
" added=" + added.size() + " removed=" + removed.size() + " headers=" + headers);
|
||||
|
||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
if (notifications.size() == 0 ||
|
||||
(Build.VERSION.SDK_INT < Build.VERSION_CODES.O && headers > 0))
|
||||
nm.cancel("unseen:" + account, 0);
|
||||
|
||||
for (Integer id : removed)
|
||||
nm.cancel("unseen:" + account, Math.abs(id));
|
||||
|
||||
for (Notification notification : notifications) {
|
||||
Integer id = (int) notification.extras.getLong("id", 0);
|
||||
if ((id == 0 && added.size() + removed.size() > 0) || added.contains(id))
|
||||
nm.notify("unseen:" + account, Math.abs(id), notification);
|
||||
}
|
||||
|
||||
notifying.put(account, all);
|
||||
}
|
||||
Core.notify(ServiceSynchronize.this, messages);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -281,6 +281,9 @@ public class ServiceUI extends IntentService {
|
|||
// Synchronize messages
|
||||
Core.onSynchronizeMessages(this, account, folder, (IMAPFolder) ifolder, folder.getSyncArgs(), new Core.State());
|
||||
|
||||
// Notify new messages
|
||||
Core.notify(this, db.message().getUnseenNotify());
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
Core.reportError(this, account, folder, ex);
|
||||
|
|
Loading…
Reference in New Issue