Search code examples
androiddatabasesqliteopenhelper

Proper way to copy database from /assets to app's private storage


I have template database in /assets directory. This database has to be copied to the main app's database which resides in the private storage area.

Now, all samples I've seen on the Internet seem very odd to me. Namely, they all extend SQLiteOpenHelper and then create initialization and copy methods, but leave onCreate and onUpgrade methods empty.

This does not look like a proper way, and yet I've seen it as an answer in multiple threads on StackOverflow as well on Internet blogs.

Is this really a proper way? Since I thought of doing coping from within onCreate (within a class that extended SQLiteOpenHelper) in a way that I first create a database that matches the template database and then I populate it with data from the template database.


Solution

  • I suggest the SQLiteAssetHelper library from:

    It has become the standard for this technique, and does all the hard work for you.

    And integration into your project is as simple as including 1 jar file.


    For example, here is my database helper class - as you can see it inherits from SQLiteAssetHelper, but there is no code I had to write in order to get the database copied from the /assets directory. That is all handled for me.

    public class DbHelper extends SQLiteAssetHelper
    {
        private static final String DATABASE_NAME = "NameOfDbFile.sqlite";
        private static final int DATABASE_VERSION = 2;
    
        public DbHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
    
            // delete old database when upgrading
            setForcedUpgrade(DATABASE_VERSION);
        }
    
    
    // ... and below a basic query as if it was any old SQLiteOpenHelper subclass
    
        public Cursor getUsers()
        {
            SQLiteDatabase db = getReadableDatabase();
            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    
            qb.setTables(User.TABLE);
            Cursor c = qb.query(db, User.COLUMNS, null, null, null, null, null);
    
            c.moveToFirst();
            return c;
        }
    
        // etc...
    }
    

    I was hesitant at first to use a library for this, but it is really simple to use.


    However, if you want to redo the work yourself, then you can take a look at how this library does it, since it is open-source on Github.