Question

I am trying to create a simple contact list app. When I want to create a new contact and enter the fields of the contact and press the save button, I encounter an error of "Illegal exception column id does not exist".

I am using the simple cursor adapter to show the data from database to list widget.

Here is my source code:

    public class WebpreneurActivity extends ListActivity {

    private static final int CONTACT_CREATE = 0;
    private static final int CONTACT_EDIT = 1;

    //select the second one, Android view menu
    private static final int INSERT_ID = Menu.FIRST;
    private static final int DELETE_ID = Menu.FIRST + 1;

    private DBHandler dbHelper;
    private Cursor c;
    ImageButton imageButton;
    long rowid;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("database1" ,"0");
        Log.d("Your Location4", "ok4:");
        super.onCreate(savedInstanceState);
        Log.d("database1" ,"1");
        setContentView(R.layout.activity_webpreneur);
        Log.d("database1" ,"2");
        dbHelper = new DBHandler(this);
        Log.d("database1" ,"3");
        dbHelper.open();
        //addListenerOnButton();
        //dbHelper.addContact();

        imageButton = (ImageButton) findViewById(R.id.imageButton1);
        Log.d("database1" ,"button");
        imageButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                Log.d("database1" ,"b4");
                Intent i = new Intent(getApplicationContext(), ContactEdit.class);
                startActivityForResult(i, CONTACT_CREATE);

                Log.d("database1" ,"button3");
                //fillData();

            }

        });

        //dbHelper.close();
    }   

    @SuppressWarnings("deprecation")
    public void fillData() {
        Log.d("Your Location4", "ok6:");
        c = dbHelper.fetchAllRows();
        Log.d("Your Location4", "ok8:");
        startManagingCursor(c);
        Log.d("Your Location4", "ok2:");
        // point of error !!!!
        //////      ListAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.contact_row, c, new String[] { DBHandler.Key_Name,
                        DBHandler.Key_Phone }, new int[] { R.id.name,
                        R.id.phonenumber });
        setListAdapter(adapter);
    }

    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        Intent i = new Intent(this, ContactEdit.class);
        i.putExtra(DBHandler.Key_ID, c.getLong(c.getColumnIndex(DBHandler.Key_ID)));
        i.putExtra(DBHandler.Key_Name, c.getString(c.getColumnIndex(DBHandler.Key_Name)));
        i.putExtra(DBHandler.Key_Address, c.getString(c.getColumnIndex(DBHandler.Key_Address)));
        i.putExtra(DBHandler.Key_Phone, c.getString(c.getColumnIndex(DBHandler.Key_Phone)));
        i.putExtra(DBHandler.Key_Website, c.getString(c.getColumnIndex(DBHandler.Key_Home)));
        startActivityForResult(i, CONTACT_EDIT);
    }

    protected void onActivityResult(int requestCode, int resultCode,
            Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            String name = data.getStringExtra(DBHandler.Key_Name);
            String address = data.getStringExtra(DBHandler.Key_Address);
            String mobile = data.getStringExtra(DBHandler.Key_Phone);
            String home = data.getStringExtra(DBHandler.Key_Home);
            switch (requestCode) {
                case CONTACT_CREATE:
                    Log.d("Your Location4", "jj:");
                    dbHelper.createRow(name, address, mobile, home);
                    Log.d("Your Location4", "ok90:");
                    fillData();
                    break;
                case CONTACT_EDIT:

                     String id = data.getStringExtra(DBHandler.Key_ID);


                     long rowId=Long.parseLong(id);

                    if (rowId != (Long)null){
                        dbHelper.updateRow(rowId, name, address, mobile, home);
                    }
                    fillData();
                    break;

            }
        }
    }
}

HERE IS MY LOG CAT

01-28 13:34:34.841: D/AndroidRuntime(24324): Shutting down VM
        01-28 13:34:34.841: W/dalvikvm(24324): threadid=1: thread exiting with uncaught exception (group=0x4001d578)
        01-28 13:34:34.871: E/AndroidRuntime(24324): FATAL EXCEPTION: main
        01-28 13:34:34.871: E/AndroidRuntime(24324): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { (has extras) }} to activity {com.webpreneur_contactlist/com.webpreneur_contactlist.WebpreneurActivity}: java.lang.IllegalArgumentException: column '_id' does not exist
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.app.ActivityThread.deliverResults(ActivityThread.java:2553)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:2595)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.app.ActivityThread.access$2000(ActivityThread.java:121)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:973)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.os.Handler.dispatchMessage(Handler.java:99)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.os.Looper.loop(Looper.java:138)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.app.ActivityThread.main(ActivityThread.java:3701)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at java.lang.reflect.Method.invokeNative(Native Method)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at java.lang.reflect.Method.invoke(Method.java:507)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at dalvik.system.NativeStart.main(Native Method)
        01-28 13:34:34.871: E/AndroidRuntime(24324): Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.support.v4.widget.CursorAdapter.init(CursorAdapter.java:174)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.support.v4.widget.CursorAdapter.<init>(CursorAdapter.java:122)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.support.v4.widget.ResourceCursorAdapter.<init>(ResourceCursorAdapter.java:54)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.support.v4.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:63)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at com.webpreneur_contactlist.WebpreneurActivity.fillData(WebpreneurActivity.java:82)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at com.webpreneur_contactlist.WebpreneurActivity.onActivityResult(WebpreneurActivity.java:117)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.app.Activity.dispatchActivityResult(Activity.java:3908)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    at android.app.ActivityThread.deliverResults(ActivityThread.java:2549)
        01-28 13:34:34.871: E/AndroidRuntime(24324):    ... 11 more

