如何获取自己的Android应用程序的(私人)数据?

时间:2013-03-21 21:19:43

标签: android adb

尝试使用

提取单个文件
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

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

14 个答案:

答案 0 :(得分:86)

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 backup extractor从Android备份(.ab)文件中提取文件。

答案 1 :(得分:44)

我遇到了同样的问题,但解决了以下问题:

$ 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}

答案 2 :(得分:28)

这对我有用:

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

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

答案 3 :(得分:20)

在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

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

答案 4 :(得分:5)

您可以在下面使用此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

答案 5 :(得分:3)

如果您使用的是Mac计算机和三星手机,则必须执行此操作(自三星上的run-as doesn't work和Mac上的zlib doesn't work起)

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

  2. 系统会要求您输入密码以在手机中加密,不要输入任何密码。只需点击"备份我的数据"。请参阅How to take BackUp?

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

  4. 使用 Android备份提取程序Download | SourceCode

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

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

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

答案 6 :(得分:2)

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

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

以前Vinicius Avellar的回答对我很有帮助。我大多数时候只需要从调试应用程序中获取设备中的数据库。

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

  
      
  1. 使用已接受的答案以及Someone Somewhere的OSX特定评论。创建备份并使用第三方解决方案,   sourceforge.net/projects/adbextractor/files/?source=navbar打开包装   变成焦油。我将在本答案的底部写下更多关于我对此解决方案的体验。 向下滚动   这就是你要找的东西。

  2.   
  3. 我解决的更快的解决方案。我创建了一个脚本,用于提取类似于Tamas'回答。我能够做到   这样,因为我的应用程序是一个调试应用程序,我可以访问run-as   我的设备。如果您无权访问 - 因为此方法无法运行   适用于OSX。

  4.   

这是我的脚本,用于提取我将与您分享的多个私人文件,读者,也在研究这个令人敬畏的问题;):

#!/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文件的错误位置。它说正确的位置是< java-home> / lib / security 。我把它们放在那里然后仍然收到错误消息。所以我调查了我在Mac上使用Java 1.8的正确位置是:< java-home> / jre / lib / security 。我确保备份原始的政策罐,并把它们放在那里。 Vola我能够使用abe.jar输入密码并解密为tar文件。

最后,我刚刚运行(再次运行上一个命令后

tar xvf myAndroidBackup.tar

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

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

答案 7 :(得分:2)

较新版本的Android Studio包含设备文件资源管理器,我发现这是从我的开发Nexus 7下载文件的便捷GUI方法。

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

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

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

  4. file explorer

    Full Documentation

答案 8 :(得分:1)

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

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

adb pull按需运作。

请参阅File.setReadable()

答案 9 :(得分:1)

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

  1. 我的备份只包含清单文件
  2. 二进制文件与Dave Thomas一起获得
  3. 这是我的脚本,它将应用数据复制到SD卡,然后将其拉出

    <div ng-repeat="object in objects | custom_filter">
    </div>

答案 10 :(得分:1)

Tamas's answer类似,此处是Mac OS X的一行内容,用于从您的设备获取带有your.app.id的应用的所有文件,并将其保存到(在这种情况下){{1 }}:

~/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 )
  • 不会踩踏会话变量
  • 您可以将整个块粘贴到Terminal.app(或根据需要删除换行符)

答案 11 :(得分:0)

使用apk备份游戏数据。 Nougat Oneplus 2。

**adb backup "-apk com.nekki.shadowfight" -f "c:\myapk\samsung2.ab"**

答案 12 :(得分:0)

  

这是否意味着可以从世界中修改目录: - x到world:r-x足够长以便能够获取文件?

是的,确切地说。奇怪的是,您还需要将文件设置为x位。 (至少在Android 2.3上)

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

答案 13 :(得分:0)

你可以这样做:

  

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