我在我的应用程序中使用RoomDB,可以执行crud操作。实际上,我想查看数据库文件。
getDatabasePath("user.db").getAbsolutePath();
上述代码给出了数据库文件所在的目录 目录形如:
/data/data/com.example.manvish.roomdb/databases/user.db
但是即使我使用命令提示符中的sudo,仍然无法访问数据目录。 现在我想将DB文件位置更改为内部存储器或SD卡中的其他文件夹。我该怎么做?
我在我的应用程序中使用RoomDB,可以执行crud操作。实际上,我想查看数据库文件。
getDatabasePath("user.db").getAbsolutePath();
上述代码给出了数据库文件所在的目录 目录形如:
/data/data/com.example.manvish.roomdb/databases/user.db
但是即使我使用命令提示符中的sudo,仍然无法访问数据目录。 现在我想将DB文件位置更改为内部存储器或SD卡中的其他文件夹。我该怎么做?
Java解决方案:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
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
}
};
要更改数据库位置,只需在构建Room数据库时放置路径,例如,在您的文件夹中,位于内部存储器中的数据库:
最初的回答:
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
}
}
大家好,我发表我的解决方案是因为我在这个问题上卡了几个小时,几乎认为我们不能使用位于应用程序 "/data/data" 内部目录以外的数据库。
然而,解决方案非常简单。使用下面的代码,我们会遇到 IllegalArgumentException 异常:"文件 ... 包含路径分隔符"
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()
}
但只需将路径更改为以斜杠作为第一个字符,所有内容就可以正常工作!
var path = "/sdcard/Android/data/$packageName/files/rms_database.sqlite"
不确定这是否是您要找的,但在我的情况下,就像@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);
}
}
}
}
为了更清晰地说明:
此外,我从以下答案中提取了这个想法: https://dev59.com/eVcP5IYBdhLWcg3whaUD#50383879
希望它能帮助任何人!
P.S. 如果您只需要查看数据并执行CRUD操作,您始终可以使用此插件:https://github.com/amitshekhariitbhu/Android-Debug-Database