使用 run-as 从内部存储中检索数据库或任何其他文件

Posted

技术标签:

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

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

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

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

【问题讨论】:

试试 adb pull ***.com/questions/8650407/… ***.com/questions/13006315 无root设备拉取数据库 【参考方案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:\UsersuserName\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】:

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

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

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

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

【讨论】:

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

如果有人正在寻找另一个可用于检索 DatabaseShared 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 并使用 userdebugeng 软件刷新手机之前,这就是您手机上的内容)限制对 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)提取到当前目录中。

【讨论】:

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

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

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

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

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

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

【讨论】:

这个脚本是用于可调试应用程序的,如果应用程序不可调试呢? 如果有问题的应用程序将该数据作为备份的一部分公开,则您唯一的选择可能是使用备份工具。除此之外,恐怕还需要提升权限。【参考方案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 文件。

以上是关于使用 run-as 从内部存储中检索数据库或任何其他文件的主要内容,如果未能解决你的问题,请参考以下文章

如何从手机(外部/内部)存储中选择图像并上传到 sqlite 数据库?

如何从任何类型的数据库(pdf、xlx、jpg 或 png)中检索文件并使其可在网页上下载?

从内部连接表中检索最新记录

如何从android应用程序导出数据库?使用 ADB run-as 清空数据库结果

使用存储过程从视图中检索或过滤数据是不是比使用存储过程从表中获取或过滤数据更快?

从服务器检索图像,将其存储在 localStorage 中,并显示它