Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the default database file location of Room DataBase?

I am using RoomDB in my app. able to perform crud operations. Actually i want to see the db file.

getDatabasePath("user.db").getAbsolutePath();

above code is giving me the directory where the db file is saves directory is like this

 /data/data/com.example.manvish.roomdb/databases/user.db

but still i am unable to access the data directory even using sudo from command prompt. now i want to change the DB file location to some other folders in internal memory or SD card. how can i do this?

like image 696
Gaju Kollur Avatar asked Oct 16 '22 22:10

Gaju Kollur


3 Answers

Java solution:

  1. Grant permissions in Manifest
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  1. Create db (Here SofDatabase is a singleton class)
private static final String DB_NAME = "stack_overflow_db";
private static final String DB_PATH = String.format("%s/%s",
 Environment.getExternalStorageDirectory().getAbsolutePath(), DB_NAME);
    public static synchronized SofDatabase getInstance(Context aContext) {
        if (sInstance == null) {
            sInstance = Room.databaseBuilder(aContext, SofDatabase.class, DB_PATH)
                    .fallbackToDestructiveMigration()
                    .addCallback(roomCallback).build(); //adding callback from Room
        }
        return sInstance;
    }

Callback

     /**
     * Get Notified once db is created
     */
    private static final RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            Log.i("SOF", db.getPath()); //which prints out -->  I/SOF: /storage/emulated/0/stack_overflow_db
            // add some jobs once db is created
        }
    };
like image 63
tamir_sagi Avatar answered Oct 20 '22 21:10

tamir_sagi


To change the db location just put the path when you build the Room database, an example for a db in your folder, in the internal storage:

fun getDatabase(context: Context, scope: CoroutineScope):   TestDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance =
                    Room.databaseBuilder(
                        context.applicationContext,
                        TestDatabase::class.java,
                        Environment.getExternalStorageDirectory().absolutePath + "/yourFolder/yourdb"
                    ).build()
                INSTANCE = instance
                return instance
            }
        }

This is a Kotlin example, if you need it in Java, just let me know. Regards.

like image 44
Jorge Alejandro Avatar answered Oct 20 '22 21:10

Jorge Alejandro


So guys I'm posting my solution because I got stuck for several hours on this problem and I was almost convinced that we couldn't use a database that is located elsewhere than the "/data/data" internal directory of the application with Room

The solution is however very simple. with the following code we have the IllegalArgumentException exception: "File ... contains a path separator"

private fun buildDatabase(context: Context) : RMSRoomDatabase {

        val packageName: String = context.getApplicationInfo().packageName
        var path = "sdcard/Android/data/$packageName/files/rms_database.sqlite"

        var builder = Room.databaseBuilder(
            context,
            RMSRoomDatabase::class.java,
            path
        )

        return builder.allowMainThreadQueries()
            .fallbackToDestructiveMigration()
            .build()
    }

But by simply changing the path with an slash as the first character, everything works correctly!

var path = "/sdcard/Android/data/$packageName/files/rms_database.sqlite"
like image 1
pjaaar Avatar answered Oct 20 '22 21:10

pjaaar