Я пытался оптимизировать свой код для получения контактной информации из базы данных контактов Android. Но что бы я ни пытался, для загрузки 80 контактов с именем, номером телефона и эскизом контакта (растровым изображением) все равно требуется около 4-5 секунд. Я запускаю следующий фрагмент внутри doInBackground()
экземпляра AsyncTask
:
Cursor cursor = null;
try {
String[] projection = {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.PHOTO_URI };
cursor = getBaseContext().getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, null, null, null);
int nameIdx = cursor.getColumnIndex(Phone.DISPLAY_NAME);
int phoneNumberIdx = cursor.getColumnIndex(Phone.NUMBER);
if(cursor.moveToFirst()) {
do {
String name = cursor.getString(nameIdx);
String phoneNumber = cursor.getString(phoneNumberIdx);
long contactId=getContactIDFromNumber(phoneNumber, getBaseContext());
Bitmap bmp=loadContactPhoto(getBaseContext().getContentResolver(), contactId);
item.add(new ContactObject(name, phoneNumber, null, null, bmp, contactId));
} while (cursor.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
А вот методы получения идентификатора контакта из номера телефона и декодирования потока растровых изображений:
public static long getContactIDFromNumber(String contactNumber,Context context)
{
contactNumber = Uri.encode(contactNumber);
int phoneContactID = new Random().nextInt();
Cursor contactLookupCursor = context.getContentResolver().query(Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, contactNumber),new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup._ID}, null, null, null);
while(contactLookupCursor.moveToNext()){
phoneContactID = contactLookupCursor.getInt(contactLookupCursor.getColumnIndexOrThrow(PhoneLookup._ID));
}
contactLookupCursor.close();
return phoneContactID;
}
public Bitmap loadContactPhoto(ContentResolver cr, long id) {
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
if (input == null) {
return BitmapFactory.decodeResource(getBaseContext().getResources(), R.drawable.ic_launcher);
}
return BitmapFactory.decodeStream(input);
}
Программа работает нормально, но мне интересно, есть ли другой способ получить контактную информацию с указанными выше полями? Я знаю, что программа работает медленно из-за метода getContactIDFromNumber()
, который выполняет подзапрос для получения contactId
. Я использую это для получения миниатюры изображения контакта. Может ли кто-нибудь предложить лучший способ сделать это? Возможно, метод, с помощью которого этот подзапрос можно было бы полностью исключить?
РЕДАКТИРОВАТЬ:
long contactId = Long.parseLong(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)));
Получение растрового изображения:
Uri contactPhotoUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
InputStream is=ContactsContract.Contacts.openContactPhotoInputStream(getBaseContext().getContentResolver(), contactPhotoUri);
Bitmap bitmap=null;
if(is!=null){
bitmap = BitmapFactory.decodeStream(is);
}