0

I am getting an error when trying to utilize a multi-table SQL adapter for an Android application. I have searched the site and the internet, and have yet to find a solution.

Here is the LogCat stack that I get when I get the error:

    12-07 00:02:56.696: E/AndroidRuntime(31297): FATAL EXCEPTION: main
    12-07 00:02:56.696: E/AndroidRuntime(31297): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tma.android.recipebox/com.tma.android.recipebox.MealHomeActivity}: java.lang.IllegalArgumentException: column '_id' does not exist
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.app.ActivityThread.access$500(ActivityThread.java:122)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at   android.os.Handler.dispatchMessage(Handler.java:99)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.os.Looper.loop(Looper.java:132)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.app.ActivityThread.main(ActivityThread.java:4123)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at java.lang.reflect.Method.invokeNative(Native Method)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at java.lang.reflect.Method.invoke(Method.java:491)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at dalvik.system.NativeStart.main(Native Method)
    12-07 00:02:56.696: E/AndroidRuntime(31297): Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at  android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:299)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.widget.CursorAdapter.init(CursorAdapter.java:169)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.widget.CursorAdapter.<init>(CursorAdapter.java:117)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.widget.ResourceCursorAdapter.<init>(ResourceCursorAdapter.java:52)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:78)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at com.tma.android.recipebox.MealHomeActivity.fillData(MealHomeActivity.java:38)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at com.tma.android.recipebox.MealHomeActivity.onCreate(MealHomeActivity.java:28)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.app.Activity.performCreate(Activity.java:4397)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at  android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
    12-07 00:02:56.696: E/AndroidRuntime(31297):    ... 11 more

The LogCat doesn't seem to give me a specific line number in the activity that is causing the error, so I will post the whole thing I suppose:

package com.tma.android.recipebox;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.SimpleCursorAdapter;

public class MealHomeActivity extends ListActivity {

private Button mAddButton;
private MyDbAdapter mDbHelper;

private static final int ACTIVITY_EDIT = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.meal_home);
    mDbHelper = new MyDbAdapter(this);
    mDbHelper.open();

    setButtonClickListeners();
    fillData();
}

private void fillData() {
    Cursor mealCursor = mDbHelper.fetchAllMeals();
    startManagingCursor(mealCursor);

    String[] from = new String[]{MyDbAdapter.KEY_TITLE, MyDbAdapter.KEY_MEALDATE};
    int[] to = new int[]{R.id.text1, R.id.text2};

    SimpleCursorAdapter meals = new SimpleCursorAdapter(this, R.layout.meal_row, mealCursor, from, to);
    setListAdapter(meals);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    MenuInflater mi = getMenuInflater();
    mi.inflate(R.menu.meal_list_menu, menu);
    return true;
}

private void createMeal() {
    Intent i = new Intent(this, MealEditActivity.class);
    startActivityForResult(i, ACTIVITY_EDIT);
}

private void setButtonClickListeners() {
    mAddButton = (Button) findViewById(R.id.add_button);
    mAddButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            createMeal();
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    fillData();
}

}

I will also post the creation statements in my DbAdapter:

package com.tma.android.recipebox;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class MyDbAdapter {

private static final String TAG = "MyDbAdapter";
private static final String DATABASE_NAME = "recipe_box";
private static final int DATABASE_VERSION = 4;

private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;

/**
 * Recipe Table Constants
 */

private static final String DATABASE_TABLE = "recipes";
public static final String KEY_NAME = "name";
public static final String KEY_ING = "ingredients";
public static final String KEY_PREP = "preparation";
public static final String KEY_DATE = "date";
public static final String KEY_ROWID = "_id";

/**
 * Meal table constants
 */

private static final String DATABASE2_TABLE = "meals";
public static final String KEY_TITLE = "title";
public static final String KEY_RECIPES = "recipes";
public static final String KEY_MEALDATE = "date";
public static final String KEY_MEALID = "mealId";

/**
 * creation statement for the Recipe table
 */

private static final String CREATE_RECIPE_TABLE = "create table " + DATABASE_TABLE + "(_id integer primary key autoincrement," 
    + KEY_NAME + " text not null, " + KEY_ING + " text not null, " + KEY_PREP + 
    " text not null, " + KEY_DATE + " text not null);";

/**
 * creation statement for the Meal table
 */

private static final String CREATE_MEAL_TABLE = "create table " + DATABASE2_TABLE + "( " + KEY_MEALID 
    + " integer primary key autoincrement," + KEY_TITLE + " text not null, " + KEY_RECIPES + " text not null, " +
    KEY_MEALDATE + " text not null);";

Please let me know if I need to post anything else that might help you answer my question.

2

1 Answer 1

2

CursorAdapters need to have a cursor which has _id column. If you don't have a _id column in your database, just select your primary key (in your case I guess its mealId), mealId as _id. You should be good to go.

Sign up to request clarification or add additional context in comments.

4 Comments

Where do I use mealId as _id? If I simply changed mealId to _id, would that solve my problem?
Yes, provided you can do it. In many cases we cannot chagne the primary key, in those cases you can use the as query.
Where exactly do I use mealId as _id? In the creation statement?
I'm sorry to seem thick, but I don't know that much about SQL. How do I implement a SELECT statement?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.