我的应用程序有一个由设备上注册的联系人填充的listView,但当我加载listView时,它花费了太长时间!这是我的代码:
public List<Contact> getContactsList(Context context, ContentResolver contentResolver) {
List<Contact> listContatos = new ArrayList<Contact>();
Uri uri = ContactsContract.Contacts.CONTENT_URI;
Cursor cursorContacts = contentResolver.query(uri, null, null, null, ContactsContract.Contacts.DISPLAY_NAME + " COLLATE NOCASE ASC;");
try {
// while there is a next contact, retrieves your data
while (cursorContacts.moveToNext()) {
Contact c = getContact(context, cursorContacts);
if (c != null) {
listContatos.add(c);
}
}
} finally {
// Closes Cursor
cursorContacts.close();
}
return listContatos;
}
public Contact getContact(Context context, Cursor contactsCur) {
Contact c = new Contact();
// get contact id
long id = contactsCur.getLong(contactsCur.getColumnIndexOrThrow(BaseColumns._ID));
String strId = contactsCur.getString(contactsCur.getColumnIndex(BaseColumns._ID));
// get contact name
String name = contactsCur.getString(contactsCur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
boolean temFone = false;
// if return is different than 1, doesn't has phone number
temFone = "1".equals(contactsCur.getString(contactsCur.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
if (temFone) {
contactsCur = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[] { strId }, null);
ArrayList<PhoneNumber> phones = new ArrayList<PhoneNumber>();
while (contactsCur.moveToNext()) {
int idx = contactsCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
if (idx != -1) {
String phoneNumber = contactsCur.getString(contactsCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
int phonetype = contactsCur.getInt(contactsCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
String customLabel = contactsCur.getString(contactsCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL));
String phoneLabel = (String) ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(), phonetype, customLabel);
phones.add(new PhoneNumber(phoneLabel, phoneNumber));
}
}
c.setPhones(phones);
contactsCur.close();
} else {
c.setPhones(null);
}
loadAddress(context, c, id);
c.setContactId(id);
c.setName(name);
loadEmails(context, c, id);
loadPhotoUri(context, c, id);
return c;
}
private void loadEmails(Context context, Contact c, long id) {
Cursor cursor = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + id,
null, null);
ArrayList<ContactMail> emails = new ArrayList<ContactMail>();
while (cursor.moveToNext()) {
int idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
if (idx != -1) {
String stremail = cursor.getString(idx);
int emailtype = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
String customLabel = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.LABEL));
String emailLabel = (String) ContactsContract.CommonDataKinds.Email.getTypeLabel(context.getResources(), emailtype, customLabel);
if (!stremail.equals(""))
emails.add(new ContactMail(stremail, emailLabel));
}
}
c.setEmails(emails);
cursor.close();
}
private void loadAddress(Context context, Contact c, long id) {
Cursor cursor = context.getContentResolver().query(
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, null, ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = " + id, null, null);
ArrayList<Address> addresses = new ArrayList<Address>();
while (cursor.moveToNext()) {
int idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.DATA);
if (idx != -1) {
String address = cursor.getString(idx);
int addresstype = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE));
String customLabel = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.LABEL));
String addressLabel = (String) ContactsContract.CommonDataKinds.StructuredPostal.getTypeLabel(context.getResources(), addresstype, customLabel);
if (!address.equals(""))
addresses.add(new Address(address, addressLabel, null));
}
}
c.setAddresses(addresses);
cursor.close();
}
public void loadPhotoUri(Context context, Contact c, long id) {
Cursor cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID
+ "="
+ id
+ " AND "
+ ContactsContract.Data.MIMETYPE
+ "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
+ "'", null, null);
while (cursor.moveToNext()) {
int idx = cursor
.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.DATA);
if (idx != -1) {
Uri person = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, id);
c.setPhoto( Uri.withAppendedPath(person,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY));
}
}
}
它运行得很好,很完美,唯一的问题是需要很长时间才能获得所有联系人的信息。我使用getContact方法来获取设备中每个联系人的所有详细信息,而不是在getContactsList中,然后放在联系人列表中。联系人列表由listView的适配器使用。
提前感谢!
抱歉有任何英语错误。。。
我也遇到了同样的问题。必须显示所有联系人的姓名和电话号码-效果很好,但花了太长时间。
作为Android开发领域的新手,我对它进行了一些研究,发现了以下帖子:
- 从联系人列表中获取姓名和电子邮件非常缓慢
这对我很有用。
我想问题是你正在进行一个内部查询,所以它会花你很长时间。我的代码的主要问题是多次获取列索引(所以我在while循环之前将其更改为一次),以及我的代码中不太清楚的内部查询,并找到了一种删除它的方法。
试着在那篇文章中使用这个例子,看看它是否有帮助(希望它会有帮助——因为对我来说它是完美的!)
祝好运
经过这么多研究,我发现这个解决方案100%快速加载。
使用光标加载器加载所有联系人
String[] PROJECTION = new String[] {
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER };
ArrayList<ContactBean> listContacts = new ArrayList<>();
CursorLoader cursorLoader = new CursorLoader(context,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION,
null, null, "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME
+ ")ASC");
Cursor c = cursorLoader.loadInBackground();
if (c.moveToFirst()) {
int Number = c
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int Name = c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
do {
try {
String phNumber = c.getString(Number);
String phName = c.getString(Name);
} catch (Exception e) {
}
} while (c.moveToNext());
c.close();
}
这是我的快速解决方案:
Cursor cursorPhones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.LABEL
},
ContactsContract.Contacts.HAS_PHONE_NUMBER + ">0 AND LENGTH(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ")>0",
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
);
while (cursorPhones.moveToNext()) {
String displayName = cursorPhones.getString(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursorPhones.getString(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
int type = cursorPhones.getInt(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
String label = cursorPhones.getString(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL));
CharSequence phoneLabel = ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(), type, label);
}
cursorPhones.close();