Error trying to fetch data

Asked

Viewed 96 times

0

I have an application that should insert data in one screen and in the other consult in the bank

The problem is that whenever I try to execute the error query:

Log

11-16 18:43:31.023: I/ActivityManager(26887): Timeline: Activity_launch_request     id:br.com.exercicio8 time:58351239
11-16 18:43:31.103: D/AndroidRuntime(26887): Shutting down VM
11-16 18:43:31.103: W/dalvikvm(26887): threadid=1: thread exiting with uncaught    exception (group=0x41996d88)
11-16 18:43:31.103: E/AndroidRuntime(26887): FATAL EXCEPTION: main
11-16 18:43:31.103: E/AndroidRuntime(26887): Process: br.com.exercicio8, PID: 26887
11-16 18:43:31.103: E/AndroidRuntime(26887): java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.exercicio8/br.com.exercicio8.LocalizacaoAtual}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2237)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2286)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.app.ActivityThread.access$800(ActivityThread.java:144)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.os.Handler.dispatchMessage(Handler.java:102)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.os.Looper.loop(Looper.java:212)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.app.ActivityThread.main(ActivityThread.java:5135)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at java.lang.reflect.Method.invokeNative(Native Method)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at java.lang.reflect.Method.invoke(Method.java:515)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at dalvik.system.NativeStart.main(Native Method)
11-16 18:43:31.103: E/AndroidRuntime(26887): Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.database.AbstractCursor.checkPosition(AbstractCursor.java:426)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at br.com.exercicio8.LocalizacaoAtual.onLocationChanged(LocalizacaoAtual.java:85)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at br.com.exercicio8.LocalizacaoAtual.onCreate(LocalizacaoAtual.java:46)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.app.Activity.performCreate(Activity.java:5231)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-16 18:43:31.103: E/AndroidRuntime(26887):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2201)
11-16 18:43:31.103: E/AndroidRuntime(26887):    ... 11 more

Code that runs from Sqliteopenhelper

public Cursor consult(int latiude, int longitude){
          SQLiteDatabase db = this.getReadableDatabase();
            String query = "select "+CADASTRO_COLUMN_NOMELOCAL+" from " + LOCATION_TABLE_NAME + " where + " + CADASTRO_COLUMN_LATITUDE + " = " + latiude + " AND "+ CADASTRO_COLUMN_LONGITUDE + " = " +longitude;
            Cursor registro = db.rawQuery(query, null); //objeto do sqllite que representa um objeto de qualquer tabela
            return registro;
       }

Code in class

