App Crashes On Startup Due To java.lang.IllegalArgumentException: column ‘_id’ does not exist

I had a similar issue – I think it’s a case of having to ‘select’ (or ‘select as’) something called _id because the SimpleCursorAdapter needs it.

From the documentation:

Handling content URI IDs

By convention, providers offer access to a single row in a table by
accepting a content URI with an ID value for the row at the end of the
URI. Also by convention, providers match the ID value to the table’s
_ID column, and perform the requested access against the row that matches.

This convention facilitates a common design pattern for apps accessing
a provider. The app does a query against the provider and displays the
resulting Cursor in a ListView using a CursorAdapter. The definition
of CursorAdapter requires one of the columns in the Cursor to be _ID.

In my case, I have an autonumber column in my table called ‘oid’ so I altered my SELECT command to be (for example)…

SELECT oid as _id, name, number FROM mytable

This cured the problem for me.

EDIT to show more extensive code…

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.channel_selector);

    GridView channel_selector_grid = (GridView) findViewById(R.id.channel_grid);
    sca = getGuideAdapter();
    channel_selector_grid.setAdapter(sca);
}

public SimpleCursorAdapter getGuideAdapter() {
    SimpleCursorAdapter adapter = null;
    SQLiteDatabase db = SQLiteDatabaseHelper.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT DISTINCT oid as _id, name, number FROM CHAN_TABLE ORDER BY number", null);
    if (cursor.moveToFirst()) {
        String[] columnNames = { "name" };
        int[] resIds = { R.id.channel_name };
        adapter = new SimpleCursorAdapter(this, R.layout.channel_selector_item, cursor, columnNames, resIds);
    }
    return adapter; 
}

Leave a Comment