0

Я пытался оптимизировать свой код для получения контактной информации из базы данных контактов Android. Но независимо от того, что я пытаюсь, для загрузки 80 контактов с именем, номером телефона и миниатюрным изображением контакта (растровым изображением) требуется еще 4-5 секунд. Я бегу следующий фрагмент кода внутри doInBackground() в качестве AsyncTask например:Получение результатов из магазина контактов Android

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(); 
    } 
} 

А вот методы для получения контактной ID из номера телефона и декодировать растровый поток:

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); 
        } 

ответ

1

Возможно, способ, с помощью которого этот суб-запрос может быть полностью устранены?

Включите ContactsContract.Contacts._ID в вашу проекцию. Поставщик ContactsContract делает соединение и может предоставить вам эту информацию в вашем первоначальном запросе.

В this sample app, я получить следующие три колонки сразу:

private static final String[] PROJECTION_NUMBERS=new String[] { 
    ContactsContract.Contacts._ID, 
    ContactsContract.Contacts.DISPLAY_NAME, 
    ContactsContract.CommonDataKinds.Phone.NUMBER 
}; 

для запроса к ContactsContract.CommonDataKinds.Phone.CONTENT_URI.

+0

Большое спасибо! Не могли бы вы объяснить, как его можно использовать для извлечения контактных эскизов? –

+0

@VinitShandilya: Как * what * можно использовать для извлечения контактных эскизов? У вас уже есть код для этого, учитывая ID контакта. – CommonsWare

+0

См. Раздел EDIT. Я попытался извлечь контактные эскизы, используя идентификатор контакта. Я также пробовал этот идентификатор контакта в моем оригинальном методе декодирования Bitmap. К сожалению, я не могу получить растровое изображение с миниатюрами. –

Смежные вопросы