Контакты Android Отображать имя и номер телефона в одном запросе к базе данных?
Я пытаюсь получить список контактов из собственной базы данных с их отображаемым именем и номером телефона (любой или все). Существует много способов получения этой информации с помощью нескольких запросов к базе данных телефона, но это приводит к значительным накладным расходам.
Вот запрос, над которым я работал, но он приводит к
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'";
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Cursor people = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
int index_id = people.getColumnIndex(ContactsContract.Contacts._ID);
int indexName = people.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
int indexNumber = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
people.moveToFirst();
do {
String _id = people.getString(index_id);
String name = people.getString(indexName);
String number = people.getString(indexNumber);
// Do work...
} while (people.moveToNext());
И вот в результате ошибка.
E/AndroidRuntime(21549): Caused by: java.lang.IllegalArgumentException: Invalid column data1
E/AndroidRuntime(21549): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:144)
E/AndroidRuntime(21549): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:114)
E/AndroidRuntime(21549): at android.content.ContentProviderProxy.bulkQueryInternal(ContentProviderNative.java:372)
E/AndroidRuntime(21549): at android.content.ContentProviderProxy.query(ContentProviderNative.java:408)
E/AndroidRuntime(21549): at android.content.ContentResolver.query(ContentResolver.java:264)
Мысли? Я считаю, что объединение может быть необходимо, чтобы получить все столбцы в одном запросе.
3 ответа
Попробуйте этот код:
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection = new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor people = getContentResolver().query(uri, projection, null, null, null);
int indexName = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int indexNumber = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
if(people.moveToFirst()) {
do {
String name = people.getString(indexName);
String number = people.getString(indexNumber);
// Do work...
} while (people.moveToNext());
}
API контактов чрезвычайно сложен и имеет несколько неявных объединений.
Прочтите ContactContract и ContactsProvider2, если вы можете позволить себе время.
Чего ты хочешь? Таблицы связаны следующим образом:
- Контакт 1- * Сырой Контакт
- Raw Contact 1- * номер телефона (таблица данных)
API работает следующим образом: вы выбираете самый нижний элемент (номер телефона) и неявное соединение с самым верхним элементом (контакт).
Вы хотите использовать регистр PHONE URI (ContactsProvider2 / строка 4377). Это должно выбрать все номера телефонов и присоединиться к контакту.
Объедините PHONE uri с некоторыми элементами пользовательского интерфейса (для группировки), запросите DISPLAY_NAME и номер PHONE (DATA1?), И вы сможете решить проблему.
Телефонные номера хранятся в отдельной таблице и должны запрашиваться отдельно. Для запроса таблицы телефонных номеров используйте URI, хранящийся в переменной SDK ContactsContract.CommonDataKinds.Phone.CONTENT_URI. Используйте условие WHERE для получения телефонных номеров для указанного контакта.
private String displayName(Uri contactUri) {
HashSet detail = ContactDetail.getInstance().getContactArray();
Log.d("ITEM", contactUri.toString());
String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor queryCursor = getActivity().getContentResolver()
.query(contactUri, null, null, null, null);
queryCursor.moveToFirst();
String name = queryCursor.getString(queryCursor.getColumnIndex("display_name"));
String id = queryCursor.getString(
queryCursor.getColumnIndex(ContactsContract.Contacts._ID));
if (Integer.parseInt(queryCursor.getString(queryCursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = getActivity().getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
String number = pCur.getString(pCur.getColumnIndex("data1"));
Log.d("Contact Name: ", number);
}
pCur.close();
}
return name;
}
Выполните второй запрос к базе данных SQLite контактов Android. Телефонные номера сопоставляются с URI, хранящимся в ContactsContract.CommonDataKinds.Phone.CONTENT_URI. Идентификатор контакта хранится в таблице телефона как ContactsContract.CommonDataKinds.Phone.CONTACT_ID, а предложение WHERE используется для ограничения возвращаемых данных.