获取姓名和电子邮件从联系人列表很慢很慢、电子邮件、姓名、联系人

2023-09-13 00:02:29 作者:月亮是我踹彎的

我实现一个AutoCompleteTextView,我需要姓名和我所有的联系人的电子邮件。 我发现这个片段,我异步运行,但它是非常缓慢的。

  ContentResolver的CR = getContentResolver();
光标CUR = cr.query(ContactsContract.Contacts.CONTENT_URI,NULL,NULL,NULL,NULL);

如果(cur.getCount()大于0){
    而(cur.moveToNext()){
        字符串ID = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
        字符串名称= cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

        光标emailCur = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,空,ContactsContract.CommonDataKinds.Email.CONTACT_ID +=?,新的String [] {ID},NULL);

            而(emailCur.moveToNext()){

                字符串email = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                    autoCompleteAdapter.add(姓名+ - +电子邮件);
            }

            emailCur.close();
        }
    }
}
 

我进行某种内部查询的,我认为这就是问题所在。有没有办法对其进行调整,使之更快?

解决方案

 私有静态最后的String []投影=新的String [] {
    ContactsContract.CommonDataKinds.Email.CONTACT_ID,
    ContactsContract.Contacts.DISPLAY_NAME,
    ContactsContract.CommonDataKinds.Email.DATA
};

...

ContentResolver的CR = getContentResolver();
光标光标= cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,投影,NULL,NULL,NULL);
如果(光标!= NULL){
    尝试 {
        最终诠释contactIdIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID);
        最终诠释displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        最终诠释emailIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
        长的ContactID;
        字符串显示名,地址;
        而(cursor.moveToNext()){
            使用ContactID = cursor.getLong(contactIdIndex);
            显示名= cursor.getString(displayNameIndex);
            地址= cursor.getString(emailIndex);
            ...
        }
    } 最后 {
        cursor.close();
    }
}
 

几个注意事项:

使用刚 ContactsContract.CommonDataKinds.Email.CONTENT_URI 来得到你需要的信息,请参阅ContactsContract.CommonDataKinds.Email信息哪些列可以查询 使用投影只得到那些你真正需要的,你节省一些内存和提高查询性能列 在获得列索引一次,就在同时,周期之前 电子邮件怎么弄 自己的邮件号码在那儿才能看到

I'm implementing an AutoCompleteTextView and I need Name and E-Mail of all my contacts. I found this snippet that I'm running asynchronously but it's very slow.

ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

if (cur.getCount() > 0) {               
    while (cur.moveToNext()) {                  
        String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));                   
        String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

        Cursor emailCur = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null); 

            while (emailCur.moveToNext()) { 

                String email = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                    autoCompleteAdapter.add(name + " - " + email);
            }

            emailCur.close();
        }
    }
}

I'm performing a sort of inner query and I think that's the problem. Is there a way to tune it and make it faster?

解决方案

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