my Dbhandler class ///////////////// public class DBHandler extends SQLiteOpenHelper{

    private static final int DB_Version = 1;

    private static final String DB_Name = "Places";

    protected static final String Places_Table = "Places";
    private String DB_PATH=""; 

    String name, Address, Website,ID;
    //WebpreneurActivity Contact;
 public static final String Key_ID = "ID";
 public static final String Key_Name = "Name";
 public static final String Key_Phone = "Phone";
 public  static final String Key_Address = "Address";
 public static final String Key_Website = "Website";
 public  static final String Key_Home = "HOME";
 public static final String PROJECTION[] = {
    Key_ID,
    Key_Name,
    Key_Address,
    Key_Phone,
    Key_Home
};

    String CREATE_PLACES_TABLE = "create table if not exists Places_Table (id integer primary key ,"+
            "name VARCHAR not null, phone VARCHAR not null, address VARCAHR not null, website VARCHAR not null,Home VARCHAR not null)";

     private final Context context;
    private static SQLiteDatabase db;

    public DBHandler(Context context) {

        super(context, DB_Name, null, DB_Version);
        this.context = context;  
         DB_PATH = "/data/data/" + context.getPackageName() + "/" + "databases/"; 
        Log.d("database1" ,"4");
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        try{
            Log.d("DB", "DB creationnewwwww");
                db.execSQL("CREATE TABLE  " + Places_Table + " (" +
                        Key_ID + " INTEGER PRIMARY KEY autoincrement," +
                        Key_Name + " TEXT NOT NULL," +
                        Key_Phone + " TEXT NOT NULL," +
                        Key_Address + " TEXT NOT NULL," +
                        Key_Website + " TEXT," +
                        Key_Home + " TEXT)");
                Log.d("DB", "DB creationnewwwwwwwwwwwwwwwwwwwwwwwwwww");
        }
        catch(SQLiteException e){
            Log.d("DB", "DB creation excptionhhhhhhhhhhhhhhh");
            e.printStackTrace();
        }

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

        db.execSQL("Drop Table If Exists" + Places_Table);
        onCreate(db);
    }

     /* void addContact() {
            SQLiteDatabase db = this.getWritableDatabase();

            ContentValues values = new ContentValues();
            values.put(Key_Name,Name); // Contact Name
            values.put(KEY_COST,cost); // Contact Phone
            values.put(Key_Address, contact.Address); //Contact phone no

            // Inserting Row
            db.insert(Places_Table, null, values);
            db.close(); // Closing database connection
        }*/

    public void open()
    {Log.d("DB", "DB creation 9");
     db = this.getWritableDatabase();
        //onCreate(db);
    Log.d("DB", "DB creation 9");
    String myPath = DB_PATH + DB_Name;
    db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    }
    @Override
    public synchronized void close() { 
       if(db != null)
            db.close(); 
        super.close(); 
    }

    //Adding Places 
    void addPlaces( int id, String name,String phone, String address,String url){

        Log.d("DB", "DB creation 1");
        //SinglePlaceActivity single = new SinglePlaceActivity();   Log.d("DB", "DB creation 2");
        ContentValues contentValues = new ContentValues();
        Log.d("DB", "DB creation 3");
        contentValues.put(Key_ID, id);
        Log.d("DB", "DB creation 4");
        contentValues.put(Key_Name, name);
        contentValues.put(Key_Phone, phone);
        contentValues.put(Key_Address, address);
        contentValues.put(Key_Website, url);
        Log.d("DB", "DB creation 4");
        db.insert(Places_Table, null, contentValues);
        Log.d("DB", "DB creation 5555");
        //db.close();
    }

    public String getdata() {
        // TODO Auto-generated method stub
        String [] columns =new String[]{Key_ID ,Key_Name,Key_Address,Key_Website};
        Cursor c =db.query(DB_Name, columns, null, null, null, null, null);
        String Result=""; 
        int iRow=c.getColumnIndex(Key_ID);
        int iName=c.getColumnIndex(Key_Name);
        int iAddress=c.getColumnIndex(Key_Address);
        int iWebsite=c.getColumnIndex(Key_Website);
        for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
            Result=Result+c.getString(iRow)+"    "+c.getString(iName)+ "  "+c.getString(iAddress)+ "   "+c.getString(iWebsite)+ "\n";
        }

        return Result;
    }   


    public void createRow(String name, String address, String Phone, String home)
    {SQLiteDatabase db = this.getWritableDatabase();
        ContentValues initialValues = new ContentValues();
        initialValues.put(Key_Name, name);
        initialValues.put(Key_Address, address);
        initialValues.put(Key_Phone, Phone);
        initialValues.put(Key_Home, home);
                //pass the initialValues to the database to insert the row
        Log.d(Key_Home, home);
        db.insert(Places_Table, null, initialValues);
        Log.d("Your Location4", "okna:");
    }

        public void deleteRow(long rowId){
        db.delete(Places_Table, Key_ID+"="+rowId,null);
    }

        public boolean updateRow (long rowId, String name, String address, String Phone, String home){
        ContentValues args = new ContentValues();
        args.put(Key_Name, name);
        args.put(Key_Address, address);
        args.put(Key_Phone, Phone);
        args.put(Key_Home, home);
        return db.update(Places_Table, args, Key_ID +"="+ rowId, null)>0;
    }
        public Cursor fetchRow(long rowId) throws SQLException{
            Cursor result = db.query( Places_Table, null, 
                    Key_ID + "=" + rowId, null, null, null,null);
            if ((result.equals(rowId)) || !result.isFirst()) {
                throw new SQLException("No note matching ID: " + rowId);
            }
            return result;
        }

        public Cursor fetchAllRows(){
            Log.d("Your Location4", "ok99:");
            return db.query(Places_Table, PROJECTION, 
                    null, null, null, null, null);

        }

}
Was it helpful?

