最近在做Android通讯录相关开发,需求是获取系统通讯录中所有手机号字段,包括住宅的手机号,还要展示姓名和头像
获取通讯录手机性能低500条数据大概耗时要15s左右,满足不了产品需求,所以要进行优化获取速度。
简单实现:
查询所有手机号要指定URI路径:content://com.android.contacts/phones
速度优化点:
一、查询sql一定要过滤列,500条数据会将时间从15s缩短到5-6s,指定projection字段,我指定了四列,如果你不取头像,可以只取data1和display_name两列
“contact_id”:contactId,为了按照这个id查询头像URI的数据
“data1”:手机号
"display_name":姓名
"photo_id":头像ID
二、优化头像获取速度
1、有photo_id字段有数据才查询,没有数据就不用查询了
2、按照contact_id、mimetype、deleted的查询条件过滤头像
3、查询出的字节数组直接保存,不要decode成bitmap再保存
总结:
在不做缓存的情况下,500条数据基本1s内就能查询出来。
示例代码:
public static List<ContactInfo> loadAllContacts(Context context) {
if (context == null) {
return null;
}
ContentResolver resolver = context.getContentResolver();
if (resolver == null) {
return null;
}
List<ContactInfo> dataList = new ArrayList<>();
String[] projection = new String[]{
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_ID
};
Cursor cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, null, null, null);
if (cursor == null) {
return Collections.EMPTY_LIST;
}
while (cursor.moveToNext()) {
int contactId = cursor.getInt(0);
String phone = cursor.getString(1);
String name = cursor.getString(2);
long photoId = cursor.getLong(3);
byte[] photoBytes = null;
if (photoId > 0) {
Cursor cursorPhoto = resolver.query(ContactsContract.RawContactsEntity.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Photo.PHOTO},
ContactsContract.RawContactsEntity.CONTACT_ID + " = ? and " + ContactsContract.RawContactsEntity.MIMETYPE + " = ? and " + ContactsContract.RawContactsEntity.DELETED + " = ?",
new String[]{String.valueOf(contactId), ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE, "0"},
null);
if (cursorPhoto.moveToNext()) {
photoBytes = cursorPhoto.getBlob(0);
}
cursorPhoto.close();
} else {
photoBytes = null;
}
ContactInfo contactInfo = new ContactInfo(name, phone, photoBytes);
dataList.add(contactInfo);
}
cursor.close();
return dataList;
}