【问题标题】:Debugging sqlite database on the device在设备上调试 sqlite 数据库
【发布时间】:2011-10-19 05:18:58
【问题描述】:

我目前正在开发适用于 Android 的 WiFi 应用程序。我在尝试访问设备上的数据库时遇到问题。在模拟器中调试对我不起作用,因为模拟器中没有 WiFi 支持。我尝试使用

将数据库文件从设备中拉出
adb pull data/data/package-name/databases/database-name

但我收到错误“权限被拒绝。”。 在这个答案Android: Where are database files stored? 中,Commonsware 建议通过在调试模式下运行来提取数据库文件。但它也不起作用。任何有关如何在不生根设备的情况下调试数据库的帮助将不胜感激。

【问题讨论】:

    标签: android sqlite adb


    【解决方案1】:

    我会从another answer重复我自己:

    从 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 权限,因为复制是由始终可以写入外部存储的 shell 用户完成的。

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

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

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

    【讨论】:

    • @MikeIsrael 以防万一,您不会在您的应用程序中使用 SQLCipher 吗?如果没有,则大致检查数据库是否下载正确,在查看器(最好是十六进制查看器)中打开数据库文件并检查它是否以SQLite format 3字符串开头。还要确保你有一个正确的sqlite 版本(即你不是试图用 sqlite2 可执行文件打开 sqlite3 数据库)。您也可以尝试其他 SQLite 客户端(例如 SQLiteStudio)。希望对您有所帮助。
    • 我在使用一个班轮时遇到了问题。如果我在 shell 中运行命令,它可以正常工作,但如果我放入一个衬垫,我会得到:系统找不到指定的路径。
    • package 未知...任何人都知道为什么。我通过按调试按钮通过工作室安装。
    • 在 Android Lollipop 上,我收到了 permission denied
    • 我提取了一个数据库,其中包含两个表,每个表有十几行,并对每个表进行全选择查询。一个工作正常,另一个报告文件中的数据错误。我现在最好的猜测是 Android 和本地 shell 之间的编码不匹配。
    【解决方案2】:

    我在我的 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
    

    【讨论】:

    【解决方案3】:

    查看和管理你的安卓应用数据库的最好方法是使用这个库https://github.com/sanathp/DatabaseManager_For_Android

    使用这个库,您可以从您的应用程序本身管理您的应用程序 SQLite 数据库。 您可以查看应用数据库中的表格、更新、删除、向表格中插入行。一切都来自您的应用。

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

    对我帮助很大。希望对你也有帮助。

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

    【讨论】:

      【解决方案4】:

      虽然,这是一个老问题,但我认为它仍然具有相关性,值得当前状态的答案。有一些可用的工具可以让您直接检查数据库(无需从设备或模拟器中提取它们)。

      我最近发现(并且最喜欢)的工具是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】:

        在我的应用程序中,我将数据库导出到 SD 卡。一旦数据库在 SD 卡上,就可以通过将设备插入计算机来访问它。

        看这个帖子:Making a database backup to SDCard on Android

        【讨论】:

          【解决方案6】:

          如果你得到

          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"
          

          注意双引号!

          【讨论】:

            【解决方案7】:

            在新的 Android Studio 4.1 中有新的Database Inspector

            您可以从菜单栏View > Tool Windows > Database Inspector 中选择以下选项来打开它(Android Studio 4.2 中的App Inspector)。更详细的说明可以在this blogExploring the Database Inspector in Android Studio 中号文章中找到。

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

            【讨论】:

            • 这是 2020 年及以后的最佳选择
            【解决方案8】:

            我只是做了:

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

            然后我可以使用正确的权限从 shell 调试一个 sqlite 数据库或我想做的任何事情。

            【讨论】:

              【解决方案9】:

              如果 apk 可调试,则有一种方法可以使用(非根)adb shell 中名为 run-as 的程序来复制应用程序的私有文件。

              【讨论】:

                【解决方案10】:

                这里是分步说明 - 主要来自其他答案的组合。这适用于未解锁的设备。

                1. 连接您的设备并在调试模式下启动应用程序。

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

                  ./adb -d shell 'run-as com.yourpackge.name cat /data/data/com.yourpackge.name/databases/filename.sqlite > /sdcard/filename.sqlite'

                3. 将数据库文件拉到你的机器上:执行:

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

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

                5. 打开 Firefox SQLLite 管理器并打开上述第 3 步中的数据库文件。

                6. 享受吧!

                【讨论】:

                  【解决方案11】:

                  Android Studio 4.1 添加了查看/编辑 Android SQLite 数据库的新功能。

                  如何打开数据库检查器

                  要在 Android Studio 中打开 Database Inspector,您需要从菜单栏中选择 View > Tool Windows > Database Inspector

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

                  使用这个工具你可以

                  • 查询您的数据库

                  • 修改和调试您的数据库

                  【讨论】:

                    【解决方案12】:

                    您需要以 root 身份运行 adb,或者在有 root 权限的手机上使用它。

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

                    另请参阅:Why do I get access denied to data folder when using adb?

                    【讨论】:

                    • 我试过这个。但它给了我“adb 不能在生产构建中以 root 身份运行”
                    • 您需要在调试模式下运行它。
                    • 看这个:mydroidworld.com/forums/android-hacks/… 如果你在手机而不是模拟器上运行它,你必须root它。
                    • 我在调试模式下运行应用程序并尝试了上述步骤。它不起作用。
                    • 这仅适用于模拟器或有根设备。
                    【解决方案13】:

                    run-as-and-cat-to-sdcard 解决方案均不适用于 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
                    

                    然后我复制到Javaland中的/sdcard/Android/data/com.example.myapp/files(这需要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
                    

                    【讨论】:

                    • 有一个更简单的解决方案。如果你 chmod 777 你的 sqlite 文件,然后退出 run-as,它会让你将它复制到 /sdcard 作为常规使用。
                    【解决方案14】:

                    我的设备没有 sdcard

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

                    如果你有类似的问题,试试这样:

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

                    【讨论】:

                    • /sdcard 不一定是 SD 卡。在我的手机上,当没有物理 SD 卡时,它指向内部存储。
                    【解决方案15】:

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

                    在付费版本中,它具有私有数据库 (/data/data/package-name...) 的 root 访问权限或实现一个 Content Provider 以使用 SQLiteWeb 进行连接(应用程序内的说明)

                    但如果想继续使用免费版本,您可以在外部存储中创建数据库:

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

                    【讨论】:

                      【解决方案16】:

                      在 OSX 上,使用带有 automator 和 sqllitebrowser(https://github.com/sqlitebrowser/sqlitebrowser) 的 @Tadas 回答:

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

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

                      3. 粘贴这个:

                        来源 ~/.bash_profile adb shell 'run-as cat /data/data/your_app_uid/databases/db.name > /tmp/db.name' adb pull /tmp/db.name ~/ 打开 -a sqlitebrowser ~/db.name

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

                      【讨论】:

                        【解决方案17】:
                        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)。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2012-03-20
                          • 1970-01-01
                          • 2014-08-25
                          • 1970-01-01
                          • 1970-01-01
                          • 2015-03-29
                          相关资源
                          最近更新 更多