Now that contacts loading are lightning fast, stop fetching them from async task + fixed contacts refreshing when rotating device
This commit is contained in:
parent
90a013dece
commit
234983f0af
3 changed files with 153 additions and 213 deletions
|
@ -48,7 +48,6 @@ import android.database.MatrixCursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
|
@ -60,13 +59,12 @@ interface ContactsUpdatedListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ContactsManager extends ContentObserver {
|
public class ContactsManager extends ContentObserver {
|
||||||
public static int CONTACTS_STEP = 15;
|
|
||||||
private static ContactsManager instance;
|
private static ContactsManager instance;
|
||||||
|
|
||||||
private List<LinphoneContact> contacts, sipContacts;
|
private List<LinphoneContact> contacts, sipContacts;
|
||||||
private boolean preferLinphoneContacts = false, isContactPresenceDisabled = true, hasContactAccess = false;
|
private boolean preferLinphoneContacts = false, isContactPresenceDisabled = true, hasContactAccess = false;
|
||||||
private ContentResolver contentResolver;
|
private ContentResolver contentResolver;
|
||||||
private Context context;
|
private Context context;
|
||||||
private ContactsFetchTask contactsFetchTask;
|
|
||||||
private HashMap<String, LinphoneContact> contactsCache;
|
private HashMap<String, LinphoneContact> contactsCache;
|
||||||
private HashMap<String, LinphoneContact> androidContactsCache;
|
private HashMap<String, LinphoneContact> androidContactsCache;
|
||||||
private LinphoneContact contactNotFound;
|
private LinphoneContact contactNotFound;
|
||||||
|
@ -99,13 +97,13 @@ public class ContactsManager extends ContentObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
if (contactsFetchTask != null && !contactsFetchTask.isCancelled()) {
|
|
||||||
contactsFetchTask.cancel(true);
|
|
||||||
}
|
|
||||||
defaultAvatar.recycle();
|
defaultAvatar.recycle();
|
||||||
instance = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean contactsFetchedOnce() {
|
||||||
|
return contacts.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public Bitmap getDefaultAvatarBitmap() {
|
public Bitmap getDefaultAvatarBitmap() {
|
||||||
return defaultAvatar;
|
return defaultAvatar;
|
||||||
|
@ -118,31 +116,31 @@ public class ContactsManager extends ContentObserver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange, Uri uri) {
|
public void onChange(boolean selfChange, Uri uri) {
|
||||||
fetchContactsAsync();
|
fetchContactsSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentResolver getContentResolver() {
|
public ContentResolver getContentResolver() {
|
||||||
return contentResolver;
|
return contentResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final synchronized ContactsManager getInstance() {
|
public static final ContactsManager getInstance() {
|
||||||
if (instance == null) instance = new ContactsManager(handler);
|
if (instance == null) instance = new ContactsManager(handler);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean hasContacts() {
|
public boolean hasContacts() {
|
||||||
return contacts.size() > 0;
|
return contacts.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized List<LinphoneContact> getContacts() {
|
public List<LinphoneContact> getContacts() {
|
||||||
return contacts;
|
return contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized List<LinphoneContact> getSIPContacts() {
|
public List<LinphoneContact> getSIPContacts() {
|
||||||
return sipContacts;
|
return sipContacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized List<LinphoneContact> getContacts(String search) {
|
public List<LinphoneContact> getContacts(String search) {
|
||||||
search = search.toLowerCase(Locale.getDefault());
|
search = search.toLowerCase(Locale.getDefault());
|
||||||
List<LinphoneContact> searchContactsBegin = new ArrayList<LinphoneContact>();
|
List<LinphoneContact> searchContactsBegin = new ArrayList<LinphoneContact>();
|
||||||
List<LinphoneContact> searchContactsContain = new ArrayList<LinphoneContact>();
|
List<LinphoneContact> searchContactsContain = new ArrayList<LinphoneContact>();
|
||||||
|
@ -159,7 +157,7 @@ public class ContactsManager extends ContentObserver {
|
||||||
return searchContactsBegin;
|
return searchContactsBegin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized List<LinphoneContact> getSIPContacts(String search) {
|
public List<LinphoneContact> getSIPContacts(String search) {
|
||||||
search = search.toLowerCase(Locale.getDefault());
|
search = search.toLowerCase(Locale.getDefault());
|
||||||
List<LinphoneContact> searchContactsBegin = new ArrayList<LinphoneContact>();
|
List<LinphoneContact> searchContactsBegin = new ArrayList<LinphoneContact>();
|
||||||
List<LinphoneContact> searchContactsContain = new ArrayList<LinphoneContact>();
|
List<LinphoneContact> searchContactsContain = new ArrayList<LinphoneContact>();
|
||||||
|
@ -223,7 +221,7 @@ public class ContactsManager extends ContentObserver {
|
||||||
initializeContactManager(context, contentResolver);
|
initializeContactManager(context, contentResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized LinphoneContact findContactFromAddress(LinphoneAddress address) {
|
public LinphoneContact findContactFromAddress(LinphoneAddress address) {
|
||||||
String sipUri = address.asStringUriOnly();
|
String sipUri = address.asStringUriOnly();
|
||||||
String username = address.getUserName();
|
String username = address.getUserName();
|
||||||
|
|
||||||
|
@ -257,7 +255,7 @@ public class ContactsManager extends ContentObserver {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized LinphoneContact findContactFromPhoneNumber(String phoneNumber) {
|
public LinphoneContact findContactFromPhoneNumber(String phoneNumber) {
|
||||||
LinphoneContact cache = contactsCache.get(phoneNumber);
|
LinphoneContact cache = contactsCache.get(phoneNumber);
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
if (cache == contactNotFound) return null;
|
if (cache == contactNotFound) return null;
|
||||||
|
@ -286,15 +284,15 @@ public class ContactsManager extends ContentObserver {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setContacts(List<LinphoneContact> c) {
|
public void setContacts(List<LinphoneContact> c) {
|
||||||
contacts = c;
|
contacts = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setSipContacts(List<LinphoneContact> c) {
|
public void setSipContacts(List<LinphoneContact> c) {
|
||||||
sipContacts = c;
|
sipContacts = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void refreshSipContact(LinphoneFriend lf) {
|
public void refreshSipContact(LinphoneFriend lf) {
|
||||||
LinphoneContact contact = (LinphoneContact)((LinphoneFriendImpl)lf).getUserData();
|
LinphoneContact contact = (LinphoneContact)((LinphoneFriendImpl)lf).getUserData();
|
||||||
if (!sipContacts.contains(contact)) {
|
if (!sipContacts.contains(contact)) {
|
||||||
sipContacts.add(contact);
|
sipContacts.add(contact);
|
||||||
|
@ -306,36 +304,12 @@ public class ContactsManager extends ContentObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void fetchContactsAsync() {
|
public void fetchContactsSync() {
|
||||||
if (contactsFetchTask != null && !contactsFetchTask.isCancelled()) {
|
|
||||||
contactsFetchTask.cancel(true);
|
|
||||||
}
|
|
||||||
contactsFetchTask = new ContactsFetchTask();
|
|
||||||
contactsFetchTask.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ContactsLists {
|
|
||||||
public List<LinphoneContact> contacts;
|
|
||||||
public List<LinphoneContact> sipContacts;
|
|
||||||
|
|
||||||
public ContactsLists(List<LinphoneContact> c, List<LinphoneContact> s) {
|
|
||||||
contacts = c;
|
|
||||||
sipContacts = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ContactsFetchTask extends AsyncTask<Void, ContactsLists, ContactsLists> {
|
|
||||||
protected ContactsLists doInBackground(Void... params) {
|
|
||||||
List<LinphoneContact> contacts = new ArrayList<LinphoneContact>();
|
List<LinphoneContact> contacts = new ArrayList<LinphoneContact>();
|
||||||
List<LinphoneContact> sipContacts = new ArrayList<LinphoneContact>();
|
List<LinphoneContact> sipContacts = new ArrayList<LinphoneContact>();
|
||||||
Date contactsTime = new Date();
|
Date contactsTime = new Date();
|
||||||
androidContactsCache.clear();
|
androidContactsCache.clear();
|
||||||
|
|
||||||
//We need to check sometimes to know if Linphone was destroyed
|
|
||||||
if (this.isCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasContactsAccess()) {
|
if (hasContactsAccess()) {
|
||||||
Cursor c = getContactsCursor(contentResolver);
|
Cursor c = getContactsCursor(contentResolver);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
|
@ -378,10 +352,6 @@ public class ContactsManager extends ContentObserver {
|
||||||
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeElapsed)));
|
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeElapsed)));
|
||||||
Log.i("[ContactsManager] Step 1 for " + contacts.size() + " contacts executed in " + time);
|
Log.i("[ContactsManager] Step 1 for " + contacts.size() + " contacts executed in " + time);
|
||||||
|
|
||||||
//We need to check sometimes to know if Linphone was destroyed
|
|
||||||
if (this.isCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
if (lc != null) {
|
if (lc != null) {
|
||||||
for (LinphoneFriend friend : lc.getFriendList()) {
|
for (LinphoneFriend friend : lc.getFriendList()) {
|
||||||
|
@ -426,14 +396,6 @@ public class ContactsManager extends ContentObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(contacts);
|
|
||||||
Collections.sort(sipContacts);
|
|
||||||
publishProgress(new ContactsLists(contacts, sipContacts));
|
|
||||||
|
|
||||||
//We need to check sometimes to know if Linphone was destroyed
|
|
||||||
if (this.isCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasContactsAccess()) {
|
if (hasContactsAccess()) {
|
||||||
Cursor c = getPhonesCursor(contentResolver);
|
Cursor c = getPhonesCursor(contentResolver);
|
||||||
|
@ -463,9 +425,7 @@ public class ContactsManager extends ContentObserver {
|
||||||
}
|
}
|
||||||
c.close();
|
c.close();
|
||||||
}
|
}
|
||||||
Collections.sort(sipContacts);
|
|
||||||
}
|
}
|
||||||
publishProgress(new ContactsLists(contacts, sipContacts));
|
|
||||||
|
|
||||||
timeElapsed = (new Date()).getTime() - contactsTime.getTime();
|
timeElapsed = (new Date()).getTime() - contactsTime.getTime();
|
||||||
time = String.format("%02d:%02d",
|
time = String.format("%02d:%02d",
|
||||||
|
@ -475,10 +435,6 @@ public class ContactsManager extends ContentObserver {
|
||||||
Log.i("[ContactsManager] Step 2 for " + contacts.size() + " contacts executed in " + time);
|
Log.i("[ContactsManager] Step 2 for " + contacts.size() + " contacts executed in " + time);
|
||||||
|
|
||||||
for (LinphoneContact contact : contacts) {
|
for (LinphoneContact contact : contacts) {
|
||||||
//We need to check sometimes to know if Linphone was destroyed
|
|
||||||
if (this.isCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Create the LinphoneFriends matching the native contacts
|
// Create the LinphoneFriends matching the native contacts
|
||||||
contact.createOrUpdateLinphoneFriendFromNativeContact();
|
contact.createOrUpdateLinphoneFriendFromNativeContact();
|
||||||
}
|
}
|
||||||
|
@ -490,28 +446,17 @@ public class ContactsManager extends ContentObserver {
|
||||||
Log.i("[ContactsManager] Step 3 for " + contacts.size() + " contacts executed in " + time);
|
Log.i("[ContactsManager] Step 3 for " + contacts.size() + " contacts executed in " + time);
|
||||||
|
|
||||||
androidContactsCache.clear();
|
androidContactsCache.clear();
|
||||||
return new ContactsLists(contacts, sipContacts);
|
Collections.sort(contacts);
|
||||||
}
|
Collections.sort(sipContacts);
|
||||||
|
setContacts(contacts);
|
||||||
protected void onProgressUpdate(ContactsLists... result) {
|
setSipContacts(sipContacts);
|
||||||
synchronized (ContactsManager.this) {
|
|
||||||
setContacts(result[0].contacts);
|
|
||||||
setSipContacts(result[0].sipContacts);
|
|
||||||
contactsCache.clear();
|
contactsCache.clear();
|
||||||
for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
|
|
||||||
listener.onContactsUpdated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPostExecute(ContactsLists result) {
|
|
||||||
Log.d("[ContactsManager] Updating contacts subscribtions");
|
|
||||||
LinphoneManager.getLc().getFriendLists()[0].updateSubscriptions();
|
LinphoneManager.getLc().getFriendLists()[0].updateSubscriptions();
|
||||||
for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
|
for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
|
||||||
listener.onContactsUpdated();
|
listener.onContactsUpdated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAddressOrNumberForAndroidContact(ContentResolver resolver, Uri contactUri) {
|
public static String getAddressOrNumberForAndroidContact(ContentResolver resolver, Uri contactUri) {
|
||||||
// Phone Numbers
|
// Phone Numbers
|
||||||
|
|
|
@ -133,7 +133,6 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
private RelativeLayout sideMenuContent, quitLayout, defaultAccount;
|
private RelativeLayout sideMenuContent, quitLayout, defaultAccount;
|
||||||
private ListView accountsList, sideMenuItemList;
|
private ListView accountsList, sideMenuItemList;
|
||||||
private ImageView menu;
|
private ImageView menu;
|
||||||
private boolean fetchedContactsOnce = false;
|
|
||||||
private boolean doNotGoToCallActivity = false;
|
private boolean doNotGoToCallActivity = false;
|
||||||
private List<String> sideMenuItems;
|
private List<String> sideMenuItems;
|
||||||
private boolean callTransfer = false;
|
private boolean callTransfer = false;
|
||||||
|
@ -1264,10 +1263,9 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
}
|
}
|
||||||
if (readContactsI >= 0 && grantResults[readContactsI] == PackageManager.PERMISSION_GRANTED) {
|
if (readContactsI >= 0 && grantResults[readContactsI] == PackageManager.PERMISSION_GRANTED) {
|
||||||
ContactsManager.getInstance().enableContactsAccess();
|
ContactsManager.getInstance().enableContactsAccess();
|
||||||
if (!fetchedContactsOnce) {
|
if (!ContactsManager.getInstance().contactsFetchedOnce()) {
|
||||||
ContactsManager.getInstance().enableContactsAccess();
|
ContactsManager.getInstance().enableContactsAccess();
|
||||||
ContactsManager.getInstance().fetchContactsAsync();
|
ContactsManager.getInstance().fetchContactsSync();
|
||||||
fetchedContactsOnce = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1304,10 +1302,9 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
permissionsList.add(Manifest.permission.READ_CONTACTS);
|
permissionsList.add(Manifest.permission.READ_CONTACTS);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!fetchedContactsOnce) {
|
if (!ContactsManager.getInstance().contactsFetchedOnce()) {
|
||||||
ContactsManager.getInstance().enableContactsAccess();
|
ContactsManager.getInstance().enableContactsAccess();
|
||||||
ContactsManager.getInstance().fetchContactsAsync();
|
ContactsManager.getInstance().fetchContactsSync();
|
||||||
fetchedContactsOnce = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1321,14 +1318,12 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
@Override
|
@Override
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
outState.putSerializable("currentFragment", currentFragment);
|
outState.putSerializable("currentFragment", currentFragment);
|
||||||
outState.putBoolean("fetchedContactsOnce", fetchedContactsOnce);
|
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||||
super.onRestoreInstanceState(savedInstanceState);
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
fetchedContactsOnce = savedInstanceState.getBoolean("fetchedContactsOnce");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -463,7 +463,7 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
if (!ContactsManager.getInstance().hasContactsAccess()) {
|
if (!ContactsManager.getInstance().hasContactsAccess()) {
|
||||||
// This refresh is only needed if app has no contacts permission to refresh the list of LinphoneFriends.
|
// This refresh is only needed if app has no contacts permission to refresh the list of LinphoneFriends.
|
||||||
// Otherwise contacts will be refreshed due to changes in native contact and the handler in ContactsManager
|
// Otherwise contacts will be refreshed due to changes in native contact and the handler in ContactsManager
|
||||||
ContactsManager.getInstance().fetchContactsAsync();
|
ContactsManager.getInstance().fetchContactsSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue