Saša Šijak Saša Šijak - 3 months ago 21
Android Question

Updating prepopulated database in Android

I lost last 3 hours trying to do this. Im making an app that will ship with a DB filled with populated tables that would not change on clients devices.
I managed to do this by putting it in the assets folder and copying it as a stream of bytes to the appropriate data folder on the phone. Problem is when I wish to update the database, I cant get it to work. I delete the DB in data folder on phone (from code), but copying the new database always fails, or the copied DB has the appropriate size but no tables in it.
How to do this? Or is there a simpler way? Can I open DB directly from assets (it would be the simplest way if it can, but I cant find how to access the path to assets from code)?

Answer

Here is the code I am using:

public class DataBaseHelper extends SQLiteOpenHelper {

    private static final String DB_PATH = "/data/data/com.project.mydb/databases/";
    private static final String DB_NAME = "mydb.db";
    private static final String DB_TABLE = "words";
    private static final int DB_VERSION = 6;
    private static final String TAG = "DataBaseHelper";
    int id = 0;
    Random random = new Random();
    private SQLiteDatabase myDataBase;
    private final Context myContext;

    public DataBaseHelper(Context context){
        super(context, DB_NAME, null, DB_VERSION);
        this.myContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        createDB();
    }

    @Override
    public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion){
        Log.w(TAG, "Upgrading DB from version " + oldVersion + " to " +
                newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
        onCreate(db);
    }

    public void createDataBase(){
        createDB();
    }

    private void createDB(){
        boolean dbExist = dbExists();
        if(!dbExist){
            copyDataBase();
        }
        else if(dbExist){
            copyDataBase();
        }
    }

    private boolean dbExists(){
        SQLiteDatabase db = null;
        try{
            String dbPath = DB_PATH + DB_NAME;
            db = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
            db.setLocale(Locale.getDefault());
            db.setLockingEnabled(true);
            db.setVersion(DB_VERSION);
        }
        catch(SQLiteException e){
            Log.e("SQL Helper", "database not found");
        }
        if(db != null){
            db.close();
        }
        return db != null ? true : false;
    }

    private void copyDataBase(){
        InputStream iStream = null;
        OutputStream oStream = null;
        String outFilePath = DB_PATH + DB_NAME;
        try{
            iStream = myContext.getAssets().open(DB_NAME);
            oStream = new FileOutputStream(outFilePath);
            byte[] buffer = new byte[1024];
            int length;
            while((length = iStream.read(buffer))>0){
                oStream.write(buffer,0,length);
            }
            oStream.flush();
            oStream.close();
            iStream.close();
        }
        catch(IOException ioe){
            throw new Error("Problem copying database from resource file.");
        }
    }

    public void openDataBase() throws SQLException {
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    }

    @Override
    public synchronized void close(){
        if (myDataBase != null)
            myDataBase.close();
        super.close();
    }
}
Comments