在设备上调试sqlite数据库


98

我目前正在研究适用于Android的WiFi应用程序。我在尝试访问设备上的数据库时遇到麻烦。在仿真器中进行调试对我不起作用,因为仿真器中没有WiFi支持。我尝试通过使用将数据库文件从设备中拉出

adb pull data/data/package-name/databases/database-name

但是我收到错误“权限被拒绝”。在此答案中,Android:数据库文件存储在哪里?,Commonsware建议通过在调试模式下运行来拉数据库文件。但这也不起作用。我们将不胜感激地提供有关如何调试数据库而无需生根设备的任何帮助。

Answers:


142

我将从另一个答案中重复自己:

从API级别8(Android 2.2)开始,如果您将应用程序构建为可调试的,则可以使用shell run-as命令以特定用户/应用程序的身份运行命令或可执行文件,或者仅切换至UID应用程序的,以便可以访问其数据目录。

因此,如果您希望从设备中提取应用程序数据库,则应运行应用程序的调试版本,连接adb shell并运行以下命令:

run-as com.yourpackage sh -c "cat ~/databases/db-file" > /sdcard/db-file.sqlite

这会将您复制db-file到SD卡/外部存储的根目录。现在,您可以使用文件管理器adb pull或任何您喜欢的东西轻松地从那里获取它。请注意,使用这种方法,您的应用无需获得WRITE_EXTERNAL_STORAGE许可,因为复制操作始终由可始终写入外部存储的外壳用户完成。

在Linux / Mac系统上,可以使用以下命令将数据库直接复制到您的计算机上,而无需输入adb shell:

adb shell 'run-as com.yourpackage sh -c "cat ~/databases/db-file"' > db-file.sqlite

但是,由于CR / LF符号转换,这在Windows上将无法正常工作。在那里使用前一种方法。


1
@MikeIsrael以防万一,您没有在应用程序中使用SQLCipher吗?如果不是,则要大致检查数据库是否已正确下载,请在查看器(最好是十六进制查看器)中打开DB文件,并检查其是否以SQLite format 3字符串开头。还要确保您具有正确的sqlite版本(即,您不尝试使用sqlite2可执行文件打开sqlite3数据库)。您也可以尝试其他SQLite客户端(例如SQLiteStudio)。希望能帮助到你。
Idolon

1
我在一根衬里上遇到麻烦。如果我在外壳程序中运行命令,则工作正常,但如果放入一个内衬,则会得到:系统找不到指定的路径。
泰勒牧师(Rev Tyler)

2
包裹<我的包裹>是未知的...谁知道为什么。我通过Studio通过按调试按钮进行安装。
内森·史威文2014年

4
在Android Lollipop上,我得到permission denied
Muhammad Babar

1
我拉了一个数据库,其中有两个表,每个表有十几行,并对每个表进行了完全选择查询。一个工作正常,另一个报告文件中的数据错误。我现在最好的猜测是Android和本地Shell之间的编码不匹配。
梅森2015年

23

我在MAC上使用此Shell脚本,该脚本将数据库直接复制到我的主文件夹中。简单的一键式解决方案,只需更改程序包名称(com.example.app)和数据库名称(database.sqlite)

简单脚本

#!/bin/bash
adb -d shell 'run-as com.example.app cat /data/data/com.example.app/databases/database.sqlite > /sdcard/database.sqlite'
adb pull /sdcard/database.sqlite ~/

接受参数[package_name] [database]的脚本

#!/bin/bash

REQUIRED_ARGS=2
ADB_PATH=/Users/Tadas/Library/sdk/platform-tools/adb
PULL_DIR="~/"

