I need to get a distinct list of all contacts from a device and their phone numbers. But wait... We know that some contacts may have multiple numbers assigned, it all depends how each of the users stores his contacts. Here is what i do:
ContentResolver cr = context.getContentResolver();
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME };
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'";
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
ArrayList<user> contacts = new ArrayList<user>();
Cursor users = a.managedQuery(uri, projection, selection, null, sortOrder);
while (users.moveToNext()) {
user u = new user();
u.PhoneId = users.getInt(users.getColumnIndex(ContactsContract.Contacts._ID));
u.Name = users.getString(users.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String homePhone = "", cellPhone = "", workPhone = "", otherPhone = "";
Cursor contactPhones = cr.query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + " = " + u.PhoneId, null, null);
while (contactPhones.moveToNext()) {
String number = contactPhones.getString(contactPhones.getColumnIndex(Phone.NUMBER));
int type = contactPhones.getInt(contactPhones.getColumnIndex(Phone.TYPE));
switch (type) {
case Phone.TYPE_HOME: homePhone = number; break;
case Phone.TYPE_MOBILE: cellPhone = number; break;
case Phone.TYPE_WORK: workPhone = number; break;
case Phone.TYPE_OTHER: otherPhone = number; break;
}
}
u.Phone = ((cellPhone!="") ? cellPhone : ((homePhone!="") ? homePhone : ((workPhone!="") ? workPhone : otherPhone)));
}
return contacts;
The process works but for my 80 contacts it takes between 1000-2000 miliseconds, and i need to work much faster :)
Cursor contactPhones = cr.query(Phone.CONTENT_URI, null,
Phone.CONTACT_ID + " = " + u.PhoneId,
null,
null);
This is slightly sub-optimal in that you are encoding the contact ID field directly in the query, rather than making it an argument. This means that the query parser has to re-parse the query each time, rather than being able to use a single cached copy.
Supply the ID as an argument instead:
Cursor contactPhones = cr.query(Phone.CONTENT_URI, null,
Phone.CONTACT_ID + " =? ",
new String[] { Integer.toString(u.PhoneId) },
null);
The javadoc for ContentResolver.query()
reiterates this guidance:
Use question mark parameter markers such as 'phone=?' instead of explicit values in the selection parameter, so that queries that differ only by those values will be recognized as the same for caching purposes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With