Cursor error when querying in sqlite from the assets folder when the application is removed and reinstalled

1

I have a problem when I query the sqlite database from the assets folder only when I uninstall the application and reinstall it. If it is the first time you install the application runs normally without any problem. In the list of errors it shows me that the error is in the cursor but I do not understand the reason since when I install the application for the first time this does not happen. When I delete the data in the data folder, everything works normally again.

I attach the code:

public class MainActivity extends AppCompatActivity {

    ButtonRectangle button,button2;
    EditText view;
    private MyDatabase db;
    ListView listView;
    FloatingActionButton nuevaB;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
       setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView= (ListView) findViewById(R.id.listView);
        view = (EditText) findViewById(R.id.view);
        db = new MyDatabase(MainActivity.this);
        button2= (ButtonRectangle) findViewById(R.id.button2);
        button= (ButtonRectangle) findViewById(R.id.btnAceptar);

        nuevaB= (FloatingActionButton) findViewById(R.id.floatB);

        File database = getApplicationContext().getDatabasePath(MyDatabase.DBNAME);
        //Si la base de datos no existe

        if(false == database.exists()) {
            db.getReadableDatabase();
            //Copiar db
            if (copyDatabase(this)) {
                Toast.makeText(this, "Base de datos creada", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Error al crear la base de datos", Toast.LENGTH_SHORT).show();
                return;
            }
        }

        nuevaB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent a=new Intent(getApplicationContext(),Registro.class);
                startActivity(a);
            }
        });

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            Buscar();
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                view.setText("");
                view.setEnabled(true);
                button.setEnabled(true);
                cargaralimento();
            }
        });


        cargaralimento();
    }

private boolean copyDatabase(Context context) {
    try {

        InputStream inputStream = context.getAssets().open(MyDatabase.DBNAME);
        String outFileName = MyDatabase.DBLOCATION + MyDatabase.DBNAME;
        OutputStream outputStream = new FileOutputStream(outFileName);
        byte[] buff = new byte[1024];
        int length = 0;
        while ((length = inputStream.read(buff)) > 0) {
            outputStream.write(buff, 0, length);
        }
        outputStream.flush();
        outputStream.close();
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

public void cargaralimento(){
    ArrayList<Alimento> item=new ArrayList<Alimento>();
    item=db.listarAlimentos();

    ArrayAdapter<Alimento> adapter=new ArrayAdapter<Alimento>(this,android.R.layout.simple_list_item_1,item);
    listView.setAdapter(adapter);
}
}

Helper code:

public class MyDatabase extends SQLiteOpenHelper {

public static final String DBNAME = "dbTest.db";
public static final String DBLOCATION = "/data/data/com.example.jinex.dbTest/databases/";
private Context mContext;
private SQLiteDatabase mDatabase;

public MyDatabase(Context context) {
    super(context, DBNAME, null, 1);
    this.mContext = context;
}

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

public void openDatabase() {
    String dbPath = mContext.getDatabasePath(DBNAME).getPath();
    if(mDatabase != null && mDatabase.isOpen()) {
        return;
    }
    mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
}

public void closeDatabase() {
    if(mDatabase!=null) {
        mDatabase.close();
    }
}



public ArrayList<Alimento> listarAlimentos() throws SQLException{
    Alimento a=null;
    ArrayList<Alimento> item= new ArrayList<Alimento>();
    openDatabase();
    Cursor cursor=null;
    cursor = mDatabase.rawQuery("SELECT * FROM ALIMENTOS", null);
    cursor.moveToFirst();
    try{
    while (!cursor.isAfterLast()) {
       a=new Alimento(cursor.getInt(0),cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getDouble(4),cursor.getDouble(5),cursor.getDouble(6),cursor.getDouble(7),cursor.getDouble(8),cursor.getDouble(9),cursor.getDouble(10),cursor.getDouble(11),cursor.getDouble(12),cursor.getDouble(13),cursor.getDouble(14),cursor.getDouble(15),cursor.getDouble(16),cursor.getDouble(17),cursor.getDouble(18),cursor.getDouble(19),cursor.getDouble(20),cursor.getDouble(21));
        item.add(a);
        cursor.moveToNext();
    }}catch (Exception e){
        Log.d("error",e.toString());
    }
    cursor.close();
    closeDatabase();
    return item;
}

I enclose the error that comes out:

  

04-19 18: 25: 43.365 18263-18263 / com.example.jinex.dbTest   E / CursorWindow: Failed to read row 0, column 9 from a CursorWindow   which has 635 rows, 9 columns.

04-19 18:25:43.367 18263-18263/com.example.jinex.dbTest D/error: java.lang.IllegalStateException: Couldn't read row 0, col 9 from
     

CursorWindow. Make sure the Cursor is initialized correctly before   accessing data from it.

the database is located in the assets folder and when the installation is executed it is verified if it is in the cell phone. If you find it does not do anything otherwise copy.

    
asked by Jinex Velarde 20.04.2017 в 01:35
source

2 answers

0

The problem is here, you are defining fixed indices that probably do not match the values of the columns in the database :

a=new Alimento(cursor.getInt(0),cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getDouble(4),cursor.getDouble(5),cursor.getDouble(6),cursor.getDouble(7),cursor.getDouble(8),cursor.getDouble(9),cursor.getDouble(10),cursor.getDouble(11),cursor.getDouble(12),cursor.getDouble(13),cursor.getDouble(14),cursor.getDouble(15),cursor.getDouble(16),cursor.getDouble(17),cursor.getDouble(18),cursor.getDouble(19),cursor.getDouble(20),cursor.getDouble(21));

I recommend you to avoid this type of error even for maintenance, instead of defining an index:

cursor.getString(1)

define the name of the field, this will save you a lot of headaches (I say from experience):

cursor.getString(cursor.getColumnIndex("nombre de campo") 
    
answered by 20.04.2017 в 18:02
0

Well, apparently your database only has 9 columns and you are trying to get the data of 23 columns.

a=new 
Alimento(cursor.getInt(0),cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getDouble(4),cursor.getDouble(5),cursor.getDouble(6),cursor.getDouble(7),cursor.getDouble(8),cursor.getDouble(9),cursor.getDouble(10),cursor.getDouble(11),cursor.getDouble(12),cursor.getDouble(13),cursor.getDouble(14),cursor.getDouble(15),cursor.getDouble(16),cursor.getDouble(17),cursor.getDouble(18),cursor.getDouble(19),cursor.getDouble(20),cursor.getDouble(21));

here you must modify to:

 a=new Alimento(cursor.getInt(0),cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getDouble(4),cursor.getDouble(5),cursor.getDouble(6),cursor.getDouble(7),cursor.getDouble(8);
    
answered by 14.01.2019 в 19:27