Get first and last name of a contact rather than single display name?
Asked Answered
M

3

9

I am currently working with the Android Contacts content provider and currently can access a contacts full display name without issue using the following code:

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

However I want to be able to get both the contacts first and last name separately, I have tried to use the StructuredName in an attempt to get this but I can't seem to get it working.

Can anyone point me in the right direction as to how to use the StructuredName correctly to get the name split into First and Last?

UPDATE:

Following hovanessyan's advice I have attempted the following:

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

However using the PROJECTION causes a crash as follows:

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

If I remove the PROJECTION I get all the results printed out but a lot of them contain NULL.

For example:

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

So can anyone see what I'm doing wrong in that my PROJECTION doesn't work?

FURTHER UPDATE:

I have sorted out the issues with my PROJECTION but now I have an issue where the DATA content provider is supplying me back with all the null data and causing NULL pointer exceptions in my code.

A cursor count from ContactsContract.Contacts gives me back 115 for example but using the DATA table gives me back 464 using the same parameters and this is causing huge issues in my app.

Anyone have any ideas why that is?

Murguia answered 8/12, 2011 at 13:43 Comment(1)
You need to select the minetype and lookup_key also and merge contacts, checkout Contactables from android samples.Heigho
T
14

Take a look at ContactsContract.CommonDataKinds.StructuredName class. You have all the needed columns there, and you can probably do something like:

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);
}
Textual answered 8/12, 2011 at 13:55 Comment(6)
It has to be done within a FilterQuery though which seems to be causing the problem, I need to be able to get the ID, DisplayName and HasPhoneNumber columns where my String constraint is equal to either the Given or Family name. So i need a managedQuery and this seems to be presenting some problems.Murguia
You have to use the generic table Data in order to achieve this: developer.android.com/reference/android/provider/…Textual
I have attempted to get the info using the generic DATA table and have come across some issues, I've edited my question in case you can help further, thanks.Murguia
I will look at this tomorrow, but just a hint - what's the size of the cursor if you select only distinct results.Textual
Hello, I tried this, but it didn't work. Here is my question, I would really appreciate your help! :) https://mcmap.net/q/182714/-get-contact-name/…Spermaceti
Hello, I believe the API might have changed since 2011, so please seek more up-to-date answer. This answer was valid for Android 2.3/2.4Textual
S
6

Here is a general function for getting user data from ContactsContract.Data table:

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;
Stromberg answered 24/3, 2014 at 11:42 Comment(0)
K
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();
Kinch answered 29/10, 2014 at 11:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.