@Override
public void onLocationChanged(Location location) {
    double lat = location.getLatitude();
    double lon = location.getLongitude();
    campoLat = (int)lat;
    campoLong = (int)lon;

    BD dbm = new BD(getApplicationContext());
    Cursor seleciona = dbm.consult(campoLat,campoLong);
    seleciona.moveToFirst();
    String aux = seleciona.getString(seleciona.getColumnIndex(BD.CADASTRO_COLUMN_NOMELOCAL));
    /*
    if(aux != "" || aux != null)
    {
        local.setText(aux);
    }
    else
    {
        local.setText("Local desconhecido");
    }*/

Bank code

 public class BD extends SQLiteOpenHelper {
   public static final String DATABASE_NAME = "location.db";
   public static final String LOCATION_TABLE_NAME = "cadastro";
   public static final String CADASTRO_COLUMN_NOMELOCAL = "nomeLocal";
   public static final String CADASTRO_COLUMN_LATITUDE = "latitude";
   public static final String CADASTRO_COLUMN_LONGITUDE = "longitude";

public BD(Context context) {

      super(context, DATABASE_NAME , null, 1);

}

@Override
public void onCreate(SQLiteDatabase db) {

     db.execSQL(
              "create table " + LOCATION_TABLE_NAME + 
              "(" +
                CADASTRO_COLUMN_NOMELOCAL + " text primary key, " +
                CADASTRO_COLUMN_LATITUDE + " text,"+
                CADASTRO_COLUMN_LONGITUDE + " text" +
              ")"
              );

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    String query = "drop table if exists "+ LOCATION_TABLE_NAME;
    db.execSQL(query);
    onCreate(db);
}


   @Override
public void onOpen(SQLiteDatabase db) {
        String query = "drop table if exists "+ LOCATION_TABLE_NAME;
        db.execSQL(query);
        onCreate(db);
}

public boolean insert (String nome, String latitude, String longitude)
   {
      SQLiteDatabase db = this.getWritableDatabase();
      ContentValues contentValues = new ContentValues();

      contentValues.put(CADASTRO_COLUMN_NOMELOCAL, nome);
      contentValues.put(CADASTRO_COLUMN_LATITUDE, latitude);
      contentValues.put(CADASTRO_COLUMN_LONGITUDE, longitude);  


      db.insert(LOCATION_TABLE_NAME, null, contentValues);
      return true;
   }

   public Cursor consult(int latiude, int longitude){
          SQLiteDatabase db = this.getReadableDatabase();
            String query = "select * from " + LOCATION_TABLE_NAME + " where " + CADASTRO_COLUMN_LATITUDE + " = " + latiude + " AND "+ CADASTRO_COLUMN_LONGITUDE + " = " +longitude;
            Cursor registro = db.rawQuery(query, null); //objeto do sqllite que representa um objeto de qualquer tabela
            return registro;
       }

}

Error occurs when running this line

 String aux = seleciona.getString(seleciona.getColumnIndex(BD.CADASTRO_COLUMN_NOMELOCAL));

To delete the table

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    String query = "delete table if exists "+ LOCATION_TABLE_NAME;
    db.execSQL(query);
    String queryy = "drop table if exists "+ LOCATION_TABLE_NAME;
    db.execSQL(queryy);
    onCreate(db);
}
  • 1

    The error means that the Cursor is empty. When using moveToFirst the cursor positions one position before the first line, you must execute one moveToNext to consult (with the getXYZ) the first and the other lines in sequence, checking if he did not return false or check using isAfterLast.

  • Thanks for the help Wakim, I just have a small problem, my bank is not being excluded when on onUpgrade, someone could help me?

  • The syntax of delete this wrong, missing the from. Also since you are dropping the table, you do not need to run the delete.

  • I tried only with the drop but the table continues, and in order to put a new value,when I start the app on my smartphone I have to go in settings -> Apps -> app -> Clear data

  • Aren’t you making a mistake? How is yours onCreate, may be included in the question?

  • Worse that does not indicate any error. Include the whole bank class

  • Are you incrementing the version every time you update the schema? It only runs the onUpgrade when this occurs. When do you want to delete the database? Every application deploy or every opening?

  • Preferably whenever the app is opened (if it is not possible it can be in the same deploy)

Show 3 more comments

1 answer

1

When you’re using the Cursor, should first use the moveToFirst. With this the cursor will point to before the first line.

To access the data, use moveToNext checking whether the return was true. For example:

BD dbm = new BD(getApplicationContext());
Cursor seleciona = dbm.consult(campoLat,campoLong);

seleciona.moveToFirst();

if(seleciona.moveToNext()) {
    String aux = seleciona.getString(seleciona.getColumnIndex(BD.CADASTRO_COLUMN_NOMELOCAL));

    // Restante do código que dependa de aux
}

If you want to iterate on the results:

BD dbm = new BD(getApplicationContext());
Cursor seleciona = dbm.consult(campoLat,campoLong);

seleciona.moveToFirst();

// Eh bom fazer o cache do índice, já que ele nunca muda e evitamos processamento desnecessário
int index = seleciona.getColumnIndex(BD.CADASTRO_COLUMN_NOMELOCAL);

while(seleciona.moveToNext()) {
    String aux = seleciona.getString(index);

    // Restante do codigo que dependa de aux
}

In the case of onUpgrade, the syntax of delete is incorrect. The correct would be:

delete from nome_tabela

Remembering that the command delete can’t stand it if exists.

Also since you are dropping the table, it is not necessary to delete the records before.

Edit:

To clear the bank when opening the app, just use the class Application.

Registering a class Application you can be notified of the beginning and end of your application. With this you can delete the records from the table.

Just create a subclass of android.app.Application and register it on AndroidManifest with the attribute name:

<application
    android:name="nome.do.seu.pacote.NomeDaApplication">

In his NomeDaApplication just overwrite the method onCreate and clear the table:

public NomeDaApplication extends android.app.Application {

    @Override
    public void onCreate() {
        // Recupera seu banco e apaga os dados
        SQLiteDataBase bd = openOrCreateDatabase("NOME_DO_BANCO", MODE_PRIVATE, null);

        // Usar o bd para apagar as linhas
    }
}

Just be a little careful 'cause I’m not sure about the execution order on SQLiteOpenHelper and the execution of onCreate. I imagine it could be a mistake when the bank is first created.

  • Thank you Wakim.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.