mirror of https://github.com/M66B/FairEmail.git
Read all contacts at startup
This commit is contained in:
parent
01f5e07deb
commit
aa806b7ce4
1
FAQ.md
1
FAQ.md
|
@ -1591,7 +1591,6 @@ About each four hours FairEmail runs a cleanup job that:
|
|||
* Removes old image files
|
||||
* Removes old local contacts
|
||||
* Removes old log entries
|
||||
* Updates contact photos of messages
|
||||
|
||||
You can see when the last cleanup was performed at the bottom of the advanced options.
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import android.media.RingtoneManager;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.DeadSystemException;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.webkit.CookieManager;
|
||||
|
||||
|
@ -91,10 +92,14 @@ public class ApplicationEx extends Application {
|
|||
});
|
||||
|
||||
upgrade(this);
|
||||
|
||||
createNotificationChannels();
|
||||
|
||||
if (Helper.hasWebView(this))
|
||||
CookieManager.getInstance().setAcceptCookie(false);
|
||||
|
||||
MessageHelper.setSystemProperties();
|
||||
ContactInfo.init(this, new Handler());
|
||||
Core.init(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.Manifest;
|
|||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
@ -34,6 +35,7 @@ import android.graphics.PorterDuffXfermode;
|
|||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.TypedValue;
|
||||
|
||||
|
@ -43,6 +45,7 @@ import java.io.InputStream;
|
|||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
|
@ -54,10 +57,10 @@ public class ContactInfo {
|
|||
private Uri lookupUri;
|
||||
private long time;
|
||||
|
||||
private static Map<String, LookupInfo> emailLookupInfo = new HashMap<>();
|
||||
private static Object lock = new Object();
|
||||
private static Map<String, Uri> emailLookup = new ConcurrentHashMap<>();
|
||||
private static Map<String, ContactInfo> emailContactInfo = new HashMap<>();
|
||||
|
||||
private static final long CACHE_LOOKUP_DURATION = 120 * 60 * 1000L;
|
||||
private static final long CACHE_CONTACT_DURATION = 60 * 1000L;
|
||||
|
||||
private ContactInfo() {
|
||||
|
@ -93,9 +96,6 @@ public class ContactInfo {
|
|||
}
|
||||
|
||||
static void clearCache() {
|
||||
synchronized (emailLookupInfo) {
|
||||
emailLookupInfo.clear();
|
||||
}
|
||||
synchronized (emailContactInfo) {
|
||||
emailContactInfo.clear();
|
||||
}
|
||||
|
@ -214,65 +214,62 @@ public class ContactInfo {
|
|||
return info;
|
||||
}
|
||||
|
||||
static void init(final Context context, Handler handler) {
|
||||
if (Helper.hasPermission(context, Manifest.permission.READ_CONTACTS)) {
|
||||
ContentObserver observer = new ContentObserver(handler) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
Log.i("Contact changed uri=" + uri);
|
||||
emailLookup = getEmailLookup(context);
|
||||
}
|
||||
};
|
||||
|
||||
emailLookup = getEmailLookup(context);
|
||||
|
||||
Uri uri = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
|
||||
Log.i("Observing uri=" + uri);
|
||||
context.getContentResolver().registerContentObserver(uri, true, observer);
|
||||
}
|
||||
}
|
||||
|
||||
static Uri getLookupUri(Context context, Address[] addresses) {
|
||||
if (!Helper.hasPermission(context, Manifest.permission.READ_CONTACTS))
|
||||
if (addresses == null)
|
||||
return null;
|
||||
|
||||
if (addresses == null || addresses.length == 0)
|
||||
return null;
|
||||
InternetAddress address = (InternetAddress) addresses[0];
|
||||
|
||||
synchronized (emailLookupInfo) {
|
||||
LookupInfo info = emailLookupInfo.get(address.getAddress());
|
||||
if (info != null && !info.isExpired())
|
||||
return info.uri;
|
||||
for (Address from : addresses) {
|
||||
String email = ((InternetAddress) from).getAddress();
|
||||
if (emailLookup.containsKey(email))
|
||||
return emailLookup.get(email);
|
||||
}
|
||||
|
||||
try {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Map<String, Uri> getEmailLookup(Context context) {
|
||||
Map<String, Uri> all = new ConcurrentHashMap<>();
|
||||
|
||||
if (Helper.hasPermission(context, Manifest.permission.READ_CONTACTS)) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
try (Cursor cursor = resolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
|
||||
new String[]{
|
||||
ContactsContract.CommonDataKinds.Photo.CONTACT_ID,
|
||||
ContactsContract.Contacts.LOOKUP_KEY
|
||||
ContactsContract.Contacts.LOOKUP_KEY,
|
||||
ContactsContract.CommonDataKinds.Email.ADDRESS
|
||||
},
|
||||
ContactsContract.CommonDataKinds.Email.ADDRESS + " = ?",
|
||||
new String[]{
|
||||
address.getAddress()
|
||||
}, null)) {
|
||||
ContactsContract.CommonDataKinds.Email.ADDRESS + " <> ''",
|
||||
null, null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
long contactId = cursor.getLong(0);
|
||||
String lookupKey = cursor.getString(1);
|
||||
String email = cursor.getString(2);
|
||||
|
||||
Uri uri = null;
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
int colContactId = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.CONTACT_ID);
|
||||
int colLookupKey = cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
|
||||
|
||||
long contactId = cursor.getLong(colContactId);
|
||||
String lookupKey = cursor.getString(colLookupKey);
|
||||
|
||||
uri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
|
||||
Uri uri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
|
||||
all.put(email, uri);
|
||||
}
|
||||
|
||||
LookupInfo info = new LookupInfo();
|
||||
info.uri = uri;
|
||||
info.time = new Date().getTime();
|
||||
|
||||
synchronized (emailLookupInfo) {
|
||||
emailLookupInfo.put(address.getAddress(), info);
|
||||
}
|
||||
|
||||
return info.uri;
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class LookupInfo {
|
||||
private Uri uri;
|
||||
private long time;
|
||||
|
||||
private boolean isExpired() {
|
||||
return (new Date().getTime() - time > CACHE_LOOKUP_DURATION);
|
||||
}
|
||||
Log.i("Read email/uri=" + all.size());
|
||||
return all;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1383,6 +1383,14 @@ class Core {
|
|||
Log.i(folder.name + " updated id=" + message.id + " uid=" + message.uid + " unbrowse");
|
||||
}
|
||||
|
||||
Uri uri = ContactInfo.getLookupUri(context, message.from);
|
||||
String avatar = (uri == null ? null : uri.toString());
|
||||
if (!Objects.equals(message.avatar, avatar)) {
|
||||
update = true;
|
||||
message.avatar = avatar;
|
||||
Log.i(folder.name + " updated id=" + message.id + " uid=" + message.uid + " avatar=" + avatar);
|
||||
}
|
||||
|
||||
if (update)
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
|
|
@ -21,7 +21,6 @@ package eu.faircode.email;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -39,7 +38,6 @@ import java.util.Arrays;
|
|||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class WorkerCleanup extends Worker {
|
||||
|
@ -146,33 +144,6 @@ public class WorkerCleanup extends Worker {
|
|||
Log.i("Cleanup log");
|
||||
int logs = db.log().deleteLogs(now - KEEP_LOG_DURATION);
|
||||
Log.i("Deleted logs=" + logs);
|
||||
|
||||
Log.i("Update lookup URIs");
|
||||
ContactInfo.clearCache();
|
||||
List<EntityFolder> folders = db.folder().getSynchronizingFolders();
|
||||
for (EntityFolder folder : folders) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_MONTH, -folder.sync_days);
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||
cal.set(Calendar.MINUTE, 0);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
long sync_time = cal.getTimeInMillis();
|
||||
if (sync_time < 0)
|
||||
sync_time = 0;
|
||||
Log.i("Update lookup URIs " + folder.name + " before " + new Date(sync_time));
|
||||
|
||||
List<TupleMessageLookup> avatars = db.message().getAvatars(folder.id, sync_time);
|
||||
for (TupleMessageLookup message : avatars) {
|
||||
Uri uri = (message.avatar == null ? null : Uri.parse(message.avatar));
|
||||
Uri lookup = ContactInfo.getLookupUri(context, message.from);
|
||||
if (!Objects.equals(uri, lookup)) {
|
||||
Log.i("Updating email=" + MessageHelper.formatAddresses(message.from) + " uri=" + lookup);
|
||||
db.message().setMessageAvatar(message.id, lookup == null ? null : lookup.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.i("Updated lookup URIs");
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
} finally {
|
||||
|
|
Loading…
Reference in New Issue