Android: copy database from resource folder but get only empty file

Guys, I had a problem copying the database from the local resources folder to the / data / data / package _name / databases directory. Since I'm using the http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/ tutorial to do this, I can only get an empty file.

I quoted part of the copyDataBase () method, and there is no difference. Each time the application starts, it creates a directory and an empty database. So, is there a way to make copyDataBase () work?

Many thanks!

+7
source share
5 answers

I would not copy any form of the assets database folder. If you need a standard entry in your database, you can add them using INSERT in your onCreate() method.


Update:. Since this deviates from voting for the wrong (which is correct) and I cannot remove it, here is a small update.

I would say that it depends on the number of standard records that you want to add to your database. If it's one or two, sending a packed database might not be worth it.

In any case, some applications come with fairly large databases (for example, the assembly of recipes). Obviously, you cannot add all this to the code.

  • For small test entries, I'd rather just add them to onCreate() .
  • For large databases, you must pre-populate them and send them along with your application.

For later work, you need to copy the database file from assets/ to the application folder. For this you need a good library: android-sqlite-asset-helper

0
source

Why aren't you copying assets? This is perfectly normal for this. But you cannot do it in onCreate, at that moment an empty database is already created. You need to do this before. I usually do this 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; } 
+15
source

in the above example, the example worked for me as follows:

 db = super.getWritableDatabase(); db.close; copyDatabase(); 

otherwise, I received an I / O error;

0
source

Here is a simple and convenient code that I use:

 public class DataBaseImportHelper { private DataBaseImportHelper() {}; // Avoid instantiation /** * Creates a empty database on the system and rewrites it with your own database. */ public static boolean importDataBase(Context context) { InputStream myInput = null; OutputStream myOutput = null; try { // Open local db from assets as the input stream myInput = context.getAssets().open(DATABASE_NAME); createEmptyDatabase(context); // See this method below // Open the empty db as the output stream myOutput = new FileOutputStream(getDatabaseFile(context)); // transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } // Close the streams myOutput.flush(); myInput.close(); myOutput.close(); return true; } catch (IOException e) { e.printStackTrace(); } return false; } /** * Check if the database already exists. * @return true if it exists, false if it doesn't */ public static boolean isDatabaseExists(Context context) { return getDatabaseFile(context).exists(); } private static File getDatabaseFile(Context context) { return context.getDatabasePath(DatabaseHelper.DATABASE_NAME); } /** * Create an empty database into the default application database * folder.So we are gonna be able to overwrite that database with our database */ private static void createEmptyDatabase(Context context) { // use anonimous helper to create empty database new SQLiteOpenHelper(context, DatabaseHelper.DATABASE_NAME, null, 1) { // Methods are empty. We don`t need to override them @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } @Override public void onCreate(SQLiteDatabase db) { } }.getReadableDatabase().close(); } 

}

And using the code:

 if(!DataBaseImportHelper.isDatabaseExists(this)){ if (!DataBaseImportHelper.importDataBase(this)){ throw new IllegalStateException("Database doesn`t exist and hasn`t been copied!"); } } 
0
source

I don’t know if it is still useful, but here is a solution for others who get here to see the Einser. The code you used works for most phones, some older phones have different behavior with the getReadableDatabase () function. Therefore, your problem is not in the copyDataBase function, but in the createDataBase function.

in createDataBase () the following check exists:

 this.getReadableDatabase(); 

This checks if there is already a database with the specified name and if an empty database is not created so that it can be overwritten using the one in the resource folder. On new devices, this works flawlessly, but there are some devices on which it does not work. Mostly old devices. I don’t know exactly why, but it seems that the getReadableDatabase () function not only gets the database, but also opens it. If you then copy the database from the assets folder on top of it, it still has a pointer to an empty database, and you will get a table that does not contain errors.

So, for it to work on all devices, you must change it to the following lines:

 SQLiteDatabase db = this.getReadableDatabase(); if (db.isOpen()){ db.close(); } 

Even if the database is open on the check, it closes after that, and this will not give you more problems.

0
source

All Articles