我正在实现一个AutoCompleteTextView,我需要所有联系人的姓名和电子邮件。 我发现这个片段是我异步运行但速度非常慢。
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();
}
}
}
我正在执行某种内部查询,我认为这就是问题所在。有没有办法调整它并使其更快?
答案 0 :(得分:51)
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();
}
}
几点说明:
ContactsContract.CommonDataKinds.Email.CONTENT_URI
获取所需信息,有关您可以查询的列的信息,请参阅ContactsContract.CommonDataKinds.Email 答案 1 :(得分:6)
您不应直接查询ContactsContract.Contacts
使用电子邮件数据类型在ContactsContract.CommonDataKinds上进行一次查询。
ContactsContract.CommonDataKinds.Email继承了许多可用于构建投影的其他界面。 (参见文档中的继承常量)
例如:
import android.provider.ContactsContract.CommonDataKinds.Email;
[...]
public static final String[] EMAILS_PROJECTION = new String[] {
Email._ID,
Email.DISPLAY_NAME_PRIMARY,
Email.ADDRESS
};
与
一起使用Email.CONTENT_URI
您可以直接从电子邮件数据类型中检索大量信息(例如用户ID,用户显示名称...)。
修改强>
我刚刚意识到你正在尝试构建一个AutoCompleteTextView。
您应该覆盖runQueryOnBackgroundThread
方法和CursorAdapter的convertToString
并使用Email.CONTENT_FILTER_URI
我非常强烈建议您查看 ApiDemo示例。
特别是您可以找到 HERE 的 AutoComplete4.java 示例。
答案 2 :(得分:0)
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));
}
}