recently that I use sqlite in android and I have a problem not solved.
I found a tutorial that explains how to run a database and works perfectly. I'm happy to have found. Now I want to implement a CursorAdapter to customize the listview containing the data of the DB ... but I always encounter the same error. I read a lot about it and I've met people (on this website) happens the same, but can not understand the answer. I have a couple of days with this problem.
First show the code, this is my main activity:
public class RegistrosActivity extends Activity {
private ListView listView;
private Adapter_bd_notificaciones customAdapter;
private SQLite sqlite;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_registros);
//
listView = (ListView) findViewById(R.id.lstRegistros);
//Open conexion sqlite
sqlite = new SQLite(this);
sqlite.abrir();
Cursor cursor = sqlite.getRegistros();
customAdapter = new Adapter_bd_notificaciones(RegistrosActivity.this, cursor);
listView.setAdapter(customAdapter);
}
// the rest of the code
}
The SQLite.java
public class SQLite {
private SQLiteHelper sqliteHelper;
private SQLiteDatabase db;
public SQLite(Context context)
{
sqliteHelper = new SQLiteHelper( context );
}
public void abrir(){
Log.i("SQLite", "Se abre conexion a la base de datos " + sqliteHelper.getDatabaseName() );
db = sqliteHelper.getWritableDatabase();
}
public void cerrar()
{
Log.i("SQLite", "Se cierra conexion a la base de datos " + sqliteHelper.getDatabaseName() );
sqliteHelper.close();
}
public boolean addRegistro( String nombre, String fecha, String pais, String sexo, String ingles )
{
if( nombre.length()> 0 )
{
ContentValues contentValues = new ContentValues();
contentValues.put( sqliteHelper.__campo_nombre , nombre);
contentValues.put( sqliteHelper.__campo_fechanac , fecha );
contentValues.put( sqliteHelper.__campo_pais , pais);
contentValues.put( sqliteHelper.__campo_sexo , sexo);
contentValues.put( sqliteHelper.__campo_ingles , ingles);
Log.i("SQLite", "Nuevo registro " );
return ( db.insert( sqliteHelper.__tabla__ , null, contentValues ) != -1 )?true:false;
}
else
return false;
}
public int getUltimoID()
{
int id = -1;
Cursor cursor = db.query( sqliteHelper.__tabla__ ,
new String[]{ sqliteHelper.__campo_id },
null, null, null,null,
sqliteHelper.__campo_id + " DESC ", "1");
if( cursor.moveToFirst() )
{
do
{
id = cursor.getInt(0);
} while ( cursor.moveToNext() );
}
return id;
}
public boolean borrar_registro( int id )
{
return (db.delete( sqliteHelper.__tabla__ , sqliteHelper.__campo_id + " = " + id , null) > 0) ? true:false;
}
public Cursor getRegistros()
{
return db.query( sqliteHelper.__tabla__ ,
new String[]{
sqliteHelper.__campo_id ,
sqliteHelper.__campo_nombre,
sqliteHelper.__campo_fechanac,
sqliteHelper.__campo_pais,
sqliteHelper.__campo_sexo,
sqliteHelper.__campo_ingles
},
null, null, null, null, null);
}
public Cursor getRegistro( int id )
{
return db.query( sqliteHelper.__tabla__ ,
new String[]{
sqliteHelper.__campo_id ,
sqliteHelper.__campo_nombre,
sqliteHelper.__campo_fechanac,
sqliteHelper.__campo_pais,
sqliteHelper.__campo_sexo,
sqliteHelper.__campo_ingles
},
sqliteHelper.__campo_id + " = " + id ,
null, null, null, null);
}
public ArrayList<String> getFormatListUniv( Cursor cursor )
{
ArrayList<String> listData = new ArrayList<String>();
String item = "";
if( cursor.moveToFirst() )
{
do
{
item += "ID: [" + cursor.getInt(0) + "]\r\n";
item += "Nombre: " + cursor.getString(1) + "\r\n";
item += "Fecha de Nacimiento: " + cursor.getString(2) + "\r\n";
item += "Pais: " + cursor.getString(3) + "\r\n";
item += "Sexo: " + cursor.getString(4) + "\r\n";
item += "Habla ingles: " + cursor.getString(5) + "";
listData.add( item );
item="";
} while ( cursor.moveToNext() );
}
return listData;
}
}
The SQLIteHelper.java
public class SQLiteHelper extends SQLiteOpenHelper {
private static final String __DATABASE = "dbUniversidad";
private static final int __VERSION = 3;
public final String __tabla__ = "Universitario";
public final String __campo_id = "id";
public final String __campo_nombre = "Nombre";
public final String __campo_fechanac = "FechaNac";
public final String __campo_pais = "Pais";
public final String __campo_sexo = "Sexo";
public final String __campo_ingles = "Ingles";
private final String sql = "CREATE TABLE " + __tabla__ + " ( " +
__campo_id + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
__campo_nombre + " TEXT NULL, " + __campo_fechanac + " TEXT, " + __campo_pais + " TEXT NULL, " +
__campo_sexo + " TEXT NULL, " + __campo_ingles + " TEXT NULL " +
" )";
public SQLiteHelper(Context context) {
super( context, __DATABASE, null, __VERSION );
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL( sql );
}
@Override
public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion ) {
if ( newVersion > oldVersion )
{
//elimina tabla
db.execSQL( "DROP TABLE IF EXISTS " + __tabla__ );
//y luego creamos la nueva tabla
db.execSQL( sql );
}
}
}
And as I said, after two days many variations and changes, read much about it, I always find the same error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{my.database.example/my.database.example.RegistrosActivity}: java.lang.IllegalArgumentException: column '_id' does not exist
I know that most people have been the same, but even reading the right answers, I do not know how to apply my code.
column '_id' does not exist
Please, can someone tell me how to make works correctly the CursorAdapter in my code? what line I'm missing? What am I doing wrong? I would be grateful if you could correct my code.
Thank you very much for the help.
Greetings!
PS. As if that were useful, this is the full error:
FATAL EXCEPTION: main
Process: my.database.example, PID: 31765
java.lang.RuntimeException: Unable to start activity ComponentInfo{my.database.example/my.database.example.RegistrosActivity}: java.lang.IllegalArgumentException: column '_id' does not exist
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
at android.widget.CursorAdapter.init(CursorAdapter.java:172)
at android.widget.CursorAdapter.<init>(CursorAdapter.java:120)
at my.database.example.Adapter_bd_notificaciones.<init>(Adapter_bd_notificaciones.java:15)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
As mentioned by Blackbelt in his comment, Android expects the primary identifier column to be named "_id".