获取联系人的姓名而不是单个显示名称?

时间:2011-12-08 13:43:28

标签: android cursor android-contacts contactscontract

我目前正在使用Android联系人内容提供商,目前可以使用以下代码访问联系人完整显示名称:

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将名称拆分为First和Last?

更新

根据hovanessyan的建议,我尝试了以下方法:

    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);
    } 

但是使用PROJECTION会导致崩溃,如下所示:

12-08 16:52:01.575: E/AndroidRuntime(7912): Caused by: java.lang.IllegalArgumentException: Invalid column has_phone_number

如果我删除了PROJECTION,我会打印出所有结果,但很多都包含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

所以任何人都可以看到我做错了,因为我的PROJECTION不起作用了吗?

进一步更新:

我已经用我的PROJECTION解决了问题,但现在我遇到了一个问题,即DATA内容提供程序正在向我提供所有空数据并在我的代码中导致NULL指针异常。

来自ContactsContract.Contacts的游标数量让我回到115例如,但使用DATA表使用相同的参数返回464,这在我的应用程序中引起了巨大的问题。

任何人都有任何想法,为什么会这样?

3 个答案:

答案 0 :(得分:14)

看看ContactsContract.CommonDataKinds.StructuredName课程。你有所有需要的列,你可以做类似的事情:

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);
}

答案 1 :(得分:5)

        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();

答案 2 :(得分:4)

以下是从ContactsContract.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;