I\'m working on Android 2.0 and am trying to receive a list of all contacts.
Since android.provider.Contacts.People is deprecated, I have to use android
Great to see some useful info, it is frustrating how poorly this important topic is covered by docs and such. After too much hacking about I thought I would share a little code also. The following code is a little prettier and get the same thing done more efficiently.
Uri contactUri = ContactsContract.Contacts.CONTENT_URI;
String[] PROJECTION = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
};
String SELECTION = ContactsContract.Contacts.HAS_PHONE_NUMBER + "='1'";
Cursor contacts = managedQuery(contactUri, PROJECTION, SELECTION, null, null );
The above chunk of code returns a Cursor that points to the resulting query that only contains those rows that have a phone number. This is nice since you typically have many contacts without numbers. Furthermore, the PROJECTION limits the amount of data that is returned.
String key, value, phoneNumber;
Hashtable contactPhoneInfo = new Hashtable();
Uri phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String [] PHONES_PROJECTION = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER };
String PHONE_SELECTION = null;
contacts.moveToFirst();
do{
long contactId = contacts.getLong(idColumnIndex);
PHONE_SELECTION = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId;
Cursor phones = managedQuery(phoneUri,
PHONES_PROJECTION,
null,
null,
ContactsContract.CommonDataKinds.Phone.IS_SUPER_PRIMARY + " DESC");
phones.moveToFirst();
key = phones.getString(0).replaceAll("\\D", "");
value = contacts.getString(nameColumnIndex);
contactPhoneInfo.put(key, value);
}while(contacts.moveToNext());
contacts.close();
}
The above chunk gets the phone number associated with each contact id that has a phone number. I store all the info in a hash table and with a key value of the phone number. I stripped the phone number of all none digit info also. For some reason even though ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER is valid if you include that in the projection argument it breaks the query, I don't know why and it is frustrating that it does.
The second part of the code above is too slow, all the query calls just bog everything down. The following code is much faster. Just grab all the rows for the phone content and use the contact_ids to sort the data you want.
Cursor phones = managedQuery(phoneUri,
PHONES_PROJECTION,
PHONE_SELECTION,
null,
ContactsContract.CommonDataKinds.Phone.IS_SUPER_PRIMARY + " DESC");
contacts.moveToFirst();
do{
value = "";
key = contacts.getString(idColumnIndex);
contactPhoneInfo.put(key, value);
}while(contacts.moveToNext());
phones.moveToFirst();
Set keySet = contactPhoneInfo.keySet();
idColumnIndex = phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
int numColumnIndex = phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
do{
key = phones.getString(idColumnIndex);
if(keySet.contains(key)){
value = phones.getString(numColumnIndex).replaceAll("\\D", "");
contactPhoneInfo.put(key, value);
}
}while(phones.moveToNext());
You end up with a hashtable with all the info you want in it. Of course you could put whatever info you want into the data structure. The second way of doing it is much much faster.