Search code examples
android-sqlitefilestreamandroid-roompopulate

Using pre-populated database in Room by copy database file from assert


I want to use pre-populated database in Android Room. I found a way to make it through using the callback, and filled up the database files. But something is wrong, I'm sure that the database is copied normally, but it remains empty in the device monitor and android emulator. Can you please help me

public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
private static final String DB_NAME = "base.db";
static Context ctx;

public abstract Dao dao();

public static AppDatabase getDatabase(Context context) {
    if (INSTANCE == null) {
        ctx = context;
        synchronized (AppDatabase.class) {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context,
                        AppDatabase.class, DB_NAME)
                        .allowMainThreadQueries()
                        .addCallback(rdc)
                        .build();
            }
        }
    }
    return INSTANCE;
}

private static RoomDatabase.Callback rdc = new RoomDatabase.Callback() {
    public void onCreate(SupportSQLiteDatabase db) {

        new PopulateDbAsync(INSTANCE, ctx).execute();
        Log.d("db create ", "table created when db created first time in  onCreate");
    }

    public void onOpen(@NonNull SupportSQLiteDatabase db) {
        ContentValues contentValues = new ContentValues();
    }
};

private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {

    private Dao dao;
    AssetManager assetManager = ctx.getAssets();

    PopulateDbAsync(AppDatabase db, Context context) {
        Dao = db.Dao();
        ctx = context;
    }

    @Override
    protected Void doInBackground(final Void... params) {
        String DB_PATH = "/data/data/mypackage/databases/";
        String DB_NAME = "base.db";
        try {
            Log.d("AppDatabase","Trying copy database file");
            OutputStream myOutput = new FileOutputStream(DB_PATH + DB_NAME);
            byte[] buffer = new byte[1024];
            int length;
            InputStream myInput = ctx.getAssets().open("base.db");
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myInput.close();
            myOutput.flush();
            myOutput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
}

Solution

  • I solved after spending 6 hours on researching and R & D .

    Context is that : - I want to put already existing finaldb.db(which is present inside assests folder) into room database .

    Step 1 : copy this framework files from here link

    Step 2 : You need to migrate , chill i have code :)

    @Database(entities = {Status.class}, version = 1,exportSchema = false)
    public abstract class AppDatabase extends RoomDatabase {
        public abstract DataDao StatusDao();
    
        private static AppDatabase INSTANCE;
    
    
        public static AppDatabase getDatabase(Context context) {
            if (INSTANCE == null) {
                INSTANCE = createDatabase(context);
            }
            return (INSTANCE);
        }
    
        private static final Migration MIGRATION_2_3 = new Migration(1, 2) {
            @Override
            public void migrate(@NonNull SupportSQLiteDatabase database) {
                Log.d("kkkk","bc");
    
                String SQL_CREATE_TABLE = "CREATE TABLE IF NOT EXISTS 'Status' " +
                        "( 'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
                        "  'category' TEXT NOT NULL," +
                        "  'sub_category' TEXT NOT NULL," +
                        "  'content' TEXT NOT NULL," +
                        "  'favourite' INTEGER DEFAULT(0))";
    
                database.execSQL(SQL_CREATE_TABLE);
    
            }
        };
    
        private static AppDatabase createDatabase(Context context) {
            RoomDatabase.Builder<AppDatabase> builder =
                    Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class,
                            context.getString(R.string.dbase_name));
    
    
            return (builder.openHelperFactory(new AssetSQLiteOpenHelperFactory())
                    .allowMainThreadQueries()
                    .addMigrations(MIGRATION_2_3)
                    .build());
        }
    
    }
    

    In MIGRATION_2_3 you have to create table exactly same as current database(which is present in assests folder)

    want to learn about migration

    Step 3 : Now table is created successfully in room database !

    In case of crash see your logcat , in which its written in understandable form .