[英]Copy database from one app to another app
I'm trying to copy a database from an Android app to another app .我正在尝试将数据库从 Android 应用程序复制到另一个应用程序。 In other words, I want to copy a file located in the following path /data/data/com.other.package/databases/filename.db
to /data/data/com.my.app/databases/new_file.db
.换句话说,我想将位于以下路径/data/data/com.other.package/databases/filename.db
的文件复制到/data/data/com.my.app/databases/new_file.db
。
So far, I'm using root commands to do the process and then try to fix permissions , but I can't read the copied file.到目前为止,我正在使用root 命令来执行该过程,然后尝试修复权限,但我无法读取复制的文件。 This is the logcat error I'm getting:这是我收到的 logcat 错误:
type=1400 audit(0.0:6364): avc: denied { open } for name="database.db" dev="mmcblk0p28" ino=171293 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:app_data_file:s0 tclass=file permissive=0
os_unix.c:31278: (13) open(/data/user/0/com.testapp/databases/database.db)
This is the code I've come up with:这是我想出的代码:
// Define in and out filepaths
String DB_INPUT = "/data/data/com.package.name/databases/database.db";
String DB_OUTPUT = activity.getDatabasePath("database.db").getPath();
try {
// Request superuser permissions
Process suProcess = Runtime.getRuntime().exec("su");
DataOutputStream suOutputStream = new DataOutputStream(suProcess.getOutputStream());
// Copy database
suOutputStream.writeBytes("cat " + DB_INPUT + " > " + DB_OUTPUT + "\n");
// Fix permissions
int appUID = getApplication().getApplicationInfo().uid;
suOutputStream.writeBytes("chmod 600 " + DB_OUTPUT + "\n"); // rw- --- ---
suOutputStream.writeBytes("chown " + appUID + "." + appUID + " " + DB_OUTPUT + "\n");
suOutputStream.writeBytes("exit\n");
suProcess.waitFor();
suOutputStream.close();
// Test
SQLiteDatabase.openDatabase(DB_OUTPUT, null, SQLiteDatabase.OPEN_READWRITE);
} catch(Exception e) {
Log.e(LOGTAG, "Something went terrible wrong: " + e.getMessage());
}
Last but not least, a little bit of context to help you find an answer:最后但并非最不重要的一点是帮助您找到答案的上下文:
ls [path] -l
权限、所有者和组正在更改为正确的,使用终端仿真器和命令ls [path] -l
I found a pretty simple trick to avoid having to rewrite owner, group and permissions by creating an empty database with the same name and then overwriting it .我发现了一个非常简单的技巧,可以通过创建一个同名的空数据库然后覆盖它来避免重写所有者、组和权限。 This is how the final code looks like:这是最终代码的样子:
// Define in and out filepaths
String DB_INPUT = "/data/data/com.package.name/databases/database.db";
String DB_OUTPUT = activity.getDatabasePath("database.db").getPath();
// Create empty database to grant permissions
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_OUTPUT, null);
db.close();
try {
// Request superuser permissions
Process suProcess = Runtime.getRuntime().exec("su");
DataOutputStream suOutputStream = new DataOutputStream(suProcess.getOutputStream());
// Copy database
suOutputStream.writeBytes("cat " + DB_INPUT + " > " + DB_OUTPUT + "\n");
// Close terminal
suOutputStream.writeBytes("exit\n");
suProcess.waitFor();
suOutputStream.close();
} catch(Exception e) {
Log.e(LOGTAG, "Something went terrible wrong: " + e.getMessage());
}
You were very close with your original code but your problem was the SELinux error in avc: denied { open }
您与原始代码非常接近,但您的问题是avc: denied { open }
的 SELinux 错误avc: denied { open }
When you copy the DB file in, you need to change the SELinux context with something like chcon u:object_r:app_data_file:s0:c512,c768 database.db
as an SSH command in terminal.当您复制 DB 文件时,您需要使用类似chcon u:object_r:app_data_file:s0:c512,c768 database.db
类的内容更改 SELinux 上下文作为终端中的 SSH 命令。
In the the context of your code, it'd be something like在您的代码上下文中,它类似于
suOutputStream.writeBytes("chcon u:object_r:app_data_file:s0:c512,c768 " + DB_OUTPUT + "\n");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.