【问题标题】:Retrieve database or any other file from the Internal Storage using run-as使用 run-as 从内部存储中检索数据库或任何其他文件
【发布时间】:2013-08-30 13:48:06
【问题描述】:

在非 root 的 android 设备上,我可以使用带有我的包名称的 run-as 命令导航到包含数据库的数据文件夹。大多数文件类型我只满足于查看,但如果从 android 设备中提取我想提取的数据库。

这部分 adb shell 是否有 download copy 或 move 命令?我想下载数据库文件并使用数据库浏览器查看其内容。

这里的一个答案涉及将整个应用程序包转换为压缩存档,但没有进一步的答案说明一旦完成并移动到机器上如何提取该存档,当可能有更直接的解决方案时让我非常迷茫开始

【问题讨论】:

标签: android database android-sqlite adb internal-storage


【解决方案1】:

从设备中提取应用程序数据库(以调试模式安装)的步骤

如果打开则关闭数据库连接

打开 cmd(命令提示符)(将 dir 更改为您的 adb 路径)

cd C:\Program Files (x86)\Android\android-sdk\platform-tools

(列出应用文件)

adb -d shell "run-as com.xyz.name ls /data/data/com.xyz.name/files/"

(将所需文件复制到 sdcard)

adb -d shell "run-as com.xyz.name cp /data/data/com.xyz.name/files/abc.db /sdcard/abc.db"

(从 sdcard 复制到机器 adb 文件夹)

adb pull /sdcard/abc.db

打开数据库连接

在我的情况下目标文件路径 C:\Users{userName}\AppData\Local\VirtualStore\Program Files (x86)\Android\android-sdk\platform-tools 或设备存储

