106

尝试使用拉取单个文件

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

尽管在设备上启用了 USB 调试。

我们可以通过古老的路线绕过这个问题

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

将生成我正在寻找的文件。在这种情况下,我正在寻找一种解压缩/解压缩生成备份的方法!

4

14 回答 14

121

adb backup 将写入一个特定于 Android 的存档:

adb backup  -f myAndroidBackup.ab  com.corp.appName

可以使用以下方法将此存档转换为 tar 格式:

dd if=myAndroidBackup.ab bs=4K iflag=skip_bytes skip=24 | openssl zlib -d > myAndroidBackup.tar

参考:

http://nelenkov.blogspot.ca/2012/06/unpacking-android-backups.html

在该链接中搜索“更新”。


或者,使用Android 备份提取器从 Android 备份 ( .ab) 文件中提取文件。

于 2013-03-21T22:17:54.223 回答
59

我有同样的问题,但解决了它运行如下:

$ 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}
于 2015-06-05T06:54:26.357 回答
35

这对我有用:

adb -d shell "run-as com.example.test cat /data/data/com.example.test/databases/data.db" > data.db

我将数据库直接打印到本地文件中。

于 2015-07-19T18:03:50.150 回答
23

在 MacOSX 上,通过结合 Calaf 和 Ollie Ford 的答案,以下内容对我有用。

在命令行上(确保 adb 在您的路径中,我的路径是 ~/Library/Android/sdk/platform-tools/adb),并且您的 android 设备已插入并处于 USB 调试模式,运行:

 adb backup -f backup com.mypackage.myapp

您的 Android 设备会询问您是否允许备份您的数据。选择“备份我的数据”

稍等片刻。

文件备份将出现在您运行 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

并查看您的应用程序存储的所有文件。

于 2015-08-27T21:56:37.453 回答
11

较新版本的 Android Studio 包括设备文件资源管理器,我发现它是一种方便的 GUI 方法,可以从我的开发 Nexus 7 下载文件。

您必须确保已在设备上启用 USB 调试

  1. 单击查看 > 工具窗口 > 设备文件资源管理器或单击工具窗口栏中的设备文件资源管理器按钮以打开设备文件资源管理器。
  2. 从下拉列表中选择一个设备。
  3. 在文件资源管理器窗口中与设备内容交互。右键单击文件或目录以创建新文件或目录,将选定的文件或目录保存到您的计算机,上传、删除或同步。双击文件以在 Android Studio 中打开它。

    Android Studio 会将您以这种方式打开的文件保存在项目外部的临时目录中。如果您对使用设备文件资源管理器打开的文件进行了修改,并且希望将更改保存回设备,则必须手动将文件的修改版本上传到设备。

文件管理器

完整文档

于 2018-03-29T23:04:29.050 回答
6

您可以在下面使用这个 shell 脚本。它也能够从应用程序缓存中提取文件,不像该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
于 2014-07-09T16:16:03.873 回答
6

如果您使用的是 Mac 机器和三星手机,这是您必须做的(因为在三星上run-as 不起作用,在 Mac上zlib 也不起作用)

  1. 备份应用程序的数据目录 adb backup -f /Users/username/Desktop/data.ab com.example

  2. 您将被要求输入密码以在您的手机中加密,请勿输入任何密码。只需点击“备份我的数据”。请参阅如何进行备份?

  3. 成功备份后,您将data.ab在桌面中看到文件。现在我们需要将其转换为tar格式。

  4. 为此,请使用Android Backup Extractor下载| 源代码

  5. 下载它,你会看到abe.jar文件。将此添加到您的 PATH 变量中。

  6. 执行此操作以生成tar文件:java -jar abe.jar unpack /Users/username/Desktop/data.ab /Users/username/Desktop/data.tar

  7. 提取data.tar文件以访问所有文件

于 2018-01-03T12:02:30.653 回答
2

通过添加以下代码设置正确的权限后:

File myFile = ...;
myFile.setReadable(true, false); // readable, not only for the owner

adb pull按需要工作。

File.setReadable()

于 2013-07-02T12:37:14.847 回答
2

该答案基于我对其他答案的经验以及答案中的评论。我希望我可以帮助处于类似情况的人。

我正在通过终端在OSX上执行此操作。

以前,Vinicius Avellar 的回答对我很有用。我只是大部分时间都需要来自调试应用程序的设备中的数据库。

今天我有一个需要多个私有文件的用例。我最终得到了两种适用于这种情况的解决方案。

  1. 使用接受的答案以及 Somewhere 的 OSX 特定评论。创建备份并使用第 3 方解决方案 sourceforge.net/projects/adbextractor/files/?source=navbar解压缩成 tar。我将在这个答案的底部写更多关于我使用这个解决方案的经验。如果这是您要查找的内容,请向下滚动。

  2. 我解决了一个更快的解决方案。我创建了一个用于提取多个文件的脚本,类似于 Tamas 的答案。我能够这样做是因为我的应用程序是一个调试应用程序,并且我可以在我的设备上访问 run-as。如果您无权访问 run-as,则此方法在 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 上采取的步骤,以及遇到的问题:

首先,我排队备份(并设置密码来加密我的备份,我的设备需要它):

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

此时我收到一条错误消息。因为我的存档是加密的,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,并将它们放在那里。Vola 我能够使用 abe.jar 输入密码并解密为 tar 文件。

最后我刚刚跑了(再次运行上一个命令之后

tar xvf myAndroidBackup.tar

现在重要的是要注意,如果您可以只 run-as 和 cat,它会快得多。一,你只得到你想要的文件,而不是整个应用程序。第二,文件越多(对我来说是 + 加密),传输速度就越慢。因此,如果您在 OSX 上没有运行方式,那么知道这样做很重要,但脚本应该首先转到调试应用程序。

请注意,我今天才写它并测试了几次,所以请通知我任何错误!

于 2016-10-12T23:10:27.397 回答
2

Tamas 的回答类似,这里是 Mac OS X 的单行代码,用于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从模拟器中提取的
  • 不会踩踏您的会话变量
  • 您可以将整个块粘贴到 Terminal.app 中(或根据需要删除换行符)
于 2017-06-21T01:39:17.770 回答
1

从 Dave Thomas 脚本开始,我已经能够编写自己的解决方案来克服 2 个问题:

  1. 我的备份只包含清单文件
  2. 戴夫·托马斯(Dave Thomas)获得的二进制文件无法读取

这是我的脚本,它将应用程序数据复制到 sdcard 然后拉取它

#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
于 2017-03-05T11:53:58.557 回答
1

你可以做:

adb pull /storage/emulated/0/Android/data//

于 2018-03-27T08:43:38.590 回答
0

使用 apk 备份游戏数据。牛轧糖一加 2。

**adb backup "-apk com.nekki.shadowfight" -f "c:\myapk\samsung2.ab"**
于 2017-04-27T05:57:31.823 回答
0

这是否意味着可以将目录从 world:--x chmod 到 world:rx 足够长的时间以能够获取文件?

对,就是这样。奇怪的是,您还需要文件来x设置位。(至少在 Android 2.3 上)

chmod 755一直在复制文件(但如果您打算继续使用该设备,则应在之后恢复权限)。

于 2017-11-10T09:16:14.530 回答