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.
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.
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.