La aplicación se bloquea al iniciar debido a java.lang.IllegalArgumentException: la columna ‘_id’ no existe

Cada vez que inicio mi aplicación, obtengo un java.lang.IllegalArgumentException: column '_id' does not exist error en mi LogCat. He creado la columna '_id' , pero aún arroja esto. Aquí está mi principal .java:

 package com.gantt.shoppinglist; import android.app.Dialog; import android.app.ListActivity; import android.database.Cursor; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleCursorAdapter; public class ShoppingList extends ListActivity { private DataHelper DataHelper; /** Called when the activity is first created. */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); DataHelper = new DataHelper(this); Cursor c = (Cursor) DataHelper.selectAll(); long id = c.getLong(c.getColumnIndex("_id")); startManagingCursor(c); ListView lv = (ListView) findViewById(android.R.id.list); String[] from = new String[] { com.gantt.shoppinglist.DataHelper.getDatabaseName() }; int[] to = new int[] { android.R.id.text1 }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, c, from, to); lv.setAdapter(adapter); Button button1main = (Button) findViewById(R.id.add); button1main.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final Dialog additem = new Dialog(ShoppingList.this); additem.setContentView(R.layout.maindialog); final EditText et = (EditText)additem.findViewById(R.id.edittext); additem.setTitle("Type your item"); additem.setCancelable(true); et.setHint("Type the name of an item..."); Button button = (Button) additem.findViewById(R.id.cancel); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { additem.dismiss(); } }); additem.show(); Button ok = (Button) additem.findViewById(R.id.ok); ok.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final String text = et.getText().toString(); additem.dismiss(); et.setText(""); } }); } }); } } 

Aquí está mi clase DataHelper:

 package com.gantt.shoppinglist; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; import android.util.Log; public class DataHelper { private static final String DATABASE_NAME = "items.db"; private static final int DATABASE_VERSION = 1; private static final String TABLE_NAME = "table1"; public static final String KEY_ROWID = "_id"; private Context context; private SQLiteDatabase db; private SQLiteStatement insertStmt; private static final String INSERT = "insert into " + TABLE_NAME + "(name) values (?)"; public DataHelper(Context context) { this.context = context; OpenHelper openHelper = new OpenHelper(this.context); this.db = openHelper.getWritableDatabase(); this.insertStmt = this.db.compileStatement(INSERT); } public long insert(String name) { this.insertStmt.bindString(1, name); return this.insertStmt.executeInsert(); } public void deleteAll() { this.db.delete(TABLE_NAME, null, null); } public Cursor selectAll() { List list = new ArrayList(); Cursor cursor = this.db.query(TABLE_NAME, new String[] { "name" }, null, null, null, null, "name desc"); if (cursor.moveToFirst()) { do { list.add(cursor.getString(0)); } while (cursor.moveToNext()); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } return cursor; } public static String getDatabaseName() { return DATABASE_NAME; } private static class OpenHelper extends SQLiteOpenHelper { OpenHelper(Context context) { super(context, getDatabaseName(), null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY, name TEXT"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w("Example", "Upgrading database, this will drop tables and recreate."); db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } } } 

Tuve un problema similar: creo que se trata de tener que ‘seleccionar’ (o ‘seleccionar como’) algo llamado _id porque SimpleCursorAdapter necesita.

De la documentación :

Manejo de ID de URI de contenido

Por convención, los proveedores ofrecen acceso a una sola fila en una tabla al aceptar un URI de contenido con un valor de ID para la fila al final del URI. También por convención, los proveedores coinciden con el valor de ID de la columna _ID la tabla y realizan el acceso solicitado en la fila que coincide.

Esta convención facilita un patrón de diseño común para las aplicaciones que acceden a un proveedor. La aplicación hace una consulta en contra del proveedor y muestra el Cursor resultante en un ListView usando un CursorAdapter . La definición de CursorAdapter requiere que una de las columnas en el Cursor sea _ID .

En mi caso, tengo una columna de autonumeración en mi tabla llamada ‘oid’, así que modifiqué mi comando SELECT para ser (por ejemplo) …

 SELECT oid as _id, name, number FROM mytable 

Esto me solucionó el problema.

EDITAR para mostrar un código más extenso …

 @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; } 

No estoy seguro si acabas de pegarlo mal pero:

  DataHelper = new DataHelper(this); Cursor c = (Cursor) DataHelper.selectAll(); 

Está Mal. Debe declararlo a un objeto y llamar a sus métodos en el objeto DataBase inicializado:

  DataHelper dataHelper = new DataHelper(this); Cursor c = (Cursor) dataHelper.selectAll(); 

Oh, es malo, acabas de declarar tu nombre de variable con una D en mayúscula, esto no es recomendable ni el estilo estándar de encoding Java.

http://java.about.com/od/javasyntax/a/nameconventions.htm