if [ $# -ne $REQUIRED_ARGS ]
    then
        echo ""
        echo "Usage:"
        echo "android_db_move.sh [package_name] [db_name]"
        echo "eg. android_db_move.sh lt.appcamp.impuls impuls.db"
        echo ""
    exit 1
fi;


echo""

cmd1="$ADB_PATH -d shell 'run-as $1 cat /data/data/$1/databases/$2 > /sdcard/$2' "
cmd2="$ADB_PATH pull /sdcard/$2 $PULL_DIR"

echo $cmd1
eval $cmd1
if [ $? -eq 0 ]
    then
    echo ".........OK"
fi;

echo $cmd2
eval $cmd2

if [ $? -eq 0 ]
    then
    echo ".........OK"
fi;

exit 0

第一个命令是创建数据库的零字节副本,因此我在脚本中进行了一些调整:gist.github.com/romulof/6af8a8919660f395f975
romulof 2015年

14

查看和管理您的Android应用数据库的最佳方法是使用此库https://github.com/sanathp/DatabaseManager_For_Android

使用此库,您可以从应用程序本身管理应用程序SQLite数据库。您可以查看应用程序数据库中的表,进行更新,删除,向表中插入行。所有来自应用程序的内容。

它是一个单独的Java活动文件,只需将Java文件添加到您的源文件夹中即可。开发完成后,从src文件夹中删除Java文件即可。

它对我有很大帮助。希望它对您也有帮助。

您可以在此处查看1分钟的演示:http: //youtu.be/P5vpaGoBlBY


11

虽然,这是一个古老的问题,但我认为它仍然很重要,应该得到当前的答案。有可用的工具,使您可以直接检查数据库(无需从设备或仿真器中提取数据库)。

我最近发现(最受青睐)的工具是Android Debug Database

您只需要添加此依赖项:

debugImplementation 'com.amitshekhar.android:debug-db:1.0.3'

不需要其他代码。启动应用程序后,打开logcat并过滤“ DebugDB”,您会发现一条消息,提示

D/DebugDB: Open http://192.168.178.XXX:8080 in your browser

它适用于每种浏览器,您可以检查数据库表和共享首选项。

在此处输入图片说明

它也可以与默认和Genymotion模拟器一起使用。


我以前使用的工具是stetho

缺点:您需要添加一些代码,然后绑定到Chrome浏览器。

优点:您还可以选择检查网络流量。



5

如果你得到

The system cannot find the path specified.

尝试

adb -d shell "run-as com.yourpackage cat /data/data/com.yourpackage/databases/dbname.sqlite > /sdcard/dbname.sqlite"

注意双引号!


3

我只是做了:

$ adb shell
shell@android:/ $ run-as myapp.package.name sh
shell@android:/data/data/myapp.package.name $

然后,我可以调试sqlite数据库,或者调试具有适当权限的Shell想要执行的任何操作。


2

如果apk是可调试的,则有一种方法可以从非root用户adb shell使用称为运行方式的程序来复制应用程序的私有文件。


2

这是分步说明-大多取自其他答案的组合。此功能适用于未解锁的设备。

  1. 连接设备并以调试模式启动应用程序。

  2. 将数据库文件从应用程序文件夹复制到SD卡:执行:

    ./adb -d shell'以com.yourpackge.name cat /data/data/com.yourpackge.name/databases/filename.sqlite> /sdcard/filename.sqlite运行

  3. 将数据库文件拉到您的计算机上:执行:

    ./adb pull / sdcard /执行:./adb

  4. 安装Firefox SQLLite Manager:https ://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/

  5. 打开Firefox SQLLite Manager,然后从上述步骤3中打开数据库文件。

  6. 请享用!


2

Android Studio 4.1添加了一项新功能,可以查看/编辑Android SQLite数据库。

在此处输入图片说明

如何打开数据库检查器

要在Android Studio中打开数据库检查器,您需要View > Tool Windows > Database Inspector从菜单栏中选择。

另外,您还需要在运行API级别26或更高级别的设备上运行该应用程序。

使用此工具,您可以

  • 查询数据库

  • 修改和调试数据库

在此处输入图片说明


2

在新的Android Studio 4.1中,有新的数据库检查器

https://developer.android.com/studio/preview/features/images/database-inspector.gif

您可以从菜单栏中选择以下选项View > Tool Windows > Database Inspector以将其打开。可以在此博客中找到更详细的说明。

另一种方法是为此使用stetho。您添加依赖项,然后可以在插入设备后使用Chrome DevTools(chrome:// inspect)检查数据库。


1

您需要以root用户身份运行adb,或者在有根电话上使用它。

要以root身份运行adb,请使用 adb root

另请参阅:为什么使用adb时拒绝访问数据文件夹?


我已经尝试过了。但这给了我“ adb无法在生产版本中作为根运行”
Primal Pappachan 2011年

您需要在“调试”模式下运行它。
Malfist 2011年

看到这个:mydroidworld.com/forums/android-hacks/…如果您是在手机而不是模拟器上运行它,则必须将其植根。
Malfist 2011年

我在调试模式下运行该应用程序,并尝试了上述步骤。没用
Primal Pappachan 2011年

这仅适用于仿真器或有根设备。
洛特

1

run-as在Android 4.4.2上,没有“ 猫到猫”的解决方案对我有用。我不确定,但是我怀疑这可能是由于该run-as工具无法正确处理新内容sdcard_rsdcard_rw权限。

我首先必须将数据库文件复制到/files应用程序的专用内部存储中:

shell@hammerhead:/ $ run-as com.example.myapp   
shell@hammerhead:/data/data/com.example.myapp $ cp databases/mydb files/mydb

然后我复制到/sdcard/Android/data/com.example.myapp/filesJavaland中(需要WRITE_EXTERNAL_STORAGE权限):

public class MainActivity extends BaseActivity {

    @Override
     protected void onCreate(Bundle savedInstanceState) {
         ...

         if (isExternalStorageWritable()) {
             final FileInputStream input;
             try {
                 input = openFileInput("mydb");

                 File output = new File(getExternalFilesDir(null), "mydb");

                 copy(input, output);
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }

     public void copy(FileInputStream in, File dst) throws IOException {
         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);
         }
         in.close();
         out.close();
     }

     public boolean isExternalStorageWritable() {
         String state = Environment.getExternalStorageState();
         return Environment.MEDIA_MOUNTED.equals(state);
     }
 }

最后,我将文件复制到笔记本电脑上:

$ adb pull /sdcard/Android/data/com.example.myapp/files/mydb

1
有一个更简单的解决方案。如果将sqlite文件更改为chmod 777,然后退出运行方式,则可以按常规将其复制到/ sdcard。
zedix

1

我的设备没有SD卡

所以第一个解决方案对我不起作用。

如果您遇到类似的问题,请尝试如下操作:

  adb shell "run-as package chmod 777 /data/data/package/databases/yourdb.sqlite";
  adb pull /data/data/package/databases/yourdb.sqlite

/sdcard不一定是SD卡。在我的手机上,当没有物理SD卡时,它指向内部存储。
DearVolt

0

试试这个应用程序:SQLiteWeb(https://play.google.com/store/apps/details?id=br.com.cm.sqliteweb)。它提供对数据库的远程访问,而无需将其撤出。

在付费版本中,它具有对私有数据库(/ data / data / package-name ...)的root访问权,或实现了内容提供程序以使用SQLiteWeb进行连接(应用内指令)

但是,如果要保留免费版本,则可以在外部存储中创建数据库:

database = SQLiteDatabase.openDatabase(Environment.getExternalStorageDirectory()
        + "/" + DATABASE_NAME, null, DATABASE_VERSION);

0

在OSX上,将@Tadas答案与automator和sqllitebrowser(https://github.com/sqlitebrowser/sqlitebrowser)结合使用:

  1. 打开Automator并创建新的工作流程。

  2. 添加“运行Shell脚本”操作。

  3. 粘贴此:

    源〜/ .bash_profile adb shell'运行为cat /data/data/your_app_uid/databases/db.name> /tmp/db.name'adb pull /tmp/db.name〜/ open-一个sqlitebrowser〜/ db。名称

  4. 单击运行以刷新sqlitebrowser上的数据库。


0
  1. 打开一个终端
  2. cd <ANDROID_SDK_PATH>(对于Windows上的我cd C:\Users\Willi\AppData\Local\Android\sdk
  3. cd platform-tools
  4. adb shell (这仅在仅运行一个模拟器时有效)
  5. cd data/data
  6. su (获得超级用户权限)
  7. cd <PACKAGE_NAME>/databases
  8. sqlite3 <DB_NAME>
  9. 发出SQL语句(重要:用终止它们;,否则不发出该语句,而是换行。)

注意:如果需要列出目录内容,请使用ls(Linux)或dir(Windows)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.