【讨论】:

    【解决方案2】:

    使用adb run-as时,数据库文件为emtpy。这可以通过在 RoomDatabase 实例上调用 close() 来解决。调用 close() 让 SQLite 将其日志写入磁盘。 我创建了这个按钮,可以根据请求关闭数据库连接:

    via GIPHY

    Here is how to call close 在 RoomDatabase 实例上。

    【讨论】:

    • 我遇到了这个问题:数据库已复制但没有最新数据。在 db 文件复制之前关闭 db 连接解决了我的问题。
    【解决方案3】:

    这是一个适用于运行 Android 5.1 的设备的解决方案。以下示例适用于 Windows。

    您需要sed(或 Windows 上的 sed.exe,例如来自 cygwin。)(在 Unix 上,它就在那里;))。删除坏的 '\r' 字符,至少在 windows 上。

    现在只需运行以下命令:

    adb exec-out "run-as com.yourcompany.yourapp /data/data/com.yourcompany.yourapp/databases/YourDatabaseName" | c:\cygwin\bin\sed.exe 's/\x0D\x0A/\x0A/'>YourDatabaseName.db
    

    sed 命令去除尾随的 /r 字符。

    当然,您应该将“com.yourcompany.yourapp”替换为应用程序的包名称,将“YourDatabaseName”替换为应用程序中的数据库名称。

    【讨论】:

      【解决方案4】:
      #!/bin/bash
      #export for adb
      export PATH=$PATH:/Users/userMe/Library/Android/sdk/platform-tools
      export PATH=$PATH:/Users/userMe/Library/Android/sdk/tools
      
      adb -d shell 'run-as com.android.app  cp /data/data/com.android.app/files/db.realm /sdcard'
      adb pull sdcard/db.realm /Users/userMe/Desktop/db
      

      您可以使用此脚本获取 Realm 数据库。

      【讨论】:

        【解决方案5】:

        如果有人想从调试应用程序中提取数据库,可以使用以下过程:

        1. 搜索并打开设备文件浏览器

        1. 选择您的手机,然后浏览到data/data 目录

        1. 现在找到您的应用程序包并转到数据库文件夹。您可以在那里看到数据库,然后右键单击,您将获得选项 将其保存在您的驱动器中。

        【讨论】:

        • 哇,与使用 adb-shell 相比,它更容易、更安全
        • 在 Android Studio 4.1.3 查看->工具窗口->设备文件资源管理器
        • 最简单的方法!谢谢!
        【解决方案6】:

        如果有人正在寻找另一个可用于检索 Database 和 Shared Preferences 的答案,请按照以下步骤操作:

        在您的应用程序的build.gradle 文件中添加行

        debugCompile 'com.amitshekhar.android:debug-db:1.0.0'

        现在当您在non-release 模式下运行您的应用程序时,您的应用程序将自动从您的设备IP address 打开8080 端口,确保您的设备通过wifi 连接并且您的laptop 共享同一个网络。现在只需访问 url

        http://your_mobile_device_ip:8080/

        查看数据库的所有数据以及共享偏好。

        【讨论】:

          【解决方案7】:

          将文件下载到本地计算机的方法要简单得多:

          在您的 PC shell 中运行:

          adb -d shell 'run-as <package_name> cat /data/data/<package_name>/databases/<db_name>' > <local_file_name>
          

          【讨论】:

          • 非常接近,但这为我拉出了一个格式错误的数据库。
          【解决方案8】:

          根据设计user 构建的 Android(在您解锁 bootloader 并使用 userdebug 或 eng 软件刷新手机之前,这就是您手机上的内容)限制对 em>内部存储 - 每个应用程序只能访问自己的文件。幸运的是,对于不愿意root他们的手机的软件开发人员来说,Google 提供了一种使用run-as 访问其软件包的可调试版本的内部存储的方法命令。

          要从 Android 5.1+ 设备下载/data/data/debuggable.app.package.name/databases/file,请运行以下命令:

          adb exec-out run-as debuggable.app.package.name cat databases/file > file
          

          要一次下载/data/data/debuggable.app.package.name/ 下文件夹中的多个文件 - 使用tar:

          adb exec-out run-as debuggable.app.package.name tar c databases/ > databases.tar
          adb exec-out run-as debuggable.app.package.name tar c shared_prefs/ > shared_prefs.tar
          

          【讨论】:

          • 或者,只需使用run-as 将文件复制到外部存储上的某个位置,然后从那里提取数据库文件,而不是乱用文件权限。
          • run-as 没有写入 sdcard 的权限 - 最新更新中添加了一些新内容... :(
          • 当我运行 adb shell "run-as package.name chmod 666 /data/data/package.name/databases/file" adb end me error -->run-as: exec failed for chmod666错误:权限被拒绝。我在没有 root 的 Nexus 7 中
          • 使用 adb 无法再对外部 sd 卡进行写访问。
          • 如果您发现您正在返回一个空白或几乎空白的文件,您可能会发现该文件只是来自控制台的错误,该错误已被重定向到您创建的此文件。这里的一个常见问题是您试图从应用程序的 Release 变体中复制数据库。 您只能从应用的 Debug 变体复制数据库。如果发生这种情况,只需安装调试变体并再次尝试该命令。希望这对某人有所帮助。
          【解决方案9】:

          除了这个,我没有别的东西可以为我工作:

          adb shell
          run-as package.name
          cat /databases/databaseFileName.db > /sdcard/copiedDatabaseFileName.db
          exit
          exit
          adb pull /sdcard/copiedDatabaseFileName.db /file/location/on/computer/
          

          第一个exit是退出run-as,第二个exit是退出adb shell做pull。

          【讨论】:

            【解决方案10】:

            对于应用程序的调试版本,使用命令adb exec-out run-as xxx.yyy.zzz cat somefile &gt; somefile提取单个文件非常方便。但是您必须对多个文件执行多次。这是我用来提取目录的简单脚本。

            #!/bin/bash
            P=
            F=
            D=
            
            function usage()
            {
                echo "$(basename $0) [-f file] [-d directory] -p package"
                exit 1
            }
            
            while getopts ":p:f:d:" opt
            do
                case $opt in
                    p)
                        P=$OPTARG
                        echo package is $OPTARG
                        ;;
                    f)
                        F=$OPTARG
                        echo file is $OPTARG
                        ;;
                    d)
                        D=$OPTARG
                        echo directory is $OPTARG
                        ;;
                    \?)
                        echo Unknown option -$OPTARG
                        usage
                        ;;
                    \:)
                        echo Required argument not found -$OPTARG
                        usage
                        ;;
                esac
            done
            
            [ x$P == x ] && {
                echo "package can not be empty"
                usage
                exit 1
            }
            
            [[ x$F == x  &&  x$D == x ]] && {
                echo "file or directory can not be empty"
                usage
                exit 1
            }
            
            function file_type()
            {
                # use printf to avoid carriage return
                __t=$(adb shell run-as $P "sh -c \"[ -f $1 ] && printf f || printf d\"")
                echo $__t
            }
            
            function list_and_pull()
            {
                t=$(file_type $1)
                if [ $t == d ]; then
                    for f in $(adb shell run-as $P ls $1)
                    do
                        # the carriage return output from adb shell should
                        # be removed
                        mkdir -p $(echo -e $1 |sed $'s/\r//')
                        list_and_pull $(echo -e $1/$f |sed $'s/\r//')
                    done
                else
                    echo pull file $1
                    [ ! -e $(dirname $1) ] && mkdir -p $(dirname $1)
                    $(adb exec-out run-as $P cat $1 > $1)
                fi
            }
            
            [ ! -z $D ] && list_and_pull $D
            [ ! -z $F ] && list_and_pull $F
            

            希望对您有所帮助。这个脚本也可以在gist 获得。

            典型用法是

            $ ./exec_out.sh -p com.example.myapplication -d databases
            

            然后它会将您的应用程序数据库目录下的所有文件(/data/data/com.example.myapplication/databases)提取到当前目录中。

            【讨论】:

            • 即使对于多个文件,它仍然只是一个命令。检查更新stackoverflow.com/a/18472135/1778421 如果您愿意,还可以在主机端添加另一个管道来解压文件
            【解决方案11】:

            我已经发布了一个用于转储数据库的简单 shell 脚本:

            https://github.com/Pixplicity/humpty-dumpty-android

            它执行这里描述的两种不同的方法:

            1. 首先,它尝试使其他用户可以访问该文件,并尝试将其从设备中拉出。
            2. 如果失败,它将通过终端将文件内容流式传输到本地计算机。它执行了一个额外的技巧来删除某些设备输出到 shell 的 \r 字符。

            从这里您可以使用各种 CLI 或 GUI SQLite 应用程序,例如 sqlite3 或 sqlitebrowser,来浏览数据库的内容。

            【讨论】:

            • 这个脚本是用于可调试应用程序的,如果应用程序不可调试呢?
            • 如果有问题的应用程序将该数据作为备份的一部分公开,则您唯一的选择可能是使用备份工具。除此之外,恐怕还需要提升权限。
            【解决方案12】:

            接受的答案对我来说不再有效(被 Android 阻止了?)

            所以我这样做了:

            > adb shell
            shell $ run-as com.example.package
            shell $ chmod 666 databases/file
            shell $ exit                                               ## exit out of 'run-as'
            shell $ cp /data/data/package.name/databases/file /sdcard/
            shell $ run-as com.example.package
            shell $ chmod 600 databases/file
            > adb pull /sdcard/file .
            

            【讨论】:

            • 这应该是新的正确答案或@Alex P。您应该为较新的 Android 版本添加此答案。同样在我的情况下,我必须先使用 777 并将其应用于数据库目录,然后才能访问 db 文件。
            • 我的设备已root,但我发现我仍然需要运行su 才能使run-as 命令正常工作。
            • 没有SD卡怎么办?
            • 如果你没有 SD 卡,反正还有一个“sdcard”目录。
            • 太棒了!它也对我有用。我们可以制作批处理/shell文件吗?只需将 db 文件名作为参数传递,我们就有了 db 文件。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-18
            • 1970-01-01
            • 2019-06-09
            • 2016-07-29
            • 2020-02-09
            • 1970-01-01
            相关资源
            最近更新 更多