【发布时间】:2016-06-15 23:35:22
【问题描述】:
我想显示包含电话号码但所有已分配号码的联系人。我想提高性能。有没有更有效的方法来做到这一点?喜欢一次获取所有联系人缩略图?这个 approach 对我来说失败了,因为光标不是空的,而是返回 empty(?) uri。
我已经进行了一些时间跟踪,看起来 appendContactNumber() 需要从 15 毫秒(一个电话号码)到大约 20 毫秒(三个电话号码)执行。
// List specific variables
private static ArrayList<String> Contacts;
private static ArrayList<String> Numbers;
private static ArrayList<Bitmap> Photo;
// ContentResolver query specific variables
private static final Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI;
private static final String[] CONTACTS_PROJECTION = {
ContactsContract.Contacts._ID,
};
private static final String CONTACTS_SELECTION = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1";
private static final String CONTACTS_SORT_ORDER = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
private static final Uri PHONES_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
private static final String[] PHONE_PROJECTION = {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
private static final String PHONE_SELECTION = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ";
private static final String[] PHOTO_PROJECTION = { ContactsContract.Contacts.Photo.PHOTO };
private Context context;
public ContactsLoader(Context context) {
this.context = context;
}
@Override
public void run()
{
loadContacts();
}
private void loadContacts() {
Contacts = new ArrayList<>();
Numbers = new ArrayList<>();
Photo = new ArrayList<>();
// Retrieve all contacts with phone numbers
Cursor contactsCursor = context.getContentResolver().query(
CONTACTS_URI,
CONTACTS_PROJECTION,
CONTACTS_SELECTION,
null,
CONTACTS_SORT_ORDER
);
if (contactsCursor != null) {
while (contactsCursor.moveToNext()) {
appendContactNumber(contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID)));
}
contactsCursor.close();
}
}
private void appendContactNumber(final String contactId) {
// Retrieve phone numbers for contact specified by id
Cursor numbersCursor = context.getContentResolver().query(
PHONES_URI,
PHONE_PROJECTION,
PHONE_SELECTION + contactId,
null,
null
);
// If phone numbers cursor is not empty
if (numbersCursor != null) {
Bitmap thumbnail = getContactThumb(contactId);
while (numbersCursor.moveToNext()) {
Contacts.add(numbersCursor.getString(numbersCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
Numbers.add(numbersCursor.getString(numbersCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
Photo.add(thumbnail);
}
numbersCursor.close();
}
}
private Bitmap getContactThumb(final String contactId) {
// Get contact thumbnail for given contactId
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor thumbnailCursor = context.getContentResolver().query(
photoUri,
PHOTO_PROJECTION,
null,
null,
null
);
if (thumbnailCursor != null) {
// If contact thumbnail is not empty
if (thumbnailCursor.moveToFirst()) {
Bitmap contactPhoto = BitmapFactory.decodeStream(new ByteArrayInputStream(thumbnailCursor.getBlob(0)));
thumbnailCursor.close();
return contactPhoto;
}
}
// Default Bitmap
return BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_contact_picture);
}
【问题讨论】:
-
一些额外的时间跟踪结果:现在查询 100 个联系人需要 2.5 秒。使用资源中的默认图像:700 毫秒。在单独的线程中运行图像获取:大约 1 秒。
标签: android performance android-contacts android-contentresolver