I am experiencing some trouble with an SQLIte database in my Android application.
The issue is that the database is never updated, not even on multiple restarts of the emulator, of Eclipse or after deletion from DDMS.
This is my onCreate method, located in a class that extends SQLiteOpenHelper:
public void onCreate(SQLiteDatabase database) {
try {
database.execSQL(ESSENCE_TABLE_CREATE);
database.execSQL(PACCO_TABLE_CREATE);
database.execSQL(TAVOLE_TABLE_CREATE);
database.rawQuery("insert into essenza values(1, 'Rovere')",
null); // added later
} catch (SQLException e) {
Log.e("DB", e.getMessage());
}
}
After instantiating the helper, I request a reference to the database:
helper = new DBHelper(context, dbpath + "/" + DATABASE_NAME);
database = helper.getWritableDatabase();
It seems that the rawQuery statement (which was added at a later time) is not executed and that the database in use is instead cached from a previous version. I also tried to change the version of the database, but it did not work. Am I missing something? Thanks in advance.
You have two options:
Use DDMs to delete the database file from your device (look in /data/data/). This will force Android to run onCreate again.
In your constructor, increment the database version you pass to SQLiteOpenHelper. Add your raw query to onUpgrade.
You probably want option 1. Option 2 is better if you have users of your app whose databases you want to update.
Related
I'm having trouble with a pre Populated database in android. Not the usual problems though. I've got the database working just fine.
My problem comes with adding new data after the app has been published.
I spent a lot of time with onupgrade method but then it dawned on me that my problem is elsewhere. Once I've added new lines to my database in my assets folder, how do I get these added to the database that was copied to my data/data folder.....
My database is where I store my level information for a game, the last column in the table is a flag to mark the level completed so I can't lose this information.
You could add some sql patch files, and then read them to upgrade your database.
I used it simply with the FileHelper static class I copied from Danny Remington's post on SO and then do :
try {
InputStream in = mgr.open(assetFile);
String[] statements = FileHelper.parseSqlFile(in);
dao.mDb.execSQL("BEGIN TRANSACTION;");
/*dao.mDb is a reference to the SQLiteDatabase from my dao*/
for (String statement : statements) {
dao.mDb.execSQL(statement);
}
dao.mDb.execSQL("COMMIT;");
in.close();
} catch (IOException e) {
//
}
My android app works with a provided DB populated and located on the asset folder. I recently had to start adding private datas in it so I used sqlcipher to encrypt it. So before starting:
The encryption goes well, since I can decrypt it easily and read it back. This is done with sqlcipher shell.
Everything was working like a charm with the db not crypted
What I was doing was, on the first launch of my app, creating a blank db on my phone, copy and past the content of the provided db in it and then, the user was able to have his own db on his phone without having to recreate it each time ( the db is pretty big ). Indeed, if the user already has the db on his phone for the further launch, he won't have to recreate it this way.
But with sqlcipher, it's not working anymore.
Important: When using sqlcipher with a non crypted db ( using "" as parameter for the related method like openDatabase ), it was working as well.
But when I try with the crypted db and with the password, what I have is the error
file is encrypted or is not a database: create locale table failed
This happens after I created a blank db using this:
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase("password").close();
I then try to open it with the following instruction:
//Open the database
String myPath = DB_PATH + DATABASE_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, "password", null, SQLiteDatabase.OPEN_READWRITE);
And then happens the error. Someone has an idea please? I'm saddly not an android expert, using a db was already difficult but as you can guess it's getting on another level now. Any help would be welcome. Thanks in advance !
Finally solve my problem after a long search following this link: Sqlcipher __ CREATE TABLE android_metadata failed
The error was coming from the way I was opening my db, which changes whether you use sqlcipher or sqlite.
Old way to open the db using sqlite:
myDataBase = SQLiteDatabase.openDatabase(myPath, "password", null, SQLiteDatabase.OPEN_READWRITE);
New way using sqlcipher, with a SQLiteDatabaseHook:
SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
public void preKey(SQLiteDatabase database) {
}
public void postKey(SQLiteDatabase database) {
database.rawExecSQL("PRAGMA cipher_migrate;");
}
};
myDataBase = SQLiteDatabase.openOrCreateDatabase(myPath, "password", null, hook);
Firstly, I create a database called "mydb" in my Android app:
DBHelper dbHelper = new DBHelper(context, "mydb", null, 1);//DBHelper is my custom class
And write some data into it's table:
SQLiteDatabase db = dbHelper.getReadableDatabase();
db.execSQL("insert into mytable(name, text) values ('allen','hello')");
Here, everything is ok. But then, i delete this database manually not by programming, with a software "R.E. explore" (Certainly on a rooted device).
Then, in my code, i read this table of the database. What is astonishing is that i still could get the data I stored.
Cursor cursor = db.query("mytable", new String[]{"name","text"}, null, null, null, null, null);
Why?
Quoting from the Android Developers reference website:
Once opened successfully, the database is cached, so you can call
this method every time you need to write to the database. (Make sure
to call close() when you no longer need the database.)
This is from the description of the getWritableDatabase() method, however both getReadableDatabase() and getWritableDatabase() return basically the same object for reading the database.
Please note that you should use getWritableDatabase() if you want to persist the changes you make to the database on the device's internal memory. Otherwise they will be valid only for the duration of the application's runtime and will be discarded once the app is closed. If you wish to delete the database completely, you should call the SQLiteDatabase's close() method in order to invalidate the cache.
use SQLiteDatabase.deleteDatabase(File file) API to delete the database
Deletes a database including its journal file and other auxiliary files that may have been created by the database engine.
Make sure you have closed all the connections that are open.
In case you are not able to do that,
just cal the deleteDatabase followed by kill process.. - not recommended
You need to delete the app from your phone then install again
I've got an app using sqlite on android. Everything works fine, I can create, read and write the database without any problems.
BUT if I change the sourcecode in eclipse (doesn't matter what as long as it recompiles) the new apk is created and pushed to the emulator. Accessing the database now will result in
enter code here03-07 15:50:03.886: ERROR/AndroidRuntime(311): Caused by: android.database.sqlite.SQLiteException: file is encrypted or is not a database
Deleting the database file with the file explorer and accessing the database, will recreate the db and everything is fine again.
I'm sure the db is closed after every access.
I've found this error too! And Finally I've decided to create the DB file from my APP, executing some code like:
public class MyHelperSqliteHelper extends SQLiteOpenHelper{
// SQL to generate USER table
String sqlCreate = "CREATE TABLE 'user' " +
"('X_id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , " +
"'D_name' VARCHAR);";
...
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(sqlCreate);
}catch (SQLException e) {
e.printStackTrace();
}
}
...
}
Next step is export this file from DDMS view to file and open that file with SQLite manager. Here you will can to import all your datas and another tables.
Final step only need to export this database from SQLiteManager and if you open this file you can see it is encrypted.
I know this is a temporal solution but It can solve this problem, and you only need to do this one time and no more.
Good luck!
I am using my own SQLite3 database as opposed to creating a new one each time my app runs, as I have a few tables with static data that I am trying to display. I created my database and placed it in my assets folder. I then created my database helper and when I start my app I can open my database without problem but when I try to open my first table using the following code
private Cursor getData()
{
try
{
myDbHelper = new DatabaseHelper(this);
SQLiteDatabase db = myDbHelper.getReadableDatabase();
Cursor cursor = db.query("exhibitor", FROM, null, null, null,null, ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
catch(SQLiteException e)
{
String err = e.toString();
return null;
}
}
It throws an error saying android.database.sqlite.SQLiteException: no such table: exhibitor: , while compiling: SELECT _id, EXHIBITOR FROM exhibitor ORDER BY EXHIBITOR but when I check the database exhibitor is there.
What am I missing?
Settings -> Applications -> Manage Applications -> (Click on your application) -> Clear data
Whenever you create new table in an existing database the table doesnt create because the OnCreate function of database handler will not be called everytime but only if required(like database not initiated). If that is not the case your newly created table actually hasnt created. Clear the data to force the db to instantiate itself.
Have you moved the database from the assets folder to /data/data/YOUR_PACKAGE/databases/ on the emulator?
This is a good detailed post about moving the database to /data/data/YOUR_PACKAGE/databases/ if it does not exist.
Here is another short and simple solution to it.
Clear Data and uninstall application from your device and re-install application in device...
Settings -> Applications -> Manage Applications -> Your Application Name -> Clear data
Using SQLiteOpenHelper.onCreate() does not create a new database every time your app starts - rather it creates a database if it does not already exist.
It sounds like you might have an empty database created by or for your helper (if there was no database at all, I might expect a different exception), and your separate database that you created outside of Android. Looks like you and your app are not looking in the same place for your data.
Just clearing the data did not work for me.
What worked was:
Uninstall app
Restart device or emulator
Disable Instant run (Not just the main group but all individual instant run settings)
Build -> Clean Project
Build -> Rebuild Project
hapend to me once
change your DATABASE_VERSION
if your DATABASE_VERSION =1 it will see just three table
if your DATABASE_VERSION = 2 it will see just more table but i really didn't know how many
good luck
I just had a simple mistake.
Reason:
Solution:
Just happened to me. I don't exactly know why but changing the DB_VERSION attribute to a bigger number made it work. The thing is: each time i'm changing the fields of the DB (attributes of the SQLiteDB class), i need to change that number.
Here is my answer according to the description of #ReivieraKid.
No, Uninstall, No Restart, Just checking the app memory if it is your real database, if return false, then copy the database to the memory again. Then You will All set. But to apply this method, you have to know the minimum size of your database.
https://stackoverflow.com/a/73332470/7608371