Search code examples
androidemailcursorcontactscontract

Get contacts with email id


I need to get contacts information(cursor) with email. They must be distinct. There must be one entry per contact if he has got an email. How to do it? I am targetting new contacts API comes with 2.0.

1)I tried to do it using CursorJoiner, but a strange thing happens. Here is my code :

MatrixCursor matCur = new MatrixCursor(
            new String[]{
            Contacts._ID,
                Contacts.DISPLAY_NAME,
                "photo_id",
                "starred"
            }
        );

Cursor newContactCursor = managedQuery(
        ContactsContract.Contacts.CONTENT_URI,
            new String[]{
                Contacts._ID,
                Contacts.DISPLAY_NAME,
                "photo_id",
                "starred"
            },
            null,
            null,
            null//Contacts._ID 
        );

newContactCursor.moveToFirst();

Cursor emailCur = managedQuery(
        ContactsContract.CommonDataKinds.Email.CONTENT_URI,
            new String[] {  
                Email.CONTACT_ID,
                Email.DATA1
            },
            null,
            null,
            Email.CONTACT_ID
        );

            emailCur.moveToFirst();

CursorJoiner joiner = new CursorJoiner(
        newContactCursor, 
            new String[]{Contacts._ID}, 
            emailCur, 
            new String[] {Email.CONTACT_ID}
        );

for (CursorJoiner.Result joinerResult : joiner) {
        switch (joinerResult) {

        case LEFT:
        // handle case where a row in cursorA is unique
        //Log.i(TAG,"L|"+
        //newContactCursor.getString(newContactCursor.getColumnIndex("_id")) );

        break;

        case RIGHT:
        // handle case where a row in cursorB is unique
        //Log.i(TAG,
        //"R|"+
        //emailCur.getString(emailCur.getColumnIndex("contact_id")) );

        break;

        case BOTH:

        //Log.i(TAG,
        //"L|"+
        //newContactCursor.getString(newContactCursor.getColumnIndex("_id"))+
        //"|R|"+
        //emailCur.getString(emailCur.getColumnIndex("contact_id")) );

                Log.i(TAG,                                           newContactCursor.getString(newContactCursor.getColumnIndex("_id"))+"|"+
                            newContactCursor.getString(newContactCursor.getColumnIndex("display_name"))+"|"+
                            emailCur.getString(emailCur.getColumnIndex(Email.DATA1)));

                    String[] columnValues = 
                    {newContactCursor.getString(newContactCursor.getColumnIndex("_id")),
                            newContactCursor.getString(newContactCursor.getColumnIndex("display_name")),
                            newContactCursor.getString(newContactCursor.getColumnIndex("photo_id")),
                            newContactCursor.getString(newContactCursor.getColumnIndex("starred"))
                    };

                    matCur.addRow(columnValues);

                    break;
                }
            }

now what my problem is i got output like this : in this log its _id | display_name | email id i have replaced them due to privacy issue

1|[contact name]|[email id] 
4|[contact name]|[email id] 
5|[contact name]|[email id] 
6|[contact name]|[email id]
7|
8| 
9| 
90| 
91| 
92|
93| 
94| 
95| 
96| 
97| 
98| 
99|

But you can see that it directly jumps from 9 to 90 then all 9 9 9, what is this?

2) Can we do this using distinct keyword? Is it possible with contact providers like ContactsContract?


Solution

  • I just ran into the same problem. I know this thread is pretty old, but maybe this answer will help somebody else in the future.

    You must filter by MIME type to get rid of duplicates. This is how I did it:

    Uri contacts = ContactsContract.Data.CONTENT_URI;
    
    String[] projection = new String[] {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.LOOKUP_KEY,
            ContactsContract.Contacts.DISPLAY_NAME
    };
    
    String selection =
            ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ? AND " + 
            ContactsContract.Contacts.DISPLAY_NAME + " LIKE ?"  + " AND " +
            ContactsContract.Data.MIMETYPE + "='" +
            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'";
    
    String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
    
    mContactCursor = managedQuery(
            contacts,
            projection,
            selection,
            new String[] {"1", constraint.toString() + '%'},
            sortOrder);