如何更改Room DataBase的默认数据库文件位置?

时间:2018-02-21 10:44:32

标签: android android-sqlite android-room

我在我的应用中使用RoomDB。能够执行crud操作。 其实我想查看db文件。

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

上面的代码给出了保存db文件的目录 目录是这样的

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

但即使在命令提示符下使用sudo,我仍然无法访问数据目录。 现在我想将DB文件位置更改为内部存储器或SD卡中的其他文件夹。我怎么能这样做?

3 个答案:

答案 0 :(得分:0)

要更改db的位置,只需在构建Room数据库时将路径放在内部存储中,该文件是文件夹中db的示例,

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
            }
        }

这是一个Kotlin示例,如果您需要用Java编写的示例,请告诉我。 问候。

答案 1 :(得分:0)

Java解决方案:

  1. 清单中的授予权限
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  1. 创建数据库(此处SofDatabase是单例类)
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;
    }

回调

     /**
     * 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
        }
    };

答案 2 :(得分:-1)

不确定这是否是您要查找的内容,但就我而言,就像@ M.Yogeshwaran一样,我需要能够设置数据库的初始状态并从那里开始工作,所以我最终做到了:

/**
 * @param context
 */
public DatabaseService(Context context) {

        File dst = context.getDatabasePath(DB_NAME);
        dst.delete();
        File src = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()+"/database.db");
        try {
            copy(src,dst);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Init the database singleton
        db = Room.databaseBuilder(context, CrediforceDatabase.class, Constants.DB_NAME).build();
}

public static void copy(File src, File dst) throws IOException {
    try (InputStream in = new FileInputStream(src)) {
        try (OutputStream out = new FileOutputStream(dst)) {
            // Transfer bytes from in to out
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        }
    }
}

为了更加清楚:

  1. DB_NAME =“ database.db”
  2. 出于测试目的,我在下载文件夹中拥有要“导入”的“ database.db”,稍后我将转换此代码,以便设备从服务器中提取初始数据库。
  3. dst.delete();只是在测试时删除现有的数据库文件(不确定是否需要)
  4. 这基本上可以解释为:启动应用程序>替换数据库文件>构建数据库。
  5. 要小心room_master_table中的identity_hash,如果这与预期的不同,将无法正常工作。

此外,我从以下答案中提取了这个想法: https://stackoverflow.com/a/50383879/2150472

希望它对任何人都有帮助!

P.S,如果您仅需要能够查看数据并执行CRUD操作,则可以始终使用以下插入方式:https://github.com/amitshekhariitbhu/Android-Debug-Database