我想显示联系人,其中包含电话号码,但所有已分配的号码。我想提高性能。有没有更有效的方法来做到这一点?就像一次获得所有联系人缩略图一样?这个approach以某种方式失败了,因为游标不是空的,但返回空(?)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);
}
答案 0 :(得分:0)
我做了一些解决方法:而不是查询Bitmap,获取照片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;
}
}