使用 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
copy
或 move
命令?我想下载数据库文件并使用数据库浏览器查看其内容。
这里的一个答案涉及将整个应用程序包转换为压缩存档,但没有进一步的答案说明一旦完成并移动到机器上如何提取该存档,当可能有更直接的解决方案时让我非常迷茫开始
【问题讨论】:
试试 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】:如果有人正在寻找另一个可用于检索 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 > 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 应用程序,例如 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 文件。以上是关于使用 run-as 从内部存储中检索数据库或任何其他文件的主要内容,如果未能解决你的问题,请参考以下文章
如何从手机(外部/内部)存储中选择图像并上传到 sqlite 数据库?
如何从任何类型的数据库(pdf、xlx、jpg 或 png)中检索文件并使其可在网页上下载?
如何从android应用程序导出数据库?使用 ADB run-as 清空数据库结果