Search code examples
androidandroid-contentproviderandroid-contacts

Contact Ids are missing when querying to raw contacts table according to account name


I am unable to get all contact ids from the RawContacts table

private void displayAllContactsByType(String accountName)
 {//e.g accountName="WHATSAPP"

    Cursor rawCursor = null;

        rawCursor = cResolver.query(
                ContactsContract.RawContacts.CONTENT_URI,
                new String[]{ContactsContract.RawContacts.CONTACT_ID},
                ContactsContract.RawContacts.ACCOUNT_NAME + "= ?",
                new String[]{accountName},
                ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " COLLATE LOCALIZED ASC");


    rawCursor.moveToFirst();

    int contactIdColumn = rawCursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
    int rawCursorCount = rawCursor.getCount();
    int total = 1;

    Utils.Log("Raw Size", " " + rawCursorCount);//rawCursorCount is correct here

    while (rawCursor.moveToNext()) {

        Long contactId = rawCursor.getLong(contactIdColumn);

        publishProgress(((total * 100) / rawCursorCount));
        progressBar.setProgressNumberFormat("" + total + "/" + rawCursorCount);

        storeContactDetails(contactId, accountName);
        ++total;
//I am facing problem in this method only below code is just for understanding.
    }
}

Contact ids are passed to the below method with account name to get the contact details from respective id but contact ids are less compare to the log //Utils.Log("Raw Size", " " + rawCursorCount).

 private void storeContactDetails(Long id, String accountName) {

    Cursor phones = null;
    String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
            ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER,
            ContactsContract.CommonDataKinds.Phone.NUMBER,
            ContactsContract.Contacts.LOOKUP_KEY,
            "account_name",
            Phone.TYPE
    };



    //Cursor c=cResolver.query(ContactsContract.Data.CONTENT_URI,projection,ContactsContract.Data.RAW_CONTACT_ID + " = ?",new String[]{String.valueOf(id)} ,null);

        phones = cResolver.query(Phone.CONTENT_URI,
                projection,
                Phone.CONTACT_ID + " = ?",
                new String[]{String.valueOf(id)},
                null);


    phones.moveToFirst();
    getResultsFromPhoneCursor(phones, accountName);

}

    public void getResultsFromPhoneCursor(Cursor phones, String accountName) {

    int colorcounter = 0;
    String[] colorcounter_array = {"#91A46B", "#8BB6B5", "#CAA973", "#8DA6C8", "#D19B8D"};

    int color_string;
    String email_Id = "";
    String contactType = "";

    try {
        contactId = 0;
        String hasPhone = "";
        display_name = "";
        phoneNumber = "";

        contactId = phones.getLong(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
        display_name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)).trim();

        hasPhone = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER));

        if (hasPhone.equalsIgnoreCase("1"))
            hasPhone = "true";

        else
            hasPhone = "false";

        if (Boolean.parseBoolean(hasPhone)) {
            do {

                this.accountName = phones.getString(phones.getColumnIndex("account_name"));
                phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));

                switch (type) {
                    case Phone.TYPE_HOME:
                        contactType = "HOME";
                        break;
                    case Phone.TYPE_MOBILE:
                        contactType = "MOBILE";
                        break;
                    case Phone.TYPE_WORK:
                        contactType = "WORK";
                        break;
                }

                String lookupKey = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));

                if (colorcounter < 5) {
                    color_string = Color.parseColor(colorcounter_array[colorcounter]);
                    colorcounter++;
                } else {
                    colorcounter = 0;
                    color_string = Color.parseColor(colorcounter_array[colorcounter]);
                    colorcounter++;
                }

                Cursor emails = cResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Email.DATA},
                        ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId, null, null);

                while (emails.moveToNext()) {
                    email_Id = emails.getString(emails
                            .getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                }

                emails.close();

                if (this.accountName.equalsIgnoreCase(accountName)) {

                    if (!contactList.contains(new ContactsWrapper(contactId, display_name, phoneNumber, lookupKey, false, color_string, email_Id, contactType)))
                        contactList.add(new ContactsWrapper(contactId, display_name, phoneNumber, lookupKey, false, color_string, email_Id, contactType));
                }
            }

            while (phones.moveToNext());
            phones.close();
        }
    } catch (Exception e) {

        e.printStackTrace();
    }

}

please help me to solve this case or suggest any other ways to get the contact_ids . Thanks in Advance.


Solution

  • The problem is that you are loosing the first contact you fetch from the db.

    The statement rawCursor.moveToFirst(); positions the cursor on the first available result record. The, when you want to iterate over the results, you call rawCursor.moveToNext() inside your loop. The loop condition is executed before it's body, so, you end up moving the cursor to the second row, loosing the first record.

    You can fix this by getting rid of rawCursor.moveToFirst().