Мне нужно получить список я бы, имя, фамилия, число (или числа), электронное письмо, Веб-сайт контактов устройства Android. Я знаю, что, получив идентификатор, я могу запросить номера телефонов, в этом нет ничего страшного. Но я не знаю, как мне сделать запрос, чтобы правильно получить все эти столбцы.
Я предполагал, что для имен мне нужен КонтактыContract.CommonDataKinds.StructuredName, для электронной почты мне нужен КонтактыContract.CommonDataKinds.Email.ADDRESS, для идентификатора Контакты и для веб-сайта КонтактыКонтракт.CommonDataKinds.Website.URL.
Мой код возвращает странные значения, такие как однозначное число для GIVEN_NAME, null для FAMILY_NAME, один из контактных номеров для Email.ADDRESS.
Однако я думаю, что проблема в URI запроса, какой из них мне следует использовать?
ContentResolver cr = getActivity().getContentResolver();
String[] projection = new String[] {
Contacts._ID,
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
ContactsContract.CommonDataKinds.Website.URL,
ContactsContract.CommonDataKinds.Email.ADDRESS};
Cursor nameCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection,
null,
null,
null);
while (nameCur.moveToNext()) {
String given = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String family = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String email = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));
Integer id= nameCur.getInt(nameCur.getColumnIndex(Contacts._ID));
String website = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.Website.URL));
//do some work with strings...
}




