Search code examples
androidsqlcursor

Android ContentResolver.query() throwing exception when passing a String[] projection argument


In my current Android project I'm facing with a strange error.

Everytime I issue the query method I get errors saying that the columns of the passed projection String[] argument don't exist (_id column field comprised). Despite this, passing null (hence allowing all columns to be returned) works fine, so I must assume this is not a problem of column names mismatch. Also, when retrieving data from a Cursor object, the column names are not giving any problems, since I can safely get all of the data by specifying the same column names on query().

I'm currently querying on the MediaStore.Audio.* database, and all the permissions within the Manifest file and eventual settings are ok.

This is my code snippet:

  Cursor        artists[] = new Cursor[2];

        String  projection[] = {
                Audio.Artists.ARTIST,
                Audio.Artists.NUMBER_OF_ALBUMS,
                Audio.Artists.NUMBER_OF_TRACKS,
        };

    artists[0] = this.getActivity().getApplicationContext().getContentResolver().query(
                    Audio.Artists.INTERNAL_CONTENT_URI,
                    projection,
                    null,
                    null,
                    Audio.Artists.DEFAULT_SORT_ORDER
                    );

    artists[1] = this.getActivity().getApplicationContext().getContentResolver().query(
                    Audio.Artists.EXTERNAL_CONTENT_URI,
                    projection,
                    null,
                    null,
                    Audio.Artists.DEFAULT_SORT_ORDER
                    );

            this.adapter = new ArtistListAdapter(this.getActivity(), new MergeCursor(artists));

Just to make it clear, here's where I use the Cursor object:

@Override
public void bindView (View v, Context c, Cursor cursor) {
    ImageView   icon;
    TextView    name, artistInfo;

    //icon = (ImageView) v.findViewById(R.id.artist_icon);
    name = (TextView) v.findViewById(R.id.artist_name);
    artistInfo = (TextView) v.findViewById(R.id.artist_info);

    //icon.setIcon(icon);
    name.setText(cursor.getString(cursor.getColumnIndex(Audio.Artists.ARTIST)));
    artistInfo.setText(
            String.format(
                    "%s total albums\n%s total songs",
                    cursor.getString(cursor.getColumnIndex(Audio.Artists.NUMBER_OF_ALBUMS)),
                    cursor.getString(cursor.getColumnIndex(Audio.Artists.NUMBER_OF_TRACKS))
            )
    );
}

Issuing this code, I receive the following error:

07-11 21:28:31.221: E/AndroidRuntime(22737): FATAL EXCEPTION: main
07-11 21:28:31.221: E/AndroidRuntime(22737): java.lang.IllegalArgumentException: column '_id' does not exist
07-11 21:28:31.221: E/AndroidRuntime(22737):    at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
07-11 21:28:31.221: E/AndroidRuntime(22737):    at android.support.v4.widget.CursorAdapter.init(CursorAdapter.java:174)

What can be the cause of this problem and how can I fix it? Until now, I've been passing null on the projection arguments, but I don't want to retrieve content I won't be using.

Please ask if you need further informations.


Solution

  • add BaseColumns._ID to projection array. this is the required column when using the CursorAdapter (and i'm assuming from the context that you are using SimpleCursorAdapter)