Android: copy database from asset folder, but only get an empty file
Solution 1
I wouldn't copy any database form the If you need some standard entry's in your Database, you can add them using assets
-folder.INSERT
s in your onCreate()
-method.
Update: Since this is getting down-voted for being wrong (which is kinda right) and I can't delete it, here is a little update.
I'd say it depends upon how many standard entries you want to add to your database. If it's just one or two, shipping a packed DB might not be worth it.
Anyways, some apps come with rather large databases (for example, a recipe collection). You can obviously not add all these in code.
- For small test-entries, I'd still prefer simply adding them in
onCreate()
. - For bigger databases, you should pre-populate them and ship em along with your app.
For the later to work, you'll need to copy the database file from assets/
to your app-folder. There is a nice library to handle that for you: android-sqlite-asset-helper
Solution 2
Why wouldn't you copy from assets? It's perfectly normal to do so. But you can't do it in the onCreate, at that point an empty database is already created. You need to do it prior. I usually do it in an override of getWriteableDatabase, something like
public synchronized SQLiteDatabase getWritableDatabase() {
SQLiteDatabase db = null;
if (!doesDatabaseExist()) {
try {
copyDatabase();
db = super.getWritableDatabase();
} catch(Exception ex) {
Log.e("Database Log", getDatabasePath() + " failed to copy correctly. " + ex.getLocalizedMessage());
}
}
else {
db = super.getWritableDatabase();
}
return db;
}
Solution 3
I don't know if it is still usefull but here is the solution for others that get here to see the awnser. The code you used, works for most phones, some older phones have different behaviour with the getReadableDatabase() function. Your problem therefore is not in the copyDataBase function but in the createDataBase function.
in createDataBase() there is the following check;
this.getReadableDatabase();
This checks if there is already a database with the provided name and if not creates an empty database such that it can be overwritten with the one in the assets folder. On newer devices this works flawlessly but there are some devices on which this doesn't work. Mainly older devices. I do not know exactly why, but it seems like the getReadableDatabase() function not only gets the database but also opens it. If you then copy the database from the assets folder over it, it still has the pointer to an empty database and you will get table does not exist errors.
So in order to make it work on all devices you should modify it to the following lines:
SQLiteDatabase db = this.getReadableDatabase();
if (db.isOpen()){
db.close();
}
Even if the database is opened in the check, it is closed thereafter and it will not give you any more trouble.
![4af2e9eb6](https://i.stack.imgur.com/qh8M2.png?s=256&g=1)
Comments
-
4af2e9eb6 almost 2 years
guys, I have the problem when copying database from local assets folder to /data/data/package_name/databases directory. As I use the http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/ tutorial to do it, I can only get an empty file.
I quoted the part of copyDataBase() method and there is no difference. Every time the app start, it will create the directory and empty database. So is there any way to make the copyDataBase() work?
Thank you very much!!
-
4af2e9eb6 about 13 yearsThank you! It's just 2 hours job. :)
-
Horst Dehmer almost 13 yearsWhy not copy a db file from assets? In my case it's a R/O database with 19 tables and 35k lines worth of insert statements. I see no reason why I would initialize such a database on the device. Is there something I'm missing?
-
Horst Dehmer almost 13 yearsWorks for me (Android 2.3.3). Clean and solid.
-
Alexey almost 13 yearsI had to change it a little:
if (!doesDatabaseExist()) { try { SQLiteDatabase db = super.getReadableDatabase(); db.close(); } catch (Exception ignore) {} copyFromAssets(); return super.getReadableDatabase(); }
Otherwise it was crashing with FileNotFoundException, probably because database directory didnt exist. (Android 2.2) -
Chameron over 12 yearsIs there any way that don't need to copy to data folder ? Could we read directly from assets folder ?
-
OldSchool4664 about 11 yearsThe key is the call to createEmptyDatabase(). Without this, the call to "new FileOutputStream()" fails, even though it is supposed to create the file if it does not exist.