Проблема в том, что все подтаблицы, к которым вы пытаетесь получить доступ (Email, Phone, Website и т. д.), На самом деле все хранятся в одной большой таблице под названием Data.
Все эти подтаблицы используют одни и те же поля Data1-Data15, поэтому, запрашивая таблицу Phone.CONTENT_URI, вы получаете только информацию Phone, поэтому попытка доступа к StructuredName.GIVEN_NAME по результату неверна.
Вместо этого вы запрашиваете таблицу Data.CONTENT_URI, которая содержит всю информацию, и различаете строки с разными типами данных с помощью значения в Data.MIMETYPE.
См. Документы здесь: https://developer.android.com/reference/android/provider/ContactsContract.Data
Я не уверен, нужна ли вам контактная информация для всех контактов на устройстве или для конкретного.
Вот код для получения информации об одном контакте (вам нужно присвоить значение переменной contactId там)
String[] projection = {Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3};
// query only emails/phones/events
String selection = Data.CONTACT_ID + " = " + contactId + " AND " +
Data.MIMETYPE + " IN ('" + StructuredName.CONTENT_ITEM_TYPE + "', '" + Phone.CONTENT_ITEM_TYPE + "', '" + Email.CONTENT_ITEM_TYPE"', '" + Website.CONTENT_ITEM_TYPE + "')";
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);
while (cur.moveToNext()) {
long id = cur.getLong(0);
String name = cur.getString(1); // full name
String mime = cur.getString(2); // type of data (phone / birthday / email)
String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
String kind = "unknown";
switch (mime) {
case StructuredName.CONTENT_ITEM_TYPE:
String firstName = cur.getString(4);
String lastName = cur.getString(5);
Log.d(TAG, "got name: " + data + " - " + firstName + " " + lastName);
break;
case Phone.CONTENT_ITEM_TYPE:
Log.d(TAG, "got phone: " + data);
break;
case Email.CONTENT_ITEM_TYPE:
Log.d(TAG, "got email: " + data);
break;
case Website.CONTENT_ITEM_TYPE:
Log.d(TAG, "got website: " + data);
break;
}
}
cur.close();
Чтобы преобразовать его для обработки ВСЕХ контактов, просто удалите часть Data.CONTACT_ID + " = " + contactId из selection, а затем вам нужно будет создать некоторую HashMap из contactId в объект, содержащий информацию об этом контакте (используйте переменную id для ключа)
вот мое решение: сначала нам нужен запрос для получения всех идентификаторов контактов в таблице raw_contacts
List<Integer> ret = new ArrayList<Integer>();
ContentResolver contentResolver = getActivity().getContentResolver();
// Row contacts content uri( access raw_contacts table. ).
Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI;
// Return _id column in contacts raw_contacts table.
String queryColumnArr[] = {ContactsContract.RawContacts._ID};
// Query raw_contacts table and return raw_contacts table _id.
Cursor cursor = contentResolver.query(rawContactUri, queryColumnArr, null, null, null);
затем мы запрашиваем у таблицы «данные» дополнительную информацию для каждого идентификатора контакта:
// Data content uri (access data table. )
Uri dataContentUri = ContactsContract.Data.CONTENT_URI;
// Build query columns name array.
List<String> queryColumnList = new ArrayList<String>();
// ContactsContract.Data.CONTACT_ID = "contact_id";
queryColumnList.add(ContactsContract.Data.CONTACT_ID);
// ContactsContract.Data.MIMETYPE = "mimetype";
queryColumnList.add(ContactsContract.Data.MIMETYPE);
queryColumnList.add(ContactsContract.Data.DATA1);
queryColumnList.add(ContactsContract.Data.DATA2);
queryColumnList.add(ContactsContract.Data.DATA3);
queryColumnList.add(ContactsContract.Data.DATA4);
queryColumnList.add(ContactsContract.Data.DATA5);
queryColumnList.add(ContactsContract.Data.DATA6);
queryColumnList.add(ContactsContract.Data.DATA7);
queryColumnList.add(ContactsContract.Data.DATA8);
queryColumnList.add(ContactsContract.Data.DATA9);
queryColumnList.add(ContactsContract.Data.DATA10);
queryColumnList.add(ContactsContract.Data.DATA11);
queryColumnList.add(ContactsContract.Data.DATA12);
queryColumnList.add(ContactsContract.Data.DATA13);
queryColumnList.add(ContactsContract.Data.DATA14);
queryColumnList.add(ContactsContract.Data.DATA15);
// Translate column name list to array.
String queryColumnArr[] = queryColumnList.toArray(new String[queryColumnList.size()]);
// Build query condition string. Query rows by contact id.
StringBuffer whereClauseBuf = new StringBuffer();
whereClauseBuf.append(ContactsContract.Data.RAW_CONTACT_ID);
whereClauseBuf.append(" = ");
whereClauseBuf.append(rawContactId);
// Query data table and return related contact data.
Cursor cursor = contentResolver.query(dataContentUri, queryColumnArr, whereClauseBuf.toString(), null, null);
последний курсор содержит все данные любого контакта, и для получения этих данных нам нужно переключить регистр:
String mimeType =cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
switch (mimeType) {
// Get email data.
case ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE:
// Email.ADDRESS == data1
String emailAddress = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));
int emailType = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
data.setDataType(emailType);
data.setDataValue(emailAddress);
ret1.add(data);
con.setEmailList(ret1);
break;
// Get organization data.
case ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE:
// Organization.COMPANY == data1
String company = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.COMPANY));
con.setCompany(company);
break;
// Get phone number.
case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
// Phone.NUMBER == data1
String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// Phone.TYPE == data2
int phoneTypeInt = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
data.setDataType(phoneTypeInt);
data.setDataValue(phoneNumber);
ret1.add(data);
con.addPhoneList(ret1);
break;
// Get display name.
case ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE:
// StructuredName.DISPLAY_NAME == data1
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
// StructuredName.GIVEN_NAME == data2
String givenName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
// StructuredName.FAMILY_NAME == data3
String familyName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
ret.add("Display Name : " + displayName);
ret.add("Given Name : " + givenName);
ret.add("Family Name : " + familyName);
break;
// Get website.
case ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE:
// Website.URL == data1
String websiteUrl = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Website.URL));
// Website.TYPE == data2
int websiteTypeInt = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Website.TYPE));
String websiteTypeStr = getEmailTypeString(websiteTypeInt);
ret.add("Website Url : " + websiteUrl);
ret.add("Website Type Integer : " + websiteTypeInt);
ret.add("Website Type String : " + websiteTypeStr);
break;
}
это не мой код участника просто для понимания. надеюсь, это кому-то поможет!
спасибо за ваш код и ответ, это было очень полезно. Между прочим, я думаю, мне нужно глубже изучить базу контактов Android. Я нашел эту ссылку очень информативной dev2qa.com/… для тех, кто хочет учиться. Скоро выложу результат.