1

I'm trying to retrieve both the display names and the phone numbers of all my contacts but I want it to return only the rows that have a number.

Currently I have it like this and it works:

ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,null, null, ContactsContract.Contacts.DISPLAY_NAME+ " COLLATE NOCASE");
while (cur.moveToNext()) 
{           
    if ( Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
    {
                        String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                        String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));                    
                        contacts[index] = name;                                 

                        Cursor pCur = cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
                        pCur.moveToFirst();                                 
                        numbers[index] = pCur.getString( pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        index++;
                        pCur.close();
        }

The thing is that it takes something like 4-5 seconds to load as it is running the cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null); like 400 times.


Now my understanding is that the name and number of a contact are held in different tables and you need the id of the name in order to get the number.

Can this be done in any other way faster?

Thanks in advance

mixkat
  • 3,883
  • 10
  • 40
  • 58

2 Answers2

5

@mixkat I have figured out one more solution.

It is possible to get Name and Phone data using just one query.

Here is the code:

    String WHERE_CONDITION = ContactsContract.Data.MIMETYPE + " = '" +   ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'";
    String[] PROJECTION = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.DATA1};
    String SORT_ORDER = ContactsContract.Data.DISPLAY_NAME;

    Cursor cur = context.getContentResolver().query(
            ContactsContract.Data.CONTENT_URI,
            PROJECTION,
            WHERE_CONDITION,
            null,
            SORT_ORDER);

In this case you query not Contact provider but Data provider directly.

Maxim
  • 2,996
  • 17
  • 19
  • @Maxim Thanks for answering an old thread!Are you sure bout that? – mixkat Apr 28 '11 at 14:42
  • @mixkat I think so. The cursor has two columns. [0] - Display name [1] - phone number. I checked it works for me. – Maxim Apr 28 '11 at 14:54
  • @Maxim For me it returns the same number for all the contacts! – mixkat Apr 28 '11 at 15:11
  • @Maxim How do you deal with multiple entries under the same contact? – mixkat Apr 28 '11 at 15:19
  • @mixkat it depends on what you want to have. I need only one number so I make array and delete all items with repeat names (better to add contact_id field in projection and delete items with same contact_id). If you want to structure all contact's phones you can build more complicated structure. It will take less time than 400 queries to content provider (for every contact) – Maxim Apr 28 '11 at 15:25
  • @Maxim Yeah but it doesnt actually get the appropriate numbers...not for me anyway.. – mixkat Apr 28 '11 at 15:38
  • @mixkat I don't understand. I thought you need "contact name/phone number" bunches. – Maxim Apr 28 '11 at 15:42
  • @Maxim Yeah thats exactly what I need but with that code you posted instead of having each contact name matched with the correct number, I get all the contact names matched with the first number that comes up...So they all have the same number basically... – mixkat Apr 28 '11 at 15:44
  • @mixkat try to print the data for all columns (set projection to null). It couldn't be the CP (android db actually) keeps only one number for all your contacts – Maxim Apr 28 '11 at 15:52
  • @mixkat do you have mail? I will send you the snippet – Maxim Apr 28 '11 at 15:54
  • @Maxim Sorry mate I didnt get that last bit..." It couldn't be the CP (android db actually) keeps only one number for all your contacts" What do u mean by that? – mixkat Apr 28 '11 at 15:57
1

I have the same problem. I resolved it by saving contacts in db first time user open app. And than I update data (it is up to you when app should update contacts).

So application uses contacts from my db table where name and number are in one row. It takes much less time.

Maxim
  • 2,996
  • 17
  • 19
  • Yeah i thought that too! But isn't there any other way? I would probably need to update every time the list of numbers is needed(i.e. every time that particular method is called) cause the contacts may have changed since your last update so it's not really a solution for me! – mixkat Mar 30 '11 at 12:36
  • @mixkat this link could be usefull [link]http://stackoverflow.com/questions/1401280/how-to-listen-for-changes-in-contact-database – Maxim Mar 30 '11 at 12:46
  • @mixkat I have solution for the question. I've posted it as another answer – Maxim Apr 28 '11 at 14:40