打开任何SQLiteDatabase作为su / root

时间:2014-06-02 11:08:41

标签: android android-sqlite root

我知道,我可以以root用户身份启动进程,但是如何创建具有给定路径的SQliteDatabase(ANY路径,即另一个应用程序数据库)?作为此根进程中的此root用户...

我尝试直接读取文件,但即使这样也行不通(它每次都要求root访问权限)并且只打印一个空结果(因为找不到sqlite3)

 String path = "/data/data/<app_package>/databases/<database_name>";
 Process p = Runtime.getRuntime().exec("su sqlite3 -csv " + path + " \"select * from test\";");
 StringBuilder res = new StringBuilder();
 String line;
 while ((line = bufferedReader.readLine()) != null)
     res.append(line + "\n");

实际上,我想阅读另一个应用程序数据库的内容,我该如何正确地做到这一点?我满足于以下两个解决方案之一:

  • 将查询内容作为csv或类似内容获取

  • 以root身份获取SQLiteDatabase对象,并使用给定的数据库路径(首选,因为它更灵活)

找到部分解决方案:

看我的回答......

但仍然存在一个问题,它每次都要求su权限,我该如何避免这种情况?

2 个答案:

答案 0 :(得分:1)

到目前为止,以下工作只有一个问题:它每次都要求权限......可能是因为新流程......

try
{
String dbName = "<database_name>";
String packageSrc = "<package_source>";
String pathSource = "/data/data/" + packageSrc + "/databases/" + dbName;
String pathTarget = "/data/data/" + MainApp.getAppContext().getPackageName() + "/databases/" + dbName;

// 1) delete old copied file
// 2) copy file
// 3/4) set permissions of copied file
String commandDelete = "rm " + pathTarget + "\n";
String commandCopy = "cat " + pathSource + " > " + pathTarget + "\n";
String commandCHOwn = "chown root.root " + pathTarget + "\n";
String commandCHMod = "chmod 777 " + pathTarget + "\n";

Process p = Runtime.getRuntime().exec("su");

OutputStream os = p.getOutputStream();

os.write((commandDelete).getBytes("ASCII"));
os.flush();
os.write((commandCopy).getBytes("ASCII"));
os.flush();
os.write((commandCHOwn).getBytes("ASCII"));
os.flush();
os.write((commandCHMod).getBytes("ASCII"));
os.flush();

os.close();

try
{
    p.waitFor();
    if (p.exitValue() != 255)
    {
        SQLiteDatabase db = SQLiteDatabase.openDatabase(pathTarget, null, SQLiteDatabase.OPEN_READONLY);
        // be happy and work with the database
    }
}
catch (InterruptedException e)
{
    // error
}
}
catch (IOException e)
{
// error
}

答案 1 :(得分:0)

首先将数据库文件复制到项目的“assets”文件夹中,然后创建数据库文件以连接数据库(sqlite数据库)

public class dbdata扩展了SQLiteOpenHelper {

private static String DBName = "dbdata";
private String DBVersion = "3";
private static Context context;
private static String DB_PATH = "";
private SQLiteDatabase myDataBase;
Context myContext;

public dbdata(Context context) {
    super(context, DBName, null, 1);

    myContext = context;
    DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    try {
        createDataBase();
    } catch (IOException e) {

        e.printStackTrace();
    }

}

public void createDataBase() throws IOException {

    boolean dbExist = checkDataBase();

    if (dbExist) {
        // do nothing - database already exist
    } else {

        this.getReadableDatabase();

        try {

            copyDataBase();

        } catch (IOException e) {

            throw new Error("Error copying database");

        }
    }

}

private boolean checkDataBase() {

    SQLiteDatabase checkDB = null;

    try {
        String myPath = DB_PATH + DBName;
        checkDB = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);

    } catch (SQLiteException e) {

        // database does't exist yet.

    }

    if (checkDB != null) {

        checkDB.close();

    }

    return checkDB != null ? true : false;
}

private void copyDataBase() throws IOException {

    // Open your local db as the input stream
    InputStream myInput = myContext.getAssets().open(DBName);

    // Path to the just created empty db
    String outFileName = DB_PATH + DBName;

    OutputStream myOutput = new FileOutputStream(outFileName);

    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();

}

public void openDataBase() throws SQLException {

    String myPath = DB_PATH + DBName;
    myDataBase = SQLiteDatabase.openDatabase(myPath, null,
            SQLiteDatabase.OPEN_READONLY);

}

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-gene rated method stub

}

制作你自己的功能

//添加新的联系人关系表

public void addContact(personprp prop) {

    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();

    values.put("rl_first_name", prop.firstname);
    values.put("rl_last_name", prop.lastname);
    values.put("rl_age", prop.age);
    values.put("rl_dob", prop.dob);
    values.put("rl_address", prop.address);
    values.put("rl_category", prop.category);
    values.put("rl_firstcall", prop.firstcall);
    values.put("rl_firstmsg", prop.firstmsg);
    values.put("rl_brother", prop.brothers);
    values.put("rl_sister", prop.sisters);
    values.put("rl_mobile", prop.mobileno);
    values.put("rl_emailid", prop.emailid);
    values.put("rl_facebookid", prop.facebookid);
    values.put("rl_imagepath", prop.imagepath);

    db.insert("tb_contact", null, values);
    System.out.println("datasaved");

    // Inserting Row

    db.close(); // Closing database connection
}

}