简体   繁体   English

将数据库从一个应用程序复制到另一个应用程序

[英]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:最后但并非最不重要的一点是帮助您找到答案的上下文:

  • I'm running this code on a real rooted device我在真正的 root 设备上运行此代码
  • The database is a valid SQLite file, tested with SQLite Editor for Android数据库是一个有效的 SQLite 文件,用 SQLite Editor for Android 测试过
  • The file is being copied correctly to the output path (checksum matches)文件被正确复制到输出路径(校验和匹配)
  • Permissions, owner and group are being changed to the correct ones, tested using terminal emulator with command ls [path] -l权限、所有者和组正在更改为正确的,使用终端仿真器和命令ls [path] -l
  • It is NOT possible to change the source code of the app from which I want to copy the database无法更改要从中复制数据库的应用程序的源代码

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.

相关问题 将一个类从一个应用程序复制到另一个应用程序后,Android发出ClassNotFoundException异常 - ClassNotFoundException android after copy a class from one app to another one 云代工厂复制从一个应用程序到另一个应用程序 - cloud foundry copy routes from one app to another 从另一个应用程序在一个应用程序中的数据库上运行SQLite命令 - Run SQLite commands on database in one app from another 如何将表从一个数据库复制到另一个数据库? - How to copy table from one database to another? 将新记录从一个数据库复制到另一个数 - Copy new records from one database to another 将数据库设置从一个项目复制到另一个项 - copy database setup from one project to another 从android中的另一个应用程序更新一个应用程序的数据库 - update database of an app from another app in android 在 Android 11 上将数据库从我的应用程序“A”复制到我的应用程序“B” - Copy database from my App “A” to my App “B” on Android 11 将一个人的记录从一个数据库复制到另一个数据库 - Oracle 和 Java - Copy records of a person from one database to another database - Oracle and Java 如何将选择性数据从一个数据库复制到另一个数据库(ORACLE) - How to copy selective data from one database to another (ORACLE)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM