Question

I am trying to make a query that filters contacts, to retrieve only contacts that have a certain account type.

I am doing this using the following code that works on android 2.2 but does not work on newer androids(like android 4.4.2):

private void testQuery() {
    String selection = ContactsContract.Contacts._ID + " IN (" + "SELECT " +
            ContactsContract.RawContacts.CONTACT_ID + " FROM " + 
            "raw_contacts" + " WHERE " +
            ContactsContract.RawContacts.ACCOUNT_TYPE + " IS NULL OR " +
            ContactsContract.RawContacts.ACCOUNT_TYPE + " = 'com.google'" + ")";

    Cursor c = null;

    try {
        c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
            null,
            selection,
            null, null);
    } catch(Exception e) {
        e.printStackTrace();
    }

    if(c != null) {
        int indexName = c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 

        while(c.moveToNext()) {
            String name = c.getString(indexName);

            // TODO:
        }

        c.close();
    }
}

The problem is that it works on android 2.2 but it throws me an exception on newer android(android 4.4.2). The exception is: SQLiteException: no such column: account_type.

I don't know why this doesn't work on new androids but i think this is a security feature.

PROBLEM: Are there any workarounds for this issue i try to solve?

CURRENT SOLUTION: My current solution is that i make 2 querys, one in the raw_contact table and the other in the contact table. The problem with this approach is that it's very slow and clumsy and i can't use the nice CursorLoader that takes care of the reloading when the data is changed leading to very very ugly and hard to maintain code.

All help is appreciated.

UPDATE: See below for new solution.

Was it helpful?

Solution

I have solved the problem for both old androids and new androids. The problem was that i should have used the view "view_raw_contacts" instead of the table "raw_contacts". Works on all androids i have tested.

Updated selection:

String selection = ContactsContract.Contacts._ID + " IN (" + "SELECT " +
            ContactsContract.RawContacts.CONTACT_ID + " FROM " + 
            "view_raw_contacts" + " WHERE " +
            ContactsContract.RawContacts.ACCOUNT_TYPE + " IS NULL OR " +
            ContactsContract.RawContacts.ACCOUNT_TYPE + " = 'com.google'" + ")";

On the real device i extract the view name with a regex hoping that it would work on all devices, even on those who modified the contact provider.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top