Solution

The Cursor Adapter needs an _id field in the Cursor to work. http://developer.android.com/reference/android/widget/CursorAdapter.html

What you could use is the following CursorWrapper that lets you set _idto whatever field you want. https://groups.google.com/d/msg/ormlite-user/SbRoHIov5pI/-8Ir3pEycw0J

As stated by the google user jc:

/** 
 * A {@link CursorWrapper} implementation that allows a {@link Cursor} 
 * without a field named "_id" to be used with various Android {@link ListView} 
 * classes that expect a column named "_id".  This is done by specifying an 
 * alias field name to be used in place of "_id". 
 * 
 * @author j_...@users.sourceforge.net 
 */ 
public class NoIdCursorWrapper extends CursorWrapper { 

    private int idColumnIndex; 

    /** 
     * Create a NoIdCursorWrapper using the alias column index. 
     * @param c the cursor to wrap 
     * @param idColumnIndex the column index to use as the _id column 
       alias 
     */ 
    public NoIdCursorWrapper(Cursor c, int idColumnIndex) { 
            super(c); 
            this.idColumnIndex = idColumnIndex; 
    } 

    /** 
     * Create a NoIdCursorWrapper using the alias column name. 
     * @param c the cursor to wrap 
     * @param idColumnName the column name to use as the _id column alias 
     */ 
    public NoIdCursorWrapper(Cursor c, String idColumnName) { 
            super(c); 
            idColumnIndex = c.getColumnIndex(idColumnName); 
    } 

    @Override 
    public int getColumnIndex(String columnName) { 
            int index = super.getColumnIndex(columnName); 
            if (index < 0 && "_id".equals(columnName)) { 
                    index = idColumnIndex; 
            } 
            return index; 
    }; 


    @Override 
    public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException { 
            int index = getColumnIndex(columnName); 
            if (index>=0) { 
                    return index; 
            } 
            // let the AbstractCursor generate the exception 
            return super.getColumnIndexOrThrow(columnName); 
    }; 

}

Then in your fillData

@SuppressWarnings("deprecation")
public void fillData() {
    Log.d("Your Location4", "ok6:");
    // Load the Cursor in the normal way
    c = dbHelper.fetchAllRows();
    // wrap the cursor in the NoIdCursorWrapper to handle the missing _id field
    // (int this case the DBHandler.Key_ID field will act as the _id) 
    NoIdCursorWrapper nc = new NoIdCursorWrapper(c, DBHandler.Key_ID);
    Log.d("Your Location4", "ok8:");
    startManagingCursor(c);
    Log.d("Your Location4", "ok2:");

    // Add the NoIdCursorWrapper instead of the Cursor itself
    ListAdapter adapter = new SimpleCursorAdapter(this, 
                    R.layout.contact_row, nc, new String[] { DBHandler.Key_Name,
                    DBHandler.Key_Phone }, new int[] { R.id.name,
                    R.id.phonenumber });
    setListAdapter(adapter);
}

OTHER TIPS

Your PROJECTION has a Key_ID which is "ID". All CursorAdapters require that there's a column with name "_id". You should really rename your id column to _id. As a quick workaround you can also make a column alias:

public static final String PROJECTION[] = {
    Key_ID + " AS _id",

You have to include the _id column in your adapter even if you don't display it.

ListAdapter adapter = new SimpleCursorAdapter(this,
    R.layout.contact_row, c, new String[] { "_id", DBHandler.Key_Name,
                    DBHandler.Key_Phone }, new int[] { R.id.name,
                    R.id.phonenumber });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top