【问题标题】:How to check database on not rooted android device如何在未植根的 android 设备上检查数据库
【发布时间】:2013-07-26 20:19:48
【问题描述】:

我正在开发一个应用程序,我在其中使用 sqllite3 数据库来存储值。我有 Nexus S 和 Nexus 7 都是无根设备。如何获取我的应用程序的数据库以进行调试。

我试过了 (1) 我已经尝试了here

提到的所有方法
adb shell
run-as app.package.name \
cp /data/data/package.name/databases/application.sqlite /sdcard/
exit
adb pull /sdcard/application.sqlite ~/

这表示 cp not found..

(2)http://developer.android.com/tools/help/adb.html#sqlite

adb -s emulator-5554 shell
# sqlite3 /data/data/com.example.google.rss.rssexample/databases/rssitems.db
SQLite version 3.3.12
Enter ".help" for instructions
.... enter commands, then quit...
sqlite> .exit 

【问题讨论】:

标签: android sqlite adb android-contentprovider android-sqlite


【解决方案1】:

以下解决方案仅适用于可调试的应用。它可能无法在所有设备上正常工作,因为 run-as 命令在某些设备上不起作用,尤其是在 Jelly Bean 上。

  1. ​创建一个*.bat文件并复制以下脚本​​​

    adb shell run-as [package] chmod 777 /data/data/[package]/databases/

    adb shell run-as [package] chmod 777 /data/data/[package]/databases/[db_file_name]

    adb shell run-as [package] cp /data/data/[package]/databases/[db_file_name] /sdcard/

    adb pull /sdcard/[db_file_name]

  2. ​将 [package] 更改为所需的应用程序包

  3. 将 [db_file_name] 更改为所需的数据库名称 运行 bat 文件并 您应该在与 bat 相同的文件夹中看到复制的数据库 文件

上述解决方案假设:

  • 您正在使用 Windows
  • 设备已连接并在下方可见 “adb 设备”

【讨论】:

  • 如何找到 db_file_name。它说没有这样的文件或目录
  • @SergeyDirin 您需要将名称更改为您在应用中设置的实际文件名
  • 不,在我的情况下,数据库位于 /data/Users/[package]/databases/ 如果我记得它是 coreclty。您可以使用 getApplicationContext().getDatabasePath(DATABASE_NAME) 找到确切位置
【解决方案2】:

您可以使用以下命令将数据库写入外部内存:

private void writeToSD() throws IOException {
    File sd = Environment.getExternalStorageDirectory();

    if (sd.canWrite()) {
        String currentDBPath = DB_NAME;
        String backupDBPath = "backupname.db";
        File currentDB = new File(DB_PATH, currentDBPath);
        File backupDB = new File(sd, backupDBPath);

        if (currentDB.exists()) {
            FileChannel src = new FileInputStream(currentDB).getChannel();
            FileChannel dst = new FileOutputStream(backupDB).getChannel();
            dst.transferFrom(src, 0, src.size());
            src.close();
            dst.close();
        }
    }
}

其中DB_NAME 是我的数据库的名称,DB_PATH 定义如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        DB_PATH = context.getFilesDir().getAbsolutePath().replace("files", "databases") + File.separator;
    }
    else {
        DB_PATH = context.getFilesDir().getPath() + context.getPackageName() + "/databases/";
    }

并添加以下权限(感谢@Sathesh 指出这一点):

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

每当我有数据库写入时,我都会调用此方法,以便我最新的数据库文件位于外部存储器中,我可以从那里查看和调试。

然后您可以使用X-Plore app 直接在Android 设备上从外部存储器查看数据库。

【讨论】:

  • 需要添加外部存储权限。您可以使用“context.getDatabasePath(dbName).toString()”以编程方式获取 dbpath
  • 我收到原始数据库文件的 FILE NOT FOUND 异常。我有一个无根的关系 4。我已经交叉检查了路径。
  • @geekoraul 您确定调用中的数据库名称和路径正确吗?
  • 非常确定。我什至通过 ADB shell 上的 run-as 命令浏览应用程序目录来检查它。我还更改了原始数据库文件的权限
  • @geekoraul 这很奇怪......听起来文件不是你想的地方,或者它不是创建的,这似乎不太可能......
【解决方案3】:

如果你不知道你的应用程序路径,那么你可以使用这个:

public void copyAppDbToExternalStorage() throws IOException {
    File sd = Environment.getExternalStorageDirectory();
    File currentDB = getApplicationContext().getDatabasePath("databaseName"); //databaseName=your current application database name, for example "my_data.db"
    if (sd.canWrite()) {
        File backupDB = new File(sd, "toDatabaseName"); // for example "my_data_backup.db"
        if (currentDB.exists()) {
            FileChannel src = new FileInputStream(currentDB).getChannel();
            FileChannel dst = new FileOutputStream(backupDB).getChannel();
            dst.transferFrom(src, 0, src.size());
            src.close();
            dst.close();
        }
    }
}

或者,如果您需要将数据库复制到公共“下载”文件夹,那么您可以使用:

