Getting name and email from contact list is very slow

浪尽此生 提交于 2019-11-28 04:46:29
private static final String[] PROJECTION = new String[] {
    ContactsContract.CommonDataKinds.Email.CONTACT_ID,
    ContactsContract.Contacts.DISPLAY_NAME,
    ContactsContract.CommonDataKinds.Email.DATA
};

...

ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION, null, null, null);
if (cursor != null) {
    try {
        final int contactIdIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID);
        final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        final int emailIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
        long contactId;
        String displayName, address;
        while (cursor.moveToNext()) {
            contactId = cursor.getLong(contactIdIndex);
            displayName = cursor.getString(displayNameIndex);
            address = cursor.getString(emailIndex);
            ...
        }
    } finally {
        cursor.close();
    }
}

few notes:

  • use just ContactsContract.CommonDataKinds.Email.CONTENT_URI to get information you need, see ContactsContract.CommonDataKinds.Email for information what columns you can query
  • use projection to get only those columns you really need, you save some memory and increase query performance
  • get column indexes only once, just before the while cycle
Timothée Jeannin

You should not query directly the ContactsContract.Contacts

Make just one query on the ContactsContract.CommonDataKinds with the email data kind.

The ContactsContract.CommonDataKinds.Email inherits a lot of other interfaces that you can use to build your projection. (see inherited constants from the documentation)

For example :

import android.provider.ContactsContract.CommonDataKinds.Email;

[...]

public static final String[]  EMAILS_PROJECTION = new String[] {
    Email._ID,
    Email.DISPLAY_NAME_PRIMARY,
    Email.ADDRESS
};

to be used with the

Email.CONTENT_URI

You can retrieve a lot of information (such as user id, user display name ...) directly from the email data kind.

EDIT:

I just realized you're trying to build an AutoCompleteTextView.

You should override the runQueryOnBackgroundThread method and the convertToString of your CursorAdapter and use the Email.CONTENT_FILTER_URI

I really strongly suggest you to take a look at the ApiDemo samples.

Especially the AutoComplete4.java sample that you can find HERE.

Praveen Kumar
ContentResolver cr = mContext.getContentResolver(); 
Cursor cursor = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, PROJECTION, "HAS_PHONE_NUMBER <> 0", null, null); 

if (cursor!= null) 
{ 
    final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 
    final int numberIndex = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); 
    final int idIndex= cursor.getColumnIndex(ContactsContract.Contacts._ID); 
    String displayName, number = null, idValue; 

    while (cursor.moveToNext()) 
    {
        displayName = cursor.getString(displayNameIndex);
        idValue= cursor.getString(idIndex);

        Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, "contact_id = '" + idValue + "'", null, null);
        phones.moveToFirst();

        try 
        {
            number = phones.getString(phones.getColumnIndex("data1"));
        }
        catch (CursorIndexOutOfBoundsException e)
        {
        }

        phones.close();
        userList.add(new ContactModel(displayName, number, null));
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!