Search code examples
androidandroid-contentproviderandroid-contactssqlexceptionandroid-contentresolver

"SQLiteException: no such column: mimetype" when using ContactsContract in Android


I want to delete an entry from Android's internal database table ContactsContract, i.e. an event such as a birthday should be removed from the contact's entry.

The following code works pretty well, but some users (ca. 1%) have this crashing with an SQLException. So is there anything wrong in my code or is it just that their device doesn't support Android's ContactsContract correctly?

try {
    ArrayList<Long> rawContactIDs = getRawContactID(o.getID());
    int rawContactCount = rawContactIDs.size();
    for (int r = 0; r < rawContactCount; r++) {
        long rawContactID = rawContactIDs.get(r);
        String where = ContactsContract.Data.MIMETYPE+" = ? AND "+ContactsContract.Data.RAW_CONTACT_ID+" = ? AND "+ContactsContract.CommonDataKinds.Event.TYPE+" = ?";
        String[] selection = new String[] { ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE, String.valueOf(MY_RAW_CONTACT_ID), String.valueOf(ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY) };
        getContentResolver().delete(ContactsContract.Data.CONTENT_URI, where, selection);
    }
}
catch (Exception e) {}

The exception that is thrown is:

android.database.sqlite.SQLiteException: no such column: mimetype: , while
compiling: DELETE FROM data WHERE mimetype = ? AND raw_contact_id = ? AND
data2 = ?
at
android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:158)
at
android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:114)
at
android.content.ContentProviderProxy.delete(ContentProviderNative.java:472)
at android.content.ContentResolver.delete(ContentResolver.java:700)
at ... MY_ACTIVITY ...

Solution

  • It is possible for device manufacturers to change the implementation of a ContentProvider that ships with the AOSP. In theory, those changes would be caught by the Compatibility Test Suite (CTS), so that only devices that don't break the API will run your app when shipped through the Play Store.

    That being said...

    • The CTS is far from complete
    • The CTS does not protect you if you intentionally distribute your app beyond the Play Store, and somebody with an incompatible device runs your app
    • The CTS does not protect you if you unintentionally distribute your app beyond the Play Store (i.e., your app's been pirated), and somebody with an incompatible device runs your app
    • Various device manufacturers pirate the Play Store app itself

    So, when you see problems that would appear to originate from within an OS-supplied ContentProvider, but those problems are infrequent and/or are on unrecognized devices, don't panic. You still might choose to somehow fail gracefully in this case (by wrapping the failing calls in your own exception handler), but it's unlikely that your code is really the source of the difficulty.