public void copyAppDbToDownloadFolder() throws IOException {
    File backupDB = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "toDatabaseName"); // for example "my_data_backup.db"
    File currentDB = getApplicationContext().getDatabasePath("databaseName"); //databaseName=your current application database name, for example "my_data.db"
    if (currentDB.exists()) {
        FileChannel src = new FileInputStream(currentDB).getChannel();
        FileChannel dst = new FileOutputStream(backupDB).getChannel();
        dst.transferFrom(src, 0, src.size());
        src.close();
        dst.close();
    }
}

这在我的 Nexus 4 设备上运行良好。

【讨论】:

    【解决方案4】:

    这是一个非常简单直接的答案:(在 Android 上测试:unrooted

    adb -d shell 
    $ run-as my.package.name
    $ cp databases/mydatabase.db /sdcard/mydatabase.db
    $ exit
    $ exit
    

    现在将您的数据库拉到默认的 adb 路径

    adb -d pull /sdcard/mydatabase.db
    

    或者,例如到您的桌面

    adb -d pull /sdcard/mydatabase.db C:\Users\user\Desktop
    

    您可能想使用以下命令删除副本:

    adb -d shell "rm /sdcard/mydatabase.db"
    

    -d 选项在有多个模拟器时选择默认设备。

    【讨论】:

    • 谢谢。我曾使用命令cp files/mydatabase.db /sdcard/mydatabase.db
    【解决方案5】:

    我只需要做这样的事情并且有办法做到这一点,尽管这很痛苦。您需要将该文件作为应用程序的用户帐户进行分类,然后将其通过管道传输到可写位置。这在我运行 4.3.3 的 Nexus 4 上对我有用:

    adb shell "run-as org.your.application cat /data/data/org.your.application/your-file > /mnt/sdcard/your-file"
    adb pull /mnt/sdcard/your-file
    

    【讨论】:

    • 数据库文件存储在 /data/data// databases /
    • 也用cat,写了一个空白文件。我使用cp &lt;src&gt; &lt;dest&gt; 让它工作。
    • 这也只适用于调试版本。尝试作为发布版本运行会给出run-as: Package '&lt;packagename&gt;' is not debuggable
    • 如果您关注所有 3 个 cmets,这是一个可行的解决方案,今天在 Nexus 5X 上为我工作!太糟糕了 OP 没有更新答案,否则我会 +1 ......感谢前 3 位评论者,@Ted Mielczarek,如果你更新答案,你将获得当之无愧的投票
    • 不确定是否增加了安全性更改,但是当我在 android O 上尝试时,由于某种原因导致 sdcard 文件为零字节
    【解决方案6】:

    尝试使用 facebook 开发的 stetho Library,它可以让您通过网络浏览器查看数据库https://facebook.github.io/stetho/

    【讨论】:

      【解决方案7】:
      adb shell "run-as CHR.Droid chmod 666 /data/data/CHR.Droid/files/CHR.db"
      adb shell cp /data/data/CHR.Droid/files/CHR.db /sdcard/
      

      在 Xamrin.forms 中,我必须将数据库替换为文件

      【讨论】:

        【解决方案8】:

        如果运行后

        adb shell "run-as your.package.name"
        

        您收到“run-as: Package 'your.package.name' is unknown”,然后尝试从模拟器获取数据库。见这里:https://stackoverflow.com/a/44089632/2914140

        在 Android Studio 3.0 中,单击查看 > 工具窗口 > 设备文件资源管理器。 展开 /data/data/[package-name] 节点。

        【讨论】:

          【解决方案9】:

          我认为这是最简单的方法。将此依赖项添加到您的 gradle 文件:debugImplementation 'com.amitshekhar.android:debug-db:1.0.0'

          之后,当您在控制台中启动应用程序时,您会看到以下消息: D/DebugDB:在浏览器中打开http://192.168.1.114:8080

          还有你的数据库。

          【讨论】:

            【解决方案10】:

            您无法访问非 root 设备上的 /data 文件夹

            没有办法做到这一点。 Android 拥有强大的安全机制。只有您的应用可以访问自己的文件。

            【讨论】:

            • 您仍然可以将数据库复制到 /data 之外的某个位置并在那里查看...
            • +1 当设备未root且应用程序处于非调试模式时,很难获取应用程序数据......即使使用run-as它也会失败......
            【解决方案11】:

            没有root的手机是不可能的。您无法访问 /data 目录,因此无法像(2)中那样复制数据库或使用 sqlite 应用程序。如果您需要调试,请使用模拟器,或从您的应用运行查询来检查数据库。

            【讨论】:

            • 您仍然可以将数据库复制到 /data 之外的某个位置并在那里查看...
            • @TronicZomB 确实,您可以从您的应用程序中执行此操作,但有时您无法修改源代码。由于 OP 能够修改源代码,因此您的答案是最好的。
            • 对,如果是别人的应用,那你就看不到数据库了。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-10-05
            • 2017-09-10
            • 1970-01-01
            • 2017-05-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多