diff --git a/app/src/main/java/org/linphone/LinphoneLauncherActivity.java b/app/src/main/java/org/linphone/LinphoneLauncherActivity.java index 6929d3c6b..6408a9e5d 100644 --- a/app/src/main/java/org/linphone/LinphoneLauncherActivity.java +++ b/app/src/main/java/org/linphone/LinphoneLauncherActivity.java @@ -72,8 +72,9 @@ public class LinphoneLauncherActivity extends Activity { } else if (Intent.ACTION_VIEW.equals(action)) { if (LinphoneService.isReady()) { mAddressToCall = - ContactsManager.getAddressOrNumberForAndroidContact( - getContentResolver(), intent.getData()); + ContactsManager.getInstance() + .getAddressOrNumberForAndroidContact( + getContentResolver(), intent.getData()); } else { mUriToResolve = intent.getData(); } @@ -143,8 +144,9 @@ public class LinphoneLauncherActivity extends Activity { } if (mUriToResolve != null) { mAddressToCall = - ContactsManager.getAddressOrNumberForAndroidContact( - getContentResolver(), mUriToResolve); + ContactsManager.getInstance() + .getAddressOrNumberForAndroidContact( + getContentResolver(), mUriToResolve); Log.i( "LinphoneLauncher", "Intent has uri to resolve : " + mUriToResolve.toString()); diff --git a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java index 1a4640546..c69ed6d43 100644 --- a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java +++ b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java @@ -40,17 +40,7 @@ import org.linphone.mediastream.Log; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.LinphoneUtils; -class AsyncContactsData { - final List contacts; - final List sipContacts; - - AsyncContactsData() { - contacts = new ArrayList<>(); - sipContacts = new ArrayList<>(); - } -} - -class AsyncContactsLoader extends AsyncTask { +class AsyncContactsLoader extends AsyncTask { @SuppressLint("InlinedApi") private static final String[] PROJECTION = { ContactsContract.Data.CONTACT_ID, @@ -64,7 +54,6 @@ class AsyncContactsLoader extends AsyncTask { }; private Context mContext; - private HashMap mAndroidContactsCache; public AsyncContactsLoader(Context context) { mContext = context; @@ -72,8 +61,6 @@ class AsyncContactsLoader extends AsyncTask { @Override protected void onPreExecute() { - mAndroidContactsCache = new HashMap<>(); - if (mContext == null) { mContext = LinphoneService.instance().getApplicationContext(); } @@ -102,7 +89,10 @@ class AsyncContactsLoader extends AsyncTask { ContactsContract.Data.IN_VISIBLE_GROUP + " == 1", null, null); + + HashMap androidContactsCache = new HashMap<>(); AsyncContactsData data = new AsyncContactsData(); + List nativeIds = new ArrayList<>(); Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); if (lc != null) { @@ -114,7 +104,8 @@ class AsyncContactsLoader extends AsyncTask { if (contact != null) { contact.clearAddresses(); if (contact.getAndroidId() != null) { - mAndroidContactsCache.put(contact.getAndroidId(), contact); + androidContactsCache.put(contact.getAndroidId(), contact); + nativeIds.add(contact.getAndroidId()); } } else { if (friend.getRefKey() != null) { @@ -135,7 +126,6 @@ class AsyncContactsLoader extends AsyncTask { } if (c != null) { - List nativeIds = new ArrayList<>(); while (c.moveToNext()) { if (isCancelled()) return data; @@ -150,15 +140,16 @@ class AsyncContactsLoader extends AsyncTask { String lookupKey = c.getString(c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); - LinphoneContact contact = mAndroidContactsCache.get(id); + LinphoneContact contact = androidContactsCache.get(id); if (contact == null) { nativeIds.add(id); contact = new LinphoneContact(); contact.setAndroidId(id); contact.setAndroidLookupKey(lookupKey); contact.setFullName(displayName); - mAndroidContactsCache.put(id, contact); + androidContactsCache.put(id, contact); } + if (contact.getFullName() == null && displayName != null) { contact.setFullName(displayName); } @@ -188,7 +179,7 @@ class AsyncContactsLoader extends AsyncTask { String id = contact.getAndroidId(); if (id != null && !nativeIds.contains(id)) { // Has been removed since last fetch - mAndroidContactsCache.remove(id); + androidContactsCache.remove(id); } } } @@ -196,7 +187,7 @@ class AsyncContactsLoader extends AsyncTask { nativeIds.clear(); } - for (LinphoneContact contact : mAndroidContactsCache.values()) { + for (LinphoneContact contact : androidContactsCache.values()) { if (isCancelled()) return data; boolean hideContactsWithoutPresence = @@ -233,7 +224,8 @@ class AsyncContactsLoader extends AsyncTask { } data.contacts.add(contact); } - mAndroidContactsCache.clear(); + + androidContactsCache.clear(); Collections.sort(data.contacts); Collections.sort(data.sipContacts); @@ -254,4 +246,14 @@ class AsyncContactsLoader extends AsyncTask { ContactsManager.getInstance().setContacts(data.contacts); ContactsManager.getInstance().setSipContacts(data.sipContacts); } + + class AsyncContactsData { + final List contacts; + final List sipContacts; + + AsyncContactsData() { + contacts = new ArrayList<>(); + sipContacts = new ArrayList<>(); + } + } } diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.java b/app/src/main/java/org/linphone/contacts/ContactsManager.java index 5f31556ca..4bdd37bdb 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.java +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.java @@ -94,60 +94,6 @@ public class ContactsManager extends ContentObserver implements FriendListListen return mContactsUpdatedListeners; } - public static String getAddressOrNumberForAndroidContact( - ContentResolver resolver, Uri contactUri) { - // Phone Numbers - String[] projection = new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER}; - Cursor c = resolver.query(contactUri, projection, null, null, null); - if (c != null) { - if (c.moveToNext()) { - int numberIndex = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); - String number = c.getString(numberIndex); - c.close(); - return number; - } - } - c.close(); - - // SIP addresses - projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS}; - c = resolver.query(contactUri, projection, null, null, null); - if (c != null) { - if (c.moveToNext()) { - int numberIndex = - c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS); - String address = c.getString(numberIndex); - c.close(); - return address; - } - } - c.close(); - return null; - } - - public void destroy() { - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - for (FriendList list : lc.getFriendsLists()) { - list.setListener(null); - } - } - mDefaultAvatar.recycle(); - sInstance = null; - } - - public MagicSearch getMagicSearch() { - return mMagicSearch; - } - - public boolean contactsFetchedOnce() { - return mContactsFetchedOnce; - } - - public Bitmap getDefaultAvatarBitmap() { - return mDefaultAvatar; - } - @Override public void onChange(boolean selfChange) { onChange(selfChange, null); @@ -178,6 +124,72 @@ public class ContactsManager extends ContentObserver implements FriendListListen mSipContacts = c; } + public void destroy() { + Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc != null) { + for (FriendList list : lc.getFriendsLists()) { + list.setListener(null); + } + } + mDefaultAvatar.recycle(); + sInstance = null; + } + + public void fetchContactsAsync() { + if (mLoadContactTask != null) { + mLoadContactTask.cancel(true); + } + mLoadContactTask = new AsyncContactsLoader(mContext); + mContactsFetchedOnce = true; + mLoadContactTask.executeOnExecutor(THREAD_POOL_EXECUTOR); + } + + public void editContact(Context context, LinphoneContact contact, String valueToAdd) { + if (context.getResources().getBoolean(R.bool.use_native_contact_editor)) { + Intent intent = new Intent(Intent.ACTION_EDIT); + Uri contactUri = contact.getAndroidLookupUri(); + intent.setDataAndType(contactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE); + intent.putExtra( + "finishActivityOnSaveCompleted", true); // So after save will go back here + if (valueToAdd != null) { + intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, valueToAdd); + } + context.startActivity(intent); + } else { + LinphoneActivity.instance().editContact(contact, valueToAdd); + } + } + + public void createContact(Context context, String name, String valueToAdd) { + if (context.getResources().getBoolean(R.bool.use_native_contact_editor)) { + Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION); + intent.setType(ContactsContract.RawContacts.CONTENT_TYPE); + intent.putExtra( + "finishActivityOnSaveCompleted", true); // So after save will go back here + if (name != null) { + intent.putExtra(ContactsContract.Intents.Insert.NAME, name); + } + if (valueToAdd != null) { + intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, valueToAdd); + } + context.startActivity(intent); + } else { + LinphoneActivity.instance().addContact(name, valueToAdd); + } + } + + public MagicSearch getMagicSearch() { + return mMagicSearch; + } + + public boolean contactsFetchedOnce() { + return mContactsFetchedOnce; + } + + public Bitmap getDefaultAvatarBitmap() { + return mDefaultAvatar; + } + public List getContacts(String search) { search = search.toLowerCase(Locale.getDefault()); List searchContactsBegin = new ArrayList<>(); @@ -216,11 +228,6 @@ public class ContactsManager extends ContentObserver implements FriendListListen return searchContactsBegin; } - private synchronized void addSipContact(LinphoneContact contact) { - mSipContacts.add(contact); - Collections.sort(mSipContacts); - } - public void enableContactsAccess() { LinphonePreferences.instance().disableFriendsStorage(); } @@ -242,7 +249,9 @@ public class ContactsManager extends ContentObserver implements FriendListListen public boolean isLinphoneContactsPrefered() { ProxyConfig lpc = LinphoneManager.getLc().getDefaultProxyConfig(); return lpc != null - && lpc.getIdentityAddress().getDomain().equals(getString(R.string.default_domain)); + && lpc.getIdentityAddress() + .getDomain() + .equals(mContext.getString(R.string.default_domain)); } public void initializeContactManager(Context context) { @@ -262,7 +271,9 @@ public class ContactsManager extends ContentObserver implements FriendListListen if (accounts != null && accounts.length == 0) { Account newAccount = - new Account(getString(R.string.sync_account_name), activity.getPackageName()); + new Account( + mContext.getString(R.string.sync_account_name), + activity.getPackageName()); try { accountManager.addAccountExplicitly(newAccount, null, null); } catch (Exception e) { @@ -305,10 +316,41 @@ public class ContactsManager extends ContentObserver implements FriendListListen return null; } + public String getAddressOrNumberForAndroidContact(ContentResolver resolver, Uri contactUri) { + // Phone Numbers + String[] projection = new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER}; + Cursor c = resolver.query(contactUri, projection, null, null, null); + if (c != null) { + if (c.moveToNext()) { + int numberIndex = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); + String number = c.getString(numberIndex); + c.close(); + return number; + } + } + c.close(); + + // SIP addresses + projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS}; + c = resolver.query(contactUri, projection, null, null, null); + if (c != null) { + if (c.moveToNext()) { + int numberIndex = + c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS); + String address = c.getString(numberIndex); + c.close(); + return address; + } + } + c.close(); + return null; + } + private synchronized boolean refreshSipContact(Friend lf) { LinphoneContact contact = (LinphoneContact) lf.getUserData(); - if (contact != null && !getSIPContacts().contains(contact)) { - addSipContact(contact); + if (contact != null && !mSipContacts.contains(contact)) { + mSipContacts.add(contact); + Collections.sort(mSipContacts); return true; } return false; @@ -367,49 +409,4 @@ public class ContactsManager extends ContentObserver implements FriendListListen } } } - - public void fetchContactsAsync() { - if (mLoadContactTask != null) { - mLoadContactTask.cancel(true); - } - mLoadContactTask = new AsyncContactsLoader(mContext); - mContactsFetchedOnce = true; - mLoadContactTask.executeOnExecutor(THREAD_POOL_EXECUTOR); - } - - public void editContact(Context context, LinphoneContact contact, String valueToAdd) { - if (context.getResources().getBoolean(R.bool.use_native_contact_editor)) { - Intent intent = new Intent(Intent.ACTION_EDIT); - Uri contactUri = - ContactsContract.Contacts.getLookupUri( - Long.parseLong(contact.getAndroidId()), contact.getAndroidLookupKey()); - intent.setDataAndType(contactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE); - intent.putExtra( - "finishActivityOnSaveCompleted", true); // So after save will go back here - if (valueToAdd != null) { - intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, valueToAdd); - } - context.startActivity(intent); - } else { - LinphoneActivity.instance().editContact(contact, valueToAdd); - } - } - - public void createContact(Context context, String name, String valueToAdd) { - if (context.getResources().getBoolean(R.bool.use_native_contact_editor)) { - Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION); - intent.setType(ContactsContract.RawContacts.CONTENT_TYPE); - intent.putExtra( - "finishActivityOnSaveCompleted", true); // So after save will go back here - if (name != null) { - intent.putExtra(ContactsContract.Intents.Insert.NAME, name); - } - if (valueToAdd != null) { - intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, valueToAdd); - } - context.startActivity(intent); - } else { - LinphoneActivity.instance().addContact(name, valueToAdd); - } - } } diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index 554f6ccfe..e8937bb27 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -703,6 +703,11 @@ public class LinphoneContact implements Serializable, Comparable