Question

I have an activity that extends ExpandableListActivity. I have no issues when I run the application on Android 2.2+. However, when I run it on an Android 2.1 emulator, this activity force closes (the other activities in the app have no issues). I am completely stumped.

I have created a custom adapter to use with the ExpandableListView that extends SimpleCursorTreeAdapter. I am setting up the list adapter using the following code:

customExpandableListAdapter = new BeerFlightsExpandableListAdapter(
                                    this,                                           // context
                                    beerFlights,                                    // cursor
                                    R.layout.beer_flight_list_item,                 // group layout
                                    new String[]{"_id", "name"},                    // group FROM
                                    new int[] {R.id.flight_id, R.id.flight_name},   // group TO
                                    R.layout.beer_flight_beer_list_item,            // child layout
                                    new String[]{"_id", "name"},                    // child FROM
                                    new int[]{R.id.beer_id, R.id.beer_name});       // child TO
setListAdapter(customExpandableListAdapter);

I am using the following code to get the group cursor:

String sql =
        "SELECT beer_flights._id, beer_flights.name, COUNT(beer_flight_beers.beer_id) AS beer_count"+
        " FROM beer_flight_beers"+
            " INNER JOIN beer_flights ON beer_flight_beers.beer_flight_id = beer_flights._id"+
            " INNER JOIN beer_locations ON beer_flights.location_id = beer_locations.location_id AND beer_locations.beer_id = beer_flight_beers.beer_id"+
        " WHERE beer_flights.location_id = ?"+
        " GROUP BY beer_flights._id"+
        " ORDER BY beer_flights.priority ASC";

Cursor cur = db.rawQuery(sql, new String[]{ locationId.toString() });

I am using the following code to get the child cursor:

String sql =
        "SELECT DISTINCT beers._id, beers.name, beers.brewery"+
        " FROM beer_flight_beers"+
            " INNER JOIN beers ON beer_flight_beers.beer_id = beers._id"+
            " INNER JOIN beer_flights ON beer_flight_beers.beer_flight_id = beer_flights._id"+
            " INNER JOIN beer_locations ON beer_flights.location_id = beer_locations.location_id AND beer_flight_beers.beer_id = beer_locations.beer_id"+
        " WHERE beer_flight_beers.beer_flight_id = ?"+
        " ORDER BY beers.name ASC";

Cursor cur = db.rawQuery(sql, new String[]{ flightId.toString() });

As I said, this works perfectly in the emulators for Android 2.2+ as well as on my Droid 2 running 2.3.3 and my Droid 4 running 2.3.6. However, when I run the same code in an Android 2.1 emulator, I get the following error:

Uncaught handler: thread main exiting due to uncaught exception
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.absolutemg.jlbeers/com.absolutemg.jlbeers.BeerFlights}:
java.lang.IllegalArgumentException: column 'name' does not exist

[snip]

Caused by: java.lang.IllegalArgumentException: column 'name' does not exist
at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
at android.widget.SimpleCursorTreeAdapter.initFromColumns(SimpleCursorTreeAdapter.java:194)
at android.widget.SimpleCursorTreeAdapter.initGroupFromColumns(SimpleCursorTreeAdapter.java:200)
at android.widget.SimpleCursorTreeAdapter.init(SimpleCursorTreeAdapter.java:180)
at android.widget.SimpleCursorTreeAdapter.<init>(SimpleCursorTreeAdapter.java:169)
at com.absolutemg.jlbeers.BeerFlights$BeerFlightsExpandableListAdapter.<init>(BeerFlights.java:395)
at com.absolutemg.jlbeers.BeerFlights.onCreate(BeerFlights.java:100)

Both cursors have columns of _id and name. So I'm not sure why I'm getting an error saying that column 'name' does not exist.

I tweaked things to change the parent cursor to return columns of flight_id and flight_name and changed the list adapter accordingly. When I did, then the activity no longer crashed. It displayed my group names. However, when I clicked on on of the groups to open it up, it force closed again.

These same changes caused the activity to force close in Android 2.2+ (I'm assuming because I don't have a column named _id in my cursor). So this really isn't a fix.

Was there something different with cursors or the rawQuery() function in 2.1 that was changed in 2.2? I'm at a complete loss here as to how to fix this issue.

I'd love to drop support for Android 2.1 for this app, but we do have some users running 2.1 (it's only about 1.26% of our user base, but I don't want to exclude anyone from the updated app).

None of the other questions I've found here in SO have been quite the same as this, and I've had no luck finding anything anywhere else. Any ideas?

Was it helpful?

Solution

I managed to fix things ... only a few minutes after posting. And the solution makes me feel like a fool. :(

I modified the queries for my cursors to explicitly set the column name, like so:

Group Cursor

SELECT beer_flights._id AS _id, beer_flights.name AS name, COUNT(beer_flight_beers.beer_id) AS beer_count

Child Cursor

SELECT DISTINCT beers._id AS _id, beers.name AS name, beers.brewery AS brewery

After I did that, everything worked as it was supposed to in all versions of Android that I am testing.

Does anyone have any clue WHY I need to do that for Android 2.1 but not for any later version? It seems silly to me, but that's what fixed things.

Maybe it was because the query has the table names prefixing the columns. That's my only guess at this point.

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