1

我想要显示具有电话号码但具有所有分配号码的联系人。我想提高性能。有没有更有效的方法来做到这一点?像一次获取所有联系人缩略图?这个approach以某种方式失败,因为游标不是空的,但返回空(?)uri。Android对于获取联系人详细信息的性能下降

我已经做了一些时间跟踪,它看起来像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); 
} 
+0

一些额外的时间跟踪结果: 现在查询100个联系人需要2.5秒。 使用来自资源的默认图像:700毫秒。 在单独的线程中运行图像抓取:约1秒。 – XXXOOO

回答

0

我做了一些解决方法:而不是查询位图获取照片URI更快。这是我的代码:

import android.content.Context; 
import android.database.Cursor; 
import android.net.Uri; 
import android.provider.ContactsContract; 
import android.util.Log; 

import java.util.ArrayList; 

public class PhoneContactsLoader extends ContactsLoader { 

    // Class specific variables 
    private ArrayList<String> Numbers; 

    public PhoneContactsLoader(Context context) { 
     super(context); 

     // ContentResolver query specific variables 
     URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI.toString(); 
     PROJECTION = new String[] { 
       ContactsContract.Contacts._ID, 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, 
       ContactsContract.CommonDataKinds.Phone.NUMBER, 
       ContactsContract.Contacts.PHOTO_URI 
     }; 
     SELECTION = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1"; 
     SORT_ORDER = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; 
    } 

    @Override 
    protected void fetchContacts() { 
     Contacts = new ArrayList<>(); 
     Numbers = new ArrayList<>(); 
     Photos = new ArrayList<>(); 

     Long timer = System.currentTimeMillis(); 

     // Retrieve all contacts containing phone numbers 
     Cursor contactsCursor = context.getContentResolver().query(
       Uri.parse(URI), 
       PROJECTION, 
       SELECTION, 
       null, 
       SORT_ORDER 
     ); 

     if (contactsCursor != null) { 
      while (contactsCursor.moveToNext()) { 
       Contacts.add(contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))); 
       Numbers.add(contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
       String photoUri = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.PHOTO_URI)); 
       if (photoUri != null) 
        Photos.add(photoUri); 
       else 
        Photos.add("useDefault"); 
      } 
      contactsCursor.close(); 
     } 
     Log.i("PhoneContactsLoader", "Thread execution time: " + (System.currentTimeMillis() - timer) + " ms"); 
    } 

    @Override 
    public ArrayList<String> getNumbers() { 
     return Numbers; 
    } 
} 
相关问题