Change in the contact search

This commit is contained in:
Erwan Croze 2016-10-13 16:48:06 +02:00
parent 3f77c02fd2
commit b3bfd69348
2 changed files with 109 additions and 93 deletions

View file

@ -58,7 +58,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
private ListView contactsList;
private TextView noSipContact, noContact;
private ImageView allContacts, linphoneContacts, newContact, edit, selectAll, deselectAll, delete, cancel;
private boolean onlyDisplayLinphoneContacts, isEditMode;
private boolean onlyDisplayLinphoneContacts, isEditMode, isSearchMode;
private View allContactsSelected, linphoneContactsSelected;
private LinearLayout editList, topbar;
private int lastKnownPosition;
@ -72,33 +72,33 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mInflater = inflater;
View view = inflater.inflate(R.layout.contacts_list, container, false);
if (getArguments() != null) {
editOnClick = getArguments().getBoolean("EditOnClick");
sipAddressToAdd = getArguments().getString("SipAddress");
onlyDisplayChatAddress = getArguments().getBoolean("ChatAddressOnly");
}
noSipContact = (TextView) view.findViewById(R.id.noSipContact);
noContact = (TextView) view.findViewById(R.id.noContact);
contactsList = (ListView) view.findViewById(R.id.contactsList);
contactsList.setOnItemClickListener(this);
allContacts = (ImageView) view.findViewById(R.id.all_contacts);
allContacts.setOnClickListener(this);
linphoneContacts = (ImageView) view.findViewById(R.id.linphone_contacts);
linphoneContacts.setOnClickListener(this);
allContactsSelected = view.findViewById(R.id.all_contacts_select);
linphoneContactsSelected = view.findViewById(R.id.linphone_contacts_select);
newContact = (ImageView) view.findViewById(R.id.newContact);
newContact.setOnClickListener(this);
newContact.setEnabled(LinphoneManager.getLc().getCallsNb() == 0);
allContacts.setEnabled(onlyDisplayLinphoneContacts);
linphoneContacts.setEnabled(!allContacts.isEnabled());
@ -119,29 +119,29 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
edit = (ImageView) view.findViewById(R.id.edit);
edit.setOnClickListener(this);
clearSearchField = (ImageView) view.findViewById(R.id.clearSearchField);
clearSearchField.setOnClickListener(this);
searchField = (EditText) view.findViewById(R.id.searchField);
searchField.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
searchContacts(searchField.getText().toString());
}
});
contactsFetchInProgress = (ProgressBar) view.findViewById(R.id.contactsFetchInProgress);
contactsFetchInProgress.setVisibility(View.VISIBLE);
@ -224,14 +224,14 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
enabledDeleteButton(false);
isEditMode = true;
}
if (id == R.id.all_contacts) {
onlyDisplayLinphoneContacts = false;
allContactsSelected.setVisibility(View.VISIBLE);
allContacts.setEnabled(false);
linphoneContacts.setEnabled(true);
linphoneContactsSelected.setVisibility(View.INVISIBLE);
}
}
else if (id == R.id.linphone_contacts) {
allContactsSelected.setVisibility(View.INVISIBLE);
linphoneContactsSelected.setVisibility(View.VISIBLE);
@ -255,7 +255,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
if (id == R.id.newContact) {
editConsumed = true;
LinphoneActivity.instance().addContact(null, sipAddressToAdd);
}
}
else if (id == R.id.clearSearchField) {
searchField.setText("");
}
@ -271,7 +271,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
private void removeContacts() {
ArrayList<String> ids = new ArrayList<String>();
int size = contactsList.getAdapter().getCount();
for (int i = size - 1; i >= 0; i--) {
if (contactsList.isItemChecked(i)) {
LinphoneContact contact = (LinphoneContact) contactsList.getAdapter().getItem(i);
@ -283,7 +283,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
}
}
}
ContactsManager.getInstance().deleteMultipleContactsAtOnce(ids);
}
@ -316,6 +316,8 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
}
changeContactsToggle();
isSearchMode = true;
if (onlyDisplayLinphoneContacts) {
contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
contactsList.setAdapter(new ContactsListAdapter(ContactsManager.getInstance().getSIPContacts(search)));
@ -324,10 +326,11 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
contactsList.setAdapter(new ContactsListAdapter(ContactsManager.getInstance().getContacts(search)));
}
}
private void changeContactsAdapter() {
changeContactsToggle();
isSearchMode = false;
noSipContact.setVisibility(View.GONE);
noContact.setVisibility(View.GONE);
contactsList.setVisibility(View.VISIBLE);
@ -344,13 +347,13 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
contactsList.setAdapter(adapter);
edit.setEnabled(true);
}
if (adapter.getCount() > 0) {
contactsFetchInProgress.setVisibility(View.GONE);
}
ContactsManager.getInstance().setLinphoneContactsPrefered(onlyDisplayLinphoneContacts);
}
private void changeContactsToggle() {
if (onlyDisplayLinphoneContacts) {
allContacts.setEnabled(true);
@ -376,7 +379,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
LinphoneActivity.instance().displayContact(contact, onlyDisplayChatAddress);
}
}
@Override
public void onResume() {
ContactsManager.addContactsListener(this);
@ -395,18 +398,18 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
changeContactsToggle();
invalidate();
}
@Override
public void onPause() {
ContactsManager.removeContactsListener(this);
super.onPause();
}
@Override
public void onContactsUpdated() {
invalidate();
}
public void invalidate() {
if (searchField != null && searchField.getText().toString().length() > 0) {
searchContacts(searchField.getText().toString());
@ -415,7 +418,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
}
contactsList.setSelectionFromTop(lastKnownPosition, 0);
}
class ContactsListAdapter extends BaseAdapter implements SectionIndexer {
private class ViewHolder {
public CheckBox delete;
@ -426,7 +429,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
public ImageView contactPicture;
public TextView organization;
//public ImageView friendStatus;
public ViewHolder(View view) {
delete = (CheckBox) view.findViewById(R.id.delete);
linphoneFriend = (ImageView) view.findViewById(R.id.friendLinphone);
@ -438,15 +441,15 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
//friendStatus = (ImageView) view.findViewById(R.id.friendStatus);
}
}
private List<LinphoneContact> contacts;
String[] sections;
ArrayList<String> sectionsList;
Map<String, Integer>map = new LinkedHashMap<String, Integer>();
ContactsListAdapter(List<LinphoneContact> contactsList) {
contacts = contactsList;
map = new LinkedHashMap<String, Integer>();
String prevLetter = null;
for (int i = 0; i < contacts.size(); i++) {
@ -465,7 +468,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
sections = new String[sectionsList.size()];
sectionsList.toArray(sections);
}
public int getCount() {
return contacts.size();
}
@ -483,7 +486,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
View view = null;
LinphoneContact contact = (LinphoneContact) getItem(position);
if (contact == null) return null;
ViewHolder holder = null;
if (convertView != null) {
view = convertView;
@ -493,17 +496,21 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
holder = new ViewHolder(view);
view.setTag(holder);
}
holder.name.setText(contact.getFullName());
if (getPositionForSection(getSectionForPosition(position)) != position) {
holder.separator.setVisibility(View.GONE);
} else {
holder.separator.setVisibility(View.VISIBLE);
String fullName = contact.getFullName();
if (fullName != null && !fullName.isEmpty()) {
holder.separatorText.setText(String.valueOf(fullName.charAt(0)));
if (!isSearchMode) {
if (getPositionForSection(getSectionForPosition(position)) != position) {
holder.separator.setVisibility(View.GONE);
} else {
holder.separator.setVisibility(View.VISIBLE);
String fullName = contact.getFullName();
if (fullName != null && !fullName.isEmpty()) {
holder.separatorText.setText(String.valueOf(fullName.charAt(0)));
}
}
} else {
holder.separator.setVisibility(View.GONE);
}
if (contact.isInLinphoneFriendList()) {
@ -522,7 +529,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
} else {
holder.contactPicture.setImageResource(R.drawable.avatar);
}
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
String org = contact.getOrganization();
if (org != null && !org.isEmpty() && isOrgVisible) {
@ -563,7 +570,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
} else {
holder.delete.setVisibility(View.GONE);
}
/*LinphoneFriend[] friends = LinphoneManager.getLc().getFriendList();
if (!ContactsManager.getInstance().isContactPresenceDisabled() && friends != null) {
holder.friendStatus.setVisibility(View.VISIBLE);
@ -580,7 +587,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
holder.friendStatus.setImageResource(R.drawable.call_quality_indicator_0);
}
}*/
return view;
}

View file

@ -59,7 +59,7 @@ public class ContactsManager extends ContentObserver {
private ContentResolver contentResolver;
private Context context;
private ContactsFetchTask contactsFetchTask;
private static ArrayList<ContactsUpdatedListener> contactsUpdatedListeners;
public static void addContactsListener(ContactsUpdatedListener listener) {
contactsUpdatedListeners.add(listener);
@ -67,11 +67,11 @@ public class ContactsManager extends ContentObserver {
public static void removeContactsListener(ContactsUpdatedListener listener) {
contactsUpdatedListeners.remove(listener);
}
private static Handler handler = new Handler() {
@Override
public void handleMessage (Message msg) {
}
};
@ -81,24 +81,24 @@ public class ContactsManager extends ContentObserver {
contacts = new ArrayList<LinphoneContact>();
sipContacts = new ArrayList<LinphoneContact>();
}
public void destroy() {
if (contactsFetchTask != null && !contactsFetchTask.isCancelled()) {
contactsFetchTask.cancel(true);
}
instance = null;
}
@Override
public void onChange(boolean selfChange) {
onChange(selfChange, null);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
fetchContactsAsync();
}
public ContentResolver getContentResolver() {
return contentResolver;
}
@ -107,49 +107,58 @@ public class ContactsManager extends ContentObserver {
if (instance == null) instance = new ContactsManager(handler);
return instance;
}
public synchronized boolean hasContacts() {
return contacts.size() > 0;
}
public synchronized List<LinphoneContact> getContacts() {
return contacts;
}
public synchronized List<LinphoneContact> getSIPContacts() {
setContacts(contacts);
return sipContacts;
}
public synchronized List<LinphoneContact> getContacts(String search) {
search = search.toLowerCase(Locale.getDefault());
List<LinphoneContact> searchContacts = new ArrayList<LinphoneContact>();
List<LinphoneContact> searchContactsBegin = new ArrayList<LinphoneContact>();
List<LinphoneContact> searchContactsContain = new ArrayList<LinphoneContact>();
for (LinphoneContact contact : contacts) {
if (contact.getFullName() != null) {
if (contact.getFullName().toLowerCase(Locale.getDefault()).contains(search)) {
searchContacts.add(contact);
if (contact.getFullName().toLowerCase(Locale.getDefault()).startsWith(search)) {
searchContactsBegin.add(contact);
} else if (contact.getFullName().toLowerCase(Locale.getDefault()).contains(search)) {
searchContactsContain.add(contact);
}
}
}
return searchContacts;
searchContactsBegin.addAll(searchContactsContain);
return searchContactsBegin;
}
public synchronized List<LinphoneContact> getSIPContacts(String search) {
search = search.toLowerCase(Locale.getDefault());
List<LinphoneContact> searchContacts = new ArrayList<LinphoneContact>();
List<LinphoneContact> searchContactsBegin = new ArrayList<LinphoneContact>();
List<LinphoneContact> searchContactsContain = new ArrayList<LinphoneContact>();
for (LinphoneContact contact : sipContacts) {
if (contact.getFullName() != null) {
if (contact.getFullName().toLowerCase(Locale.getDefault()).contains(search)) {
searchContacts.add(contact);
if (contact.getFullName().toLowerCase(Locale.getDefault()).startsWith(search)) {
searchContactsBegin.add(contact);
} else if (contact.getFullName().toLowerCase(Locale.getDefault()).contains(search)) {
searchContactsContain.add(contact);
}
}
}
return searchContacts;
searchContactsBegin.addAll(searchContactsContain);
return searchContactsBegin;
}
public void enableContactsAccess() {
hasContactAccess = true;
}
public boolean hasContactsAccess() {
return hasContactAccess && !context.getResources().getBoolean(R.bool.force_use_of_linphone_friends);
}
@ -187,17 +196,17 @@ public class ContactsManager extends ContentObserver {
}
initializeContactManager(context, contentResolver);
}
public LinphoneContact findContactFromAddress(LinphoneAddress address) {
String sipUri = address.asStringUriOnly();
String username = address.getUserName();
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
LinphoneProxyConfig lpc = null;
if (lc != null) {
lpc = lc.getDefaultProxyConfig();
}
for (LinphoneContact c: getContacts()) {
for (LinphoneNumberOrAddress noa: c.getNumbersOrAddresses()) {
String normalized = null;
@ -205,7 +214,7 @@ public class ContactsManager extends ContentObserver {
normalized = lpc.normalizePhoneNumber(noa.getValue());
}
String alias = c.getPresenceModelForUri(noa.getValue());
if ((noa.isSIPAddress() && noa.getValue().equals(sipUri)) || (alias != null && alias.equals(sipUri)) || (normalized != null && !noa.isSIPAddress() && normalized.equals(username)) || (!noa.isSIPAddress() && noa.getValue().equals(username))) {
return c;
}
@ -213,14 +222,14 @@ public class ContactsManager extends ContentObserver {
}
return null;
}
public LinphoneContact findContactFromPhoneNumber(String phoneNumber) {
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
LinphoneProxyConfig lpc = null;
if (lc != null) {
lpc = lc.getDefaultProxyConfig();
}
for (LinphoneContact c: getContacts()) {
for (LinphoneNumberOrAddress noa: c.getNumbersOrAddresses()) {
String normalized = null;
@ -234,7 +243,7 @@ public class ContactsManager extends ContentObserver {
}
return null;
}
public synchronized void setContacts(List<LinphoneContact> c) {
contacts = c;
sipContacts = new ArrayList<LinphoneContact>();
@ -244,7 +253,7 @@ public class ContactsManager extends ContentObserver {
}
}
}
public synchronized void fetchContactsAsync() {
if (contactsFetchTask != null && !contactsFetchTask.isCancelled()) {
contactsFetchTask.cancel(true);
@ -252,12 +261,12 @@ public class ContactsManager extends ContentObserver {
contactsFetchTask = new ContactsFetchTask();
contactsFetchTask.execute();
}
private class ContactsFetchTask extends AsyncTask<Void, List<LinphoneContact>, List<LinphoneContact>> {
@SuppressWarnings("unchecked")
protected List<LinphoneContact> doInBackground(Void... params) {
List<LinphoneContact> contacts = new ArrayList<LinphoneContact>();
if (hasContactsAccess()) {
Cursor c = getContactsCursor(contentResolver);
if (c != null) {
@ -312,7 +321,7 @@ public class ContactsManager extends ContentObserver {
contact.minimalRefresh();
}
Collections.sort(contacts);
// Public the current list of contacts without all the informations populated
publishProgress(contacts);
@ -320,17 +329,17 @@ public class ContactsManager extends ContentObserver {
// This time fetch all informations including phone numbers and SIP addresses
contact.refresh();
}
return contacts;
}
protected void onProgressUpdate(List<LinphoneContact>... result) {
setContacts(result[0]);
for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
listener.onContactsUpdated();
}
}
protected void onPostExecute(List<LinphoneContact> result) {
setContacts(result);
for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
@ -338,7 +347,7 @@ public class ContactsManager extends ContentObserver {
}
}
}
public static String getAddressOrNumberForAndroidContact(ContentResolver resolver, Uri contactUri) {
// Phone Numbers
String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER };
@ -366,17 +375,17 @@ public class ContactsManager extends ContentObserver {
}
return null;
}
public void delete(String id) {
ArrayList<String> ids = new ArrayList<String>();
ids.add(id);
deleteMultipleContactsAtOnce(ids);
}
public void deleteMultipleContactsAtOnce(List<String> ids) {
String select = ContactsContract.Data.CONTACT_ID + " = ?";
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
for (String id : ids) {
String[] args = new String[] { id };
ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI).withSelection(select, args).build());
@ -389,11 +398,11 @@ public class ContactsManager extends ContentObserver {
Log.e(e);
}
}
public String getString(int resourceID) {
return context.getString(resourceID);
}
private Cursor getContactsCursor(ContentResolver cr) {
String req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE
+ "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL "
@ -406,7 +415,7 @@ public class ContactsManager extends ContentObserver {
if (cursor == null) {
return cursor;
}
MatrixCursor result = new MatrixCursor(cursor.getColumnNames());
Set<String> groupBy = new HashSet<String>();
while (cursor.moveToNext()) {
@ -414,13 +423,13 @@ public class ContactsManager extends ContentObserver {
if (!groupBy.contains(name)) {
groupBy.add(name);
Object[] newRow = new Object[cursor.getColumnCount()];
int contactID = cursor.getColumnIndex(Data.CONTACT_ID);
int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME);
newRow[contactID] = cursor.getString(contactID);
newRow[displayName] = cursor.getString(displayName);
result.addRow(newRow);
}
}