不,你没有处于任何错误的边缘。Contacts ContentProvider(以及我见过的几乎所有 ContentProvider)都与传统的 SQL 智慧相矛盾,哦,好吧。
如果要从多种类型的 ContactsContracts.CommonDataKinds 中获取数据,则需要检测您所在行的 mime-type 并确定它是哪种实体(或进行额外查询,我的首选解决方案是这一切都在一个查询中......)
屏住呼吸,这是我编写的一些代码示例。您应该能够看到不同的行如何可以是不同类型的实体,因此它们的通用列可以保存不同类型的数据,这就是我们使用 CommonDataKinds.* 类在上下文中引用它们的原因:
public class ContactsHelper {
private static String[] PROJECTION = {
Data.CONTACT_ID,
Data.MIMETYPE,
StructuredName.GIVEN_NAME,
StructuredName.FAMILY_NAME,
StructuredName.DISPLAY_NAME,
StructuredName.MIDDLE_NAME,
Email.ADDRESS
};
public static void readContacts(Context context) {
ContentResolver resolver = context.getContentResolver();
Uri contactsUri = ContactsContract.Data.CONTENT_URI;
SQLiteDatabase conn = DatabaseHelper.openDatabase(context);
Cursor cursor = resolver.query(contactsUri, PROJECTION, null, null, null);
int idxContactId = cursor.getColumnIndex(Data.CONTACT_ID);
int idxMimeType = cursor.getColumnIndex(Data.MIMETYPE);
int idxGivenName = cursor.getColumnIndex(StructuredName.GIVEN_NAME);
int idxFamilyName = cursor.getColumnIndex(StructuredName.FAMILY_NAME);
int idxDisplayName = cursor.getColumnIndex(StructuredName.DISPLAY_NAME);
int idxMiddleName = cursor.getColumnIndex(StructuredName.MIDDLE_NAME);
int idxEmail = cursor.getColumnIndex(Email.ADDRESS);
for (cursor.moveToFirst(); ! cursor.isAfterLast(); cursor.moveToNext()) {
String mimeType = cursor.getString(idxMimeType);
Integer contactId = cursor.getInt(idxContactId);
if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
String firstName = cursor.getString(idxGivenName);
String middleName = cursor.getString(idxMiddleName);
String lastName = cursor.getString(idxFamilyName);
String displayName = cursor.getString(idxDisplayName);
Log.d(TAG, all the values ^^^);
}
if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
String emailName = cursor.getString(idxEmail);
Log.d(TAG, all the values ^^^);
}
}
DatabaseHelper.closeDatabase(conn);
cursor.close();
}
}
是的,这个完全严肃的解决方案确实使用了字符串比较。如果有更好的方法,请告诉我!