在上一篇文章中,我们已经获取到了某应用所创建的数据库。如何查看数据库里面的数据呢?当然可以用一些工具来查看db文件,如果我真这么告诉经理,他会不会发飙呢?
既然这样,咱就一步到胃!呃,一步到位!既然咱们能够访问到db所在的目录,理论上是完全可以操作该文件的吧?在安卓中,我们可以通过SQLiteDatabase来操作数据库,搞一搞?停下手吧,db目前所在的目录可是私有空间呢。
所以,我们在操作数据库之前,需要先做一件神奇的事情,那就是复制一份db文件到公有空间。说起来简单,但是我们可以通过IO流实现嘛?显然还是会因为权限问题,以失败告终的。这个时候我们还是将希望寄托于命令行上,我们可以通过cat命令来进行文件的复制(当然还是要ROOT之后),代码如下:
public static void move(String oldPath,String newPath){
Process process = null;
DataOutputStream os = null;
try{
String cmd = "cat "+oldPath+" >"+newPath;
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(cmd+"\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
}catch (Exception e){
Log.e("exception:",e.getMessage());
}finally {
try{
if(os!=null){
os.close();
}
process.destroy();
}catch (Exception ee){}
}
}
将db文件复制到公有空间(如外部存储)之后,我们就可以通过SQLiteDatabase操作这个数据库了,接下来又有一个小小的问题,我们怎么知道数据库中有哪些表呢?之所以说小小的问题,而不是小问题,是因为它太小了哈哈(如果你了解sqlite_master这个系统表)。
SQLiteDatabase每创建一个新的数据库(db),都会自动生成一个内置表sqlite_master,我们看下该表的结构:
CREATE TABLE sqlite_master (
type TEXT,
name TEXT,
tbl_name TEXT,
rootpage INTEGER,
sql TEXT
);
应该能猜测出这是干嘛用的吧?此表中存储着当前数据库中所有表的相关信息,比如表的名称、用于创建此表的sql语句、索引、索引所属的表、创建索引的sql语句等。所以,我们可以通过该表获取db中有哪些表。
话不多说,上代码:
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbPath, null);
List<String> tables = new ArrayList<>();
if(db!=null){
Cursor cursor = db.rawQuery("select name from sqlite_master where type='table' order by name", null);
while (cursor.moveToNext()) {
String name = cursor.getString(0);
tables.add(name);
}
}
到现在,数据库、数据库中有哪些表都已经取到了,就差最后打印表内的数据了。到这一步,该需求已经没有任何难度了,直接上代码:
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbPath, null);
List<String> datas = new ArrayList<>();
if(db!=null){
Cursor cursor = db.rawQuery("select * from "+tbName, null);
while (cursor.moveToNext()) {
String data = "";
for(int i = 0;i<cursor.getColumnCount();i++){
data+=cursor.getColumnName(i)+":"+cursor.getString(i)+"\n\n";
}
datas.add(data);
}
}
数据已经取到了,至于要干嘛用,就是经理的个人问题咯~
编程一个很大的魅力,在于可以将不可能变为可能!