Android 获取联系人的名字和姓氏,而不是单个显示名?

Android 获取联系人的名字和姓氏,而不是单个显示名?,android,cursor,android-contacts,contactscontract,Android,Cursor,Android Contacts,Contactscontract,我目前正在与Android Contacts内容提供商合作,目前可以使用以下代码访问Contacts的完整显示名称,而不会出现问题: String[] PROJECTION = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER,

我目前正在与Android Contacts内容提供商合作,目前可以使用以下代码访问Contacts的完整显示名称,而不会出现问题:

String[] PROJECTION = new String[] {
         ContactsContract.Contacts._ID,
         ContactsContract.Contacts.DISPLAY_NAME,
         ContactsContract.Contacts.HAS_PHONE_NUMBER,
        };
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";

String SELECTION = "LOWER(" + ContactsContract.Contacts.DISPLAY_NAME + ")" 
    + " LIKE '" + constraint + "%' " + "and " + 
        ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";

Cursor cur = managedQuery(ContactsContract.Contacts.CONTENT_URI, 
                PROJECTION, SELECTION, null, sortOrder);
然而,我希望能够分别获得联系人的名字和姓氏,我尝试使用StructuredName来实现这一点,但我似乎无法让它正常工作

有人能告诉我如何正确使用StructuredName将名称分为第一个和最后一个吗

更新:

根据Hovanesyan的建议,我尝试了以下几点:

    String[] PROJECTION = new String[] {
            ContactsContract.Data._ID,
            ContactsContract.Data.DISPLAY_NAME,
            ContactsContract.Data.HAS_PHONE_NUMBER,
    };

    String SELECTION = ContactsContract.CommonDataKinds.StructuredName.IN_VISIBLE_GROUP + " = '1'";

    String sortOrder = ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME + " COLLATE LOCALIZED ASC";

    Cursor cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, sortOrder);

    int indexGivenName = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
    int indexFamilyName = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
    int indexDisplayName = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);

    while (cursor.moveToNext()) {
        String given = cursor.getString(indexGivenName);
        String family = cursor.getString(indexFamilyName);
        String display = cursor.getString(indexDisplayName);
        Log.e("XXX", "Name: | " + given + " | " + family + " | " + display);
    } 
但是,使用投影会导致如下崩溃:

12-08 16:52:01.575: E/AndroidRuntime(7912): Caused by: java.lang.IllegalArgumentException: Invalid column has_phone_number
如果我去掉投影,我会打印出所有的结果,但其中很多都包含NULL

例如:

12-08 16:56:14.055: E/XXX(8155): Name: | null | null | null
12-08 16:56:14.055: E/XXX(8155): Name: | null | null | null
12-08 16:56:14.055: E/XXX(8155): Name: | null | null | null
12-08 16:56:14.055: E/XXX(8155): Name: | null | null | null
有人能看出我的投影不起作用,我做错了什么吗

进一步更新:

我已经解决了我的投影问题,但是现在我遇到了一个问题,数据内容提供者向我提供了所有空数据,并在我的代码中导致了空指针异常

ContactsContract中的游标计数。Contacts返回115,但使用数据表返回464,使用相同的参数,这在我的应用程序中造成了巨大的问题

有人知道为什么吗?

看看课堂。这里有所有需要的列,您可能可以执行以下操作:

Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, other_query_params_for_filtering);

int indexGivenName = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
int indexFamilyName = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
int indexDisplayName = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);

while (cursor.moveToNext()) {
    String given = cursor.getString(indexGivenName);
    String family = cursor.getString(indexFamilyName);
    String display = cursor.getString(indexDisplayName);
}

以下是从
contacts contract.data
表中获取用户数据的通用功能:

Map<String, String> result = new HashMap<>();
Cursor cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, ContactsContract.Data.CONTACT_ID + "='" + YOUR_CONTACT_ID + "'", null, null);
if (cursor != null) {
    while (cursor.moveToNext()) {
        String mime = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
        switch (mime) {
            case ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE:
                result.put(FIRST_NAME, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME)));
                result.put(LAST_NAME, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME)));
                break;
            case ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE:
                result.put(CITY, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY)));
                result.put(STREET, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET)));
                result.put(ZIP, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE)));
                break;
            case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
                if (ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE == cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE))) {
                    result.put(MOBILE, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
                }
                break;
        }
    }
    cursor.close();
}
return result;
Map result=newhashmap();
Cursor Cursor=context.getContentResolver().query(ContactsContract.Data.CONTENT\u URI,null,ContactsContract.Data.CONTACT\u ID+“=”+您的\u CONTACT\u ID+”,null,null);
如果(光标!=null){
while(cursor.moveToNext()){
字符串mime=cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
交换机(mime){
案例联系人contract.CommonDataTypes.StructuredName.CONTENT\u ITEM\u类型:
put(FIRST_NAME,cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataTypes.StructuredName.GIVEN_NAME));
put(姓氏,cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataTypes.StructuredName.FAMILY_NAME));
打破
案例联系人contract.CommonDataTypes.StructuredPostal.CONTENT\u ITEM\u类型:
put(CITY,cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataTypes.StructuredPostal.CITY));
put(STREET,cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataTypes.StructuredPostal.STREET));
put(ZIP,cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataTypes.StructuredPostal.POSTCODE));
打破
案例联系人contract.commonDataTypes.Phone.CONTENT\u ITEM\u类型:
if(ContactsContract.commondatatypes.Phone.TYPE_MOBILE==cursor.getInt(cursor.getColumnIndex(ContactsContract.commondatatypes.Phone.TYPE))){
put(MOBILE,cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataTypes.Phone.NUMBER));
}
打破
}
}
cursor.close();
}
返回结果;

这必须在FilterQuery中完成,虽然这似乎是问题的原因,但我需要能够获取ID、DisplayName和HasPhoneNumber列,其中我的字符串约束等于给定的或姓氏。因此,我需要一个managedQuery,这似乎带来了一些问题。为了实现这一点,您必须使用通用表数据:我试图使用通用数据表获取信息,但遇到了一些问题,我已编辑了我的问题,以防您能提供进一步帮助,谢谢。我明天将对此进行讨论,但只是一个提示-如果只选择不同的结果,光标的大小是多少。您好,我尝试了这个,但没有成功。这是我的问题,我非常感谢你的帮助!:)您还需要选择minetype和lookup_键,合并联系人,从android示例中签出联系人。
        Cursor phone_cursor = cr.query(ContactsContract.CommonDataKinds.
                Phone.CONTENT_URI, null, null, null, null);
        while (phone_cursor.moveToNext()) {
            try {
            int id = Integer.parseInt(phone_cursor.getString(phone_cursor.getColumnIndex
                    (ContactsContract.CommonDataKinds.Phone.CONTACT_ID)));
            Cursor name_cursor = cr.query(ContactsContract.Data.CONTENT_URI,null,
                    ContactsContract.Data.CONTACT_ID + "  = " + id, null, null);

                String name = phone_cursor.getString(phone_cursor.getColumnIndex
                        (ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String first_name ="";
                String last_name = "";
                while (name_cursor.moveToNext()) {
                    if(name_cursor.getString(name_cursor.getColumnIndex
                            (ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME))!=null){
                    first_name = name_cursor.getString(name_cursor.getColumnIndex
                            (ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
                    last_name = name_cursor.getString(name_cursor.getColumnIndex
                            (ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
                }}
                name_cursor.close();
                String phoneNumber = phone_cursor.getString(phone_cursor.getColumnIndex
                        (ContactsContract.CommonDataKinds.Phone.NUMBER));
            } catch (Exception e) {
            }
        }
        phone_cursor.close();