SQLiteOpenHelper onCreate does not create the database - or it is immediately overwritten

I have my database stored in my resources folder and copied at runtime. I currently have a simple operation that makes a simple database call:

DBAdapter adapter = new DBAdapter(HomeActivity.this); final SQLiteDatabase db = adapter.getReadableDatabase(); final Cursor c = db.query("exercises", new String[] { "name" }, null, null, null, null, null); startManagingCursor(c); if (c.moveToFirst()) Log.e(TAG, c.getString(0)); else Log.e(TAG,"No dice"); 

And below is my DBAdapter.java (which extends the open helper):

 public class DBAdapter extends SQLiteOpenHelper { private static final int DB_VERSION = 1; private static String DB_PATH = ""; private static final String DB_NAME = "gymrat.db"; private final Context myContext; private static final String TAG = "GymRat.DBAdapter"; /** * Constructor Takes and keeps a reference of the passed context in order to * access to the application assets and resources. * * @param context */ public DBAdapter(Context context) { super(context, DB_NAME, null, DB_VERSION); this.myContext = context; DB_PATH = "/data/data/" + context.getApplicationContext().getPackageName() + "/databases/"; } /** * Copies your database from your local assets-folder to the just created * empty database in the system folder, from where it can be accessed and * handled. This is done by transferring bytestream. * */ private void copyDatabase() throws IOException { InputStream myInput = myContext.getAssets().open(DB_NAME); String outFileName = DB_PATH + DB_NAME; OutputStream myOutput = new FileOutputStream(outFileName); byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } myOutput.flush(); myOutput.close(); myInput.close(); } /** * Call on creating data base for example for creating tables at run time */ @Override public void onCreate(SQLiteDatabase db) { Log.e(TAG, "onCreate"); try { copyDatabase(); } catch (IOException e) { Log.e(TAG,"IOException copying Database"); } } @Override public void onOpen(SQLiteDatabase db) { Log.e(TAG, "onOpen"); try { db.rawQuery("select * from exercises", null); } catch ( SQLiteException e) { Log.e(TAG,"DB copy didn't work"); try { copyDatabase(); } catch (IOException e1) { Log.e(TAG,"IOException recopying DB"); } } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.e(TAG, "Upgrading"); } } 

I took this adapter from here and changed it since it did not seem to use OpenHelper functionality.

My problem: Whenever my application launches for the first time after installation or after clearing the data in the application, onCreate is first called as I expected, and calls the copyDatabase method. The problem is that the database is not copied - or if it is running, it is immediately overwritten. Instead, a default database is created with only the "android meta_data" table, as a result of which the query in my activity throws an exception because the table does not exist.

If I copy the database again in the onOpen method, it works fine. Am I doing something out of order or is there some kind of call that causes the creation of the default SQLiteOpenHelper database? The database created by default uses the same name and version number specified in the constructor.

Right now, as you can see, I'm resorting to using a dummy query in onOpen to see if the expected table exists and if you don't go ahead and restore the database. Another option is to simply set the flag when onCreate is called signaling onOpen to copy the database. Obviously, they are a bit of hacks, and I really wonder what is going on.

I plan to move the actual database calls to separate helper classes outside of Activity, I just called db to test it.

+4
source share
1 answer

If you want to copy the database from the assets at the first start and open the database from data / data / program.name / database, you should use the code something like this:

 public class YourDatabase extends SQLiteOpenHelper public YourDatabase(Context context) { super(context, DatabaseName, null, DATABASE_VERSION); this.dbContext = context; // checking database and open it if exists if (checkDataBase()) { openDataBase(); } else { try { this.getReadableDatabase(); copyDataBase(); this.close(); openDataBase(); } catch (IOException e) { throw new Error("Error copying database"); } Toast.makeText(context, "Initial database is created", Toast.LENGTH_LONG).show(); } } 

Full answer you can read from this question

+5
source

Source: https://habr.com/ru/post/1344421/


All Articles