如何才能拉自己的Android应用程序的(私人)数据?
尝试使用单个文件
adb pull /data/data/com.corp.appName/files/myFile.txt myFile.txt
失败
failed to copy '/data/data/com.corp.appName/files/myFile.txt myFile.txt' to 'myFile.txt': Permission denied
尽pipe设备上启用了USBdebugging。
我们可以通过古老的路线来解决问题
adb shell run-as com.corp.appName cat files/myFile.txt > myFile.txt
但是这对于多个文件来说是很笨拙的。
如何将目录/data/data/com.corp.appName/files拉到我的MacBook?
直接或者通过`/ storage / sdcard0 / myDir(从我可以继续使用Android文件传输的地方)的过境来做到这一点都不错。
额外的评论
这可能只是跑步
adb backup -f myFiles com.corp.appName
将生成我正在寻找的文件。 在这种情况下,我正在寻找一种方法来解压/解压缩生成的备份!
adb备份将写一个Android特定的档案:
adb backup -f myAndroidBackup.ab com.corp.appName
这个档案可以转换成tar格式,使用:
dd if=myAndroidBackup.ab bs=24 skip=1 | openssl zlib -d > myAndroidBackup.tar
参考:
http://nelenkov.blogspot.ca/2012/06/unpacking-android-backups.html
在该链接上search“更新”。
或者,使用Android备份提取器从Android备份( .ab
)文件中提取文件。
我有同样的问题,但解决它运行以下:
$ adb shell $ run-as {app-package-name} $ cd /data/data/{app-package-name} $ chmod 777 {file} $ cp {file} /mnt/sdcard/
之后你可以运行
$ adb pull /mnt/sdcard/{file}
这是什么对我有用:
adb -d shell "run-as com.example.test cat /data/data/com.example.test/databases/data.db" > data.db
我正在将数据库直接打印到本地文件中。
在MacOSX上,通过结合来自Calaf和Ollie Ford的答案,以下为我工作。
在命令行(确保adb在你的path中,我的是在〜/ Library / Android / sdk / platform-tools / adb),并且在你的android设备插入并且在USBdebugging模式下运行:
adb backup -f backup com.mypackage.myapp
您的Android设备将要求您备份您的数据的权限。 select“备份我的数据”
等一下。
文件备份将出现在您运行adb的目录中。
现在运行:
dd if=backup bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" > backup.tar
现在你将拥有一个backup.tar文件,你可以像这样解压:
tar xvf backup.tar
并查看您的应用程序存储的所有文件。
你可以在下面使用这个shell脚本。 它也能够从应用程序caching拉取文件,而不像adb backup
工具:
#!/bin/sh if [ -z "$1" ]; then echo "Sorry script requires an argument for the file you want to pull." exit 1 fi adb shell "run-as com.corp.appName cat '/data/data/com.corp.appNamepp/$1' > '/sdcard/$1'" adb pull "/sdcard/$1" adb shell "rm '/sdcard/$1'"
那么你可以像这样使用它:
./pull.sh files/myFile.txt ./pull.sh cache/someCachedData.txt
这个答案是基于我的经验与其他答案,并在答案的意见。 我的希望是我可以帮助处于类似情况的人。
我正在通过terminal在OSX上执行此操作。
以前Vinicius Avellar的回答对我很好。 我只是大部分时间都需要来自debugging应用程序的设备数据库。
今天我有一个用例,我需要多个私人文件 。 我结束了两个解决scheme,对这种情况有效。
使用接受的答案以及Someone Somewhere的OSX特定注释。 创build备份并使用第三方解决schemesourceforge.net/projects/adbextractor/files/?source=navbar将其解压缩成 tar。 在这个答案的底部,我将更详细地介绍这个解决scheme的经验。 向下滚动,如果这是你正在寻找。
我解决了一个更快的解决scheme。 我创build了一个类似于Tamas的答案的拉多个文件的脚本。 我可以这样做,因为我的应用程序是一个debugging应用程序,我有权访问我的设备上运行。 如果您没有权限运行,则在OSX上,此方法不适用于您。
这是我的脚本拉动多个私人文件,我将分享给你,读者,谁也在调查这个真棒问题;):
#!/bin/bash # # Strict mode: http://redsymbol.net/articles/unofficial-bash-strict-mode/ set -euo pipefail IFS=$'\n\t' # # Usage: script -f fileToPull -p packageName # # This script is for pulling private files from an Android device # using run-as. Note: not all devices have run-as access, and # application must be a debug version for run-as to work. # # If run-as is deactivated on your device use one of the # alternative methods here: # http://stackoverflow.com/questions/15558353/how-can-one-pull-the-private-data-of-ones-own-android-app # # If you have encrypted backup files use: # sourceforge.net/projects/adbextractor/files/?source=navbar # From comments in the accepted answer in the above SO question # # If your files aren't encrypted use the accepted answer # ( see comments and other answers for OSX compatibility ) # # This script is open to expansions to allow selecting # device used. Currently first selected device from # adb shell will be used. #Check we have one connected device adb devices -l | grep -e 'device\b' > /dev/null if [ $? -gt 0 ]; then echo "No device connected to adb." exit 1 fi # Set filename or directory to pull from device # Set package name we will run as while getopts f:p: opt; do case $opt in f) fileToPull=$OPTARG ;; p) packageName=$OPTARG ;; esac done; # Block file arg from being blank if [ -z "$fileToPull" ]; then echo "Please specify file or folder to pull with -f argument" exit 1 fi # Block package name arg from being blank if [ -z "$packageName" ]; then echo "Please specify package name to run as when pulling file" exit 1 fi # Check package exists adb shell pm list packages | grep "$packageName" > /dev/null if [ $? -gt 0 ]; then echo "Package name $packageName does not exist on device" exit 1 fi # Check file exists and has permission with run-as fileCheck=`adb shell "run-as $packageName ls $fileToPull"` if [[ $fileCheck =~ "Permission denied" ]] || [[ $fileCheck =~ "No such file or directory" ]]; then echo "Error: $fileCheck" echo "With file -> $fileToPull" exit 1 fi # Function to pull private file # # param 1 = package name # param 2 = file to pull # param 3 = output file function pull_private_file () { mkdir -p `dirname $3` echo -e "\033[0;35m***" >&2 echo -e "\033[0;36m Coping file $2 -> $3" >&2 echo -e "\033[0;35m***\033[0m" >&2 adb shell "run-as $1 cat $2" > $3 } # Check if a file is a directory # # param 1 = directory to check function is_file_dir() { adb shell "if [ -d \"$1\" ]; then echo TRUE; fi" } # Check if a file is a symbolic link # # param 1 = directory to check function is_file_symlink() { adb shell "if [ -L \"$1\" ]; then echo TRUE; fi" } # recursively pull files from device connected to adb # # param 1 = package name # param 2 = file to pull # param 3 = output file function recurse_pull_private_files() { is_dir=`is_file_dir "$2"` is_symlink=`is_file_symlink "$2"` if [ -n "$is_dir" ]; then files=`adb shell "run-as $1 ls \"$2\""` # Handle the case where directory is a symbolic link if [ -n "$is_symlink" ]; then correctPath=`adb shell "run-as $1 ls -l \"$2\"" | sed 's/.*-> //' | tr -d '\r'` files=`adb shell "run-as $1 ls \"$correctPath\""` fi for i in $files; do # Android adds nasty carriage return that screws with bash vars # This removes it. Otherwise weird behavior happens fileName=`echo "$i" | tr -d '\r'` nextFile="$2/$fileName" nextOutput="$3/$fileName" recurse_pull_private_files "$1" "$nextFile" "$nextOutput" done else pull_private_file "$1" "$2" "$3" fi } recurse_pull_private_files "$packageName" "$fileToPull" "`basename "$fileToPull"`"
要点: https : //gist.github.com/davethomas11/6c88f92c6221ffe6bc26de7335107dd4
回到方法1 ,使用Android Backup Extractor解密备份
以下是我在Mac上采取的步骤,以及我遇到的问题:
首先我排队备份(并设置密码来encryption我的备份,我的设备需要它):
adb backup -f myAndroidBackup.ab com.corp.appName
第二我从这里下载abe.jar: https ://sourceforge.net/projects/adbextractor/files/abe.jar/download
接下来我跑了:
java -jar ./abe.jar unpack myAndroidBackup.ab myAndroidBackup.tar
此时我收到一条错误消息。 由于我的档案被encryption,Java给了我一个错误,我需要安装一些安全策略库。
- 所以我去http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html并下载我需要的安全策略jar子。; 现在在我的情况下,安装说明告诉我放置jar文件的位置是错误的。 它说适当的位置是<java-home> / lib / security 。 我把他们放在那里,仍然有错误信息。 所以我调查了一下,在我的Mac上用Java 1.8正确放置它们的地方是: <java-home> / jre / lib / security 。 我确保备份原来的策略jar子,并把它们放在那里。 沃拉我能够input密码与abe.jar和解密到一个tar文件。
最后我刚跑( 在再次运行上一个命令之后 )
tar xvf myAndroidBackup.tar
现在需要注意的是,如果你可以运行,像猫一样,速度要快得多。 一,你只得到你想要的文件,而不是整个应用程序。 二,更多的文件(encryption对我来说)使传输速度变慢。 所以,如果你没有在OSX上运行,那么知道这样做是很重要的,但是脚本应该首先转到debugging应用程序。
请注意,我今天只是写了一遍,经过几次testing,所以请告诉我任何错误!
通过添加以下代码设置正确的权限后:
File myFile = ...; myFile.setReadable(true, false); // readable, not only for the owner
adb pull
按需要工作。
请参阅File.setReadable()
从Dave Thomas脚本开始我已经能够写出自己的解决scheme来克服2个问题:
- 我的备份只包含清单文件
- 与戴夫托马斯得到的二进制文件不可读
这是我的脚本,它将应用程序数据复制到SD卡,然后将其拖动
#Check we have one connected device adb devices -l | grep -e 'device\b' > /dev/null if [ $? -gt 0 ]; then echo "No device connected to adb." exit 1 fi # Set filename or directory to pull from device # Set package name we will run as while getopts f:p: opt; do case $opt in f) fileToPull=$OPTARG ;; p) packageName=$OPTARG ;; esac done; # Block package name arg from being blank if [ -z "$packageName" ]; then echo "Please specify package name to run as when pulling file" exit 1 fi # Check package exists adb shell pm list packages | grep "$packageName" > /dev/null if [ $? -gt 0 ]; then echo "Package name $packageName does not exist on device" exit 1 fi adb shell "run-as $packageName cp -r /data/data/$packageName/ /sdcard/$packageName" adb pull /sdcard/$packageName adb shell rm -rf /sdcard/$packageName
与Tamas的答案类似,这里是Mac OS X的your.app.id
,用你的设备从your.app.id
获取应用程序的所有文件,并保存到(在这种情况下) ~/Desktop/your.app.id
:
( id=your.app.id && dest=~/Desktop && adb shell "run-as $id cp -r /data/data/$id /sdcard" && adb -d pull "/sdcard/$id" "$dest" && if [ -n "$id" ]; then adb shell "rm -rf /sdcard/$id"; fi )
- 从模拟器中排除
-d
- 不要踩你的会话variables
- 您可以将整个块粘贴到Terminal.app中(或者如果需要,可以删除换行符)
使用apk备份游戏数据 。 牛轧糖Oneplus 2。
**adb backup "-apk com.nekki.shadowfight" -f "c:\myapk\samsung2.ab"**
这是否意味着可以从世界chmod目录:-x到world:rx足够长以便能够获取文件?
对,就是这样。 奇怪的是,你也需要文件来设置x
位。 (至less在Android 2.3上)
chmod 755
一直向下工作来复制一个文件(但是如果你打算继续使用这个设备,你应该在之后恢复权限)。