Мне нужно прочитать контакты с устройства. Требуемые поля: ID
, Display Name
, Phone Number
(все типы) Email id
(все типы) и «фото». Для этого прямо сейчас я делаю так.
1: Сначала я читаю все id
из ContactsContract.Contacts.CONTENT_URI;
, как показано ниже.
Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;
// Querying the table ContactsContract.Contacts to retrieve all the contacts
String[] projection = {ID};
Cursor contactsCursor = mContentResolver.query(contactsUri, projection, null, null,
"upper(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") ASC");
2 : Затем перебираем этот курсор, чтобы прочитать обязательные поля всех контактов.
if (contactsCursor.moveToFirst()) {
do {
long contactId = contactsCursor.getLong(contactsCursor.getColumnIndex(ID));
Uri dataUri = ContactsContract.Data.CONTENT_URI;
// Querying the table ContactsContract.Data to retrieve individual items like
// home phone, mobile phone, work email etc corresponding to each contact
String[] columns = {CONTACT_ID, PHOTO_URI, DISPLAY_NAME, MIME_TYPE, DATA_1, DATA_2, DATA_4};
String selection = ContactsContract.Data.CONTACT_ID + "=" + contactId;
Cursor dataCursor = mContentResolver.query(dataUri, columns,
selection,
null, null);
if (dataCursor.moveToFirst()) {
// Getting Display Name
displayName = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
do {
// Getting Phone numbers
String mimeType = dataCursor.getString(dataCursor.getColumnIndex(MIME_TYPE));
switch (mimeType) {
case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
String phoneNumber = dataCursor.getString(dataCursor.getColumnIndex(DATA_1));
switch (dataCursor.getInt(dataCursor.getColumnIndex(DATA_2))) {
case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
homePhone = phoneNumber;
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
mobilePhone = phoneNumber;
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
workPhone = phoneNumber;
break;
default:
otherPhone = phoneNumber;
}
break;
// Getting emails
case ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE:
switch (dataCursor.getInt(dataCursor.getColumnIndex(DATA_2))) {
case ContactsContract.CommonDataKinds.Email.TYPE_HOME:
homeEmail = dataCursor.getString(dataCursor.getColumnIndex(DATA_1));
break;
case ContactsContract.CommonDataKinds.Email.TYPE_WORK:
workEmail = dataCursor.getString(dataCursor.getColumnIndex(DATA_1));
break;
default:
otherEmail = dataCursor.getString(dataCursor.getColumnIndex(DATA_1));
}
break;
// getting photo Uri
case ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE:
if (dataCursor.getString(dataCursor.getColumnIndex(PHOTO_URI)) != null) {
photoUri = Uri.parse(dataCursor.getString(dataCursor.getColumnIndex(PHOTO_URI)));
}
break;
}
} while (dataCursor.moveToNext());
} while (contactsCursor.moveToNext());
Запросы работают нормально, но проблема в том, что для повторения и получения подробной информации о каждом контакте требуется слишком много времени. Первый запрос возвращается быстро, но вся задержка теперь во второй части, то есть в итерации по каждой строке первого запроса и запросе для каждого поля. Можно ли это сделать в одном запросе на соединение, чтобы оптимизировать производительность?
ContentProvider
иContentResolver
не поддерживаютJOIN
, отчасти потому, что не требуется, чтобы провайдер поддерживался базой данных SQL или чем-то еще, что понимает, что такое объединение. - person CommonsWare   schedule 12.03.2016