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"; public DBAdapter(Context context) { super(context, DB_NAME, null, DB_VERSION); this.myContext = context; DB_PATH = "/data/data/" + context.getApplicationContext().getPackageName() + "/databases/"; } 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(); } @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.