如何从 Android 设备获取 apk 文件?

Posted

技术标签:

【中文标题】如何从 Android 设备获取 apk 文件?【英文标题】:How do I get an apk file from an Android device? 【发布时间】:2011-05-01 06:48:24 【问题描述】:

如何从安卓设备获取apk文件?或者如何将 apk 文件从设备传输到系统?

【问题讨论】:

你能把接受的答案改成这个吗? ***.com/a/18003462/238753 投票数超过 10 倍,超级简单 【参考方案1】:

这些建议都不适合我,因为 android 会在包名称后附加一个序列号以生成最终的 APK 文件名。在更新的 Android 版本(Oreo 和 Pie)上,附加了一个不可预测的随机字符串。以下命令序列在 非 root 设备上对我有用:

1) 确定应用的包名,例如“com.example.someapp”。跳过这一步如果 你已经知道包名了。

adb shell pm list packages

查看软件包名称列表,并尝试在相关应用和软件包名称之间找到匹配项。这通常很容易,但请注意,包名称可能与应用名称完全无关。如果您无法从软件包名称列表中识别该应用程序,请尝试使用浏览器在 Google Play 中查找该应用程序。 Google Play 中应用的 URL 包含包名称。

2) 获取所需包的 APK 文件的完整路径名。

adb shell pm path com.example.someapp

输出将类似于package:/data/app/com.example.someapp-2.apk包:/data/app/com.example.someapp-nfFSVxn_CTafgra3Fr_rXQ==/base.apk

3) 使用步骤 2 中的完整路径名,将 APK 文件从 Android 设备拉到开发框。

adb pull /data/app/com.example.someapp-2.apk path/to/desired/destination

【讨论】:

这是最好的答案,无需破坏设备!非常感谢 这适用于我所有的 Android 设备,应该是公认的答案。 pm list packages 支持-f 标志,它为您列出了.apk 的位置,例如package:/data/app/com.google.android.apps.maps-1.apk=com.google.android.apps.maps。内置的 pm 帮助是无用的,但是 pm 也可以过滤包的类型,更多信息请参见developer.android.com/studio/command-line/adb.html#pm。编辑:刚刚注意到下面的答案是这样说的,但这个答案并不像这个答案那么受欢迎。 对我不起作用。我收到以下错误:adb: error: remote object '/data/app/path.of.the.app-2/base.apk' does not exist。如果我用文件浏览器浏览这些文件夹,这些文件夹是空的。 我遇到了与@Bevor 类似的问题,在拉取时,我得到了apk“不存在”的错误。我通过使用adb shell 修复它,然后使用cp PathToApk /sdcard/ 然后从 sdcard 复制。【参考方案2】:

使用adb。使用 adb pull 您可以将文件从您的设备复制到您的系统,当设备通过 USB 连接时。

当然,您还需要正确的权限才能访问您的文件所在的目录。如果没有,您需要先root设备。


如果您发现许多 APK 被命名为“base.apk”,您也可以使用这一行命令将所有 APK 从您可以访问的手机中提取出来,同时将任何“base.apk”名称重命名为包名称.这也修复了 APK 路径在名称后带有看似随机字符的目录未找到问题:

for i in $(adb shell pm list packages | awk -F':' 'print $2'); do 
  adb pull "$(adb shell pm path $i | awk -F':' 'print $2')"
  mv base.apk $i.apk &> /dev/null 
done

如果您收到“adb: error: failed to stat remote object”,则表明您没有所需的权限。我在非 root 的 Moto Z2 上运行此程序,并且能够下载我没有卸载的所有 APK(见下文),除了 youtube。

adb shell pm uninstall --user 0 com.android.cellbroadcastreceiver   <--- kills presidential alert app!

(查看用户运行 adb shell pm list users) 这是一种删除/卸载(不是从手机中删除/卸载)的方法可以通过 grepping for "ccc" 找到)

【讨论】:

感谢 Maurits Rijk。请帮助我。我想将 iTwips.apk 文件从设备复制到系统。我正在使用以下命令。这是正确的吗 ?我收到错误“Android2.2Froyo/sdcard/iTwips.apk”不退出... /Users/bbb/Android/android-sdk-mac_86/tools/adb pull Android2.2Froyo/sdcard/iTwips.apk /Users/bbb谢谢提前....... 在我的设备 (Android 2.1) 上,命令将是“adb pull /sdcard/test.jpg”将 test.jpg 从我的 sd 卡复制到当前目录。请首先使用“adb shell”找到您的 iTwips.apk 文件。这会在你的设备上启动一个 shell,你可以使用标准的 Unix 命令,如 ls 和 cd 来浏览你的目录。 @Finder @Maurits Rijk 实际上,您不必为了拉取 apk 而对设备进行 root。只要您知道该 apk 的完整路径。如果安装了apk,首先通过adb shell pm list packages查看包名找到完整路径,完整路径adb shell pm path your.package.name然后在你的电脑上,你可以简单地adb pull /full/path/to/your.apk 有关说明,请参阅 Yojimbo 的回答。 值得注意的是,如果某些APK具有相同的名称,这将覆盖它们,因此您确实需要执行yojimbo指定的命令。【参考方案3】:

不需要root:

此代码将获取带有名称的 3rd 方包路径,以便您轻松识别您的 APK

adb shell pm list packages -f -3

输出将是

包:/data/app/XX.XX.XX.apk=YY.YY.YY

现在使用以下代码拉取该包:

adb pull /data/app/XX.XX.XX.apk

如果你在C:&gt;\ 中执行以上cmd,那么你会在那里找到那个包。

【讨论】:

这是一个很棒的答案!非常感谢:) 由于某种原因,我在我的 /data/app/ 目录中找不到 APK。那里总是有一个子目录。 系统应用使用-f -s而不是-f -3 如果你有很多 apk,如果你知道包名中的任何单词,grep 可以帮助缩小第一个命令的输出:adb shell pm list packages -f | grep &lt;word from package name&gt;【参考方案4】:

我已经看到了很多解决这个问题的方法,要么你必须root你的手机,要么你必须安装一个应用程序。然后经过多次谷歌搜索,我得到了这个 非 root/root 手机的解决方案。

列出您目前获得的应用程序。

adb shell pm list packages

然后你可以选择一个应用程序,例如 twitter

adb backup -apk com.twitter.android

重要的是不要设置密码来加密备份

这将创建一个名为 backup.ap 的文件,但您仍然无法打开它。为此,您必须再次提取它,但使用 dd 命令。

dd if=backup.ab bs=24 skip=1 | openssl zlib -d > backup.tar

在此之后,您所要做的就是提取 tar 内容,然后就完成了。

希望对你们有用

【讨论】:

来自blog.shvetsov.com/2013/02/…,如果您的openssl 没有zlib,这可能有效:dd if=backup.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" |焦油 -xvf - 这对我有用,而不是接受答案中的程序。今天,当我需要我的一个旧应用程序的 APK 时,它真的对我很有帮助,但我只能通过手机获得它。 如果您的 openssl 缺少 zlib 支持,这里有更多信息:***.com/questions/29830981/… 如果在@kodi 的评论中得到UnicodeDecodeError: 'utf-8' codec can't decode byte 0xda in position 1: invalid continuation byte,则在命令中将python 替换为python2【参考方案5】:

从设备下载 APK 到桌面的步骤

A) 确保您正在运行(模拟器/真实设备)。要检查使用此命令

adb devices

B) 选择您设备中安装的所有可用软件包列表。您可以使用 grep 命令选择您要下载的特定包。

adb shell pm list packages
adb shell pm list packages -f -3

输出(可用包列表)

package:/data/app/com.example.mytestapplication-sOzKi5USzfbYLPNDmaaK6g==/base.apk=com.example.mytestapplication
package:/data/app/com.example.myapplication-nd1I4FGnTZnQ9PyRbPDHhw==/base.apk=com.example.myapplication

C) 从上面的链接复制包(您喜欢下载的)。在我们的案例中,我选择了这个 (com.example.myapplication) 包

Syntax : adb shell pm path [your_package_name]
Command: adb shell pm path com.example.myapplication

输出

package:/data/app/com.example.myapplication-nd1I4FGnTZnQ9PyRbPDHhw==/base.apk

D) 最后,从您的(模拟器/真实设备)下载 APK

Syntax : adb pull /data/app/[your_package_name]-1/base.apk  [your_destination_path]
Command: adb pull /data/app/com.example.myapplication-3j4CVk0Tb2gysElgjz5O6A==/base.apk /Users/$(whoami)/Documents/your_apk.apk

示例:尝试在本地计算机 (Mac) 中提取此 CertInstaller.apk 文件

adb pull /system/app/CertInstaller/CertInstaller.apk /Users/$(whoami)/Documents/APK/download_apk/

E)在本地目录中确认

ls -la /Users/$(whoami)/Documents/

【讨论】:

目标是提取单个 apk,但在第 4 步中,您提取了两个额外的文件,没有解释或以前的参考。 我通过澄清每一步来修改这篇文章。希望这个修改会有所帮助并且易于理解。 另外,步骤 C 是做什么用的?您已经从 pm list packages 获得了包路径...只有在您只知道 apk 标识符(但不知道包路径)时才需要它。【参考方案6】:
C:\Users\xyz>adb shell pm list packages -f | findstr whatsapp
package:/data/app/com.whatsapp-1/base.apk=com.whatsapp

C:\Users\xyz>adb pull /data/app/com.whatsapp-1/base.apk Desktop
/data/app/com.whatsapp-1/base.apk: 1 f.... 13.8 MB/s (32803925 bytes in 
2.269s)

【讨论】:

这是我认为最直接的方式。谢谢! 使用 linux 或 mac 而不是 findstr 的人使用 grep【参考方案7】:

一个适用于所有 Android 版本的衬垫:

adb shell 'cat `pm path com.example.name | cut -d':' -f2`' > app.apk

【讨论】:

@AlexP。你想通过上面的链接告诉你什么?【参考方案8】:

在unix系统上,你可以试试这个功能:

function android_pull_apk() 
    if [ -z "$1" ]; then
        echo "You must pass a package to this function!"
        echo "Ex.: android_pull_apk \"com.android.contacts\""
        return 1
    fi

    if [ -z "$(adb shell pm list packages | grep $1)" ]; then
        echo "You are typed a invalid package!"
        return 1
    fi

    apk_path="`adb shell pm path $1 | sed -e 's/package://g' | tr '\n' ' ' | tr -d '[:space:]'`"
    apk_name="`adb shell basename $apk_path | tr '\n' ' ' | tr -d '[:space:]'`"

    destination="$HOME/Documents/Android/APKs"
    mkdir -p "$destination"

    adb pull $apk_path $destination
    echo -e "\nAPK saved in \"$destination/$apk_name\""

示例android_pull_apk com.android.contacts 注意:识别包:adb shell pm list packages

【讨论】:

【参考方案9】:

完成@Yojimbo 的回答,这就是我所做的(仅限Linux/Mac,不能在Windows 上开箱即用......也许在git 的bash shell 中):

for i in $(adb shell pm list packages -f -3 | cut -d= -f 1 | cut -d ":" -f 2); do adb pull $i; done

这是丑陋的 bash,但有效 :)

编辑: 它不再适用于 AndroidM:所有文件都在另一个目录下命名为“base.apk”。修复应该是“微不足道的”。

【讨论】:

【参考方案10】:

试试这个 bash 命令来备份你的所有应用:

for package in $(adb shell pm list packages -3 | tr -d '\r' | sed 's/package://g'); do apk=$(adb shell pm path $package | tr -d '\r' | sed 's/package://g'); echo "Pulling $apk"; adb pull -p $apk "$package".apk; done

此命令源自Firelord's script。我刚刚将所有 apk 重命名为它们的包名,以解决 elcuco's script 的问题,即相同的 base.apk 文件在 Android 6.0“Marshmallow”及更高版本上被覆盖。

请注意,此命令仅备份 3rd 方应用程序,因为我看不到备份内置应用程序的意义。但如果您也想备份系统应用,只需省略 -3 选项即可。

【讨论】:

@Pieter 不太可能。这在拆分 APK 很常见之前进行了测试。该脚本所做的是拉取 base.apk 并将其重命名为应用程序的包名称。 @Pieter 您需要修改脚本,从该目录中提取所有 apk 并按顺序重命名它们,或者将它们复制到一个目录中。 如果您只是 adb install 该应用程序的所有 APK 单独恢复它,它是否有效? 根据***.com/questions/55212788/… ,您必须使用新命令'adb install-multiple apk1 apk2 ...'【参考方案11】:

如上所说,可以通过 adb 中的 pull 命令获取 apk。

既然您在谈论已安装的应用程序,请继续查看您的 Android 文件系统的 /data/app 目录。您会在那里找到 APK。

然后使用 adb 命令 - adb pull /data/data/appname.apk

【讨论】:

【参考方案12】:
    在手机上打开要从中提取 apk 的应用。

    获取当前打开的应用:

    adb shell dumpsys activity activities | grep mFocusedActivity
    

    获取包名的路径

    adb shell pm path <packagename.apk>
    

4.复制你得到的路径到sdcard目录

    adb shell cp /data/app/<packagename.apk> /sdcard

5.拉取apk

    adb pull /sdcard/base.apk

编辑

如果第 2 步不起作用,请使用:

adb shell dumpsys window windows | grep mCurrentFocus

【讨论】:

【参考方案13】:

如果您知道(或者如果您可以“猜测”).apk 的路径(它似乎的格式为 /data/app/com.example.someapp-1,2,...apk 到 ,那么您可以从 @ 复制它987654324@ 也是如此。这甚至在我的非 root 库存 Android 手机上也有效。

只需使用终端仿真器应用程序(例如this one)并运行:

# step 1: confirm path
ls /data/app/com.example.someapp-1.apk
# if it doesn't show up, try -2, -3. Note that globbing (using *) doesn't work here.
# step 2: copy (make sure you adapt the path to match what you discovered above)
cp /data/app/com.example.someapp-1.apk /mnt/sdcard/

然后您可以将其从 SD 卡移动到您想要的任何位置(或将其附加到电子邮件等)。最后一点在技术上可能是可选的,但是当您尝试使用 .apk 文件做某事时,它会让您的生活更轻松。

【讨论】:

【参考方案14】:

此处概述的程序不适用于 Android 7 (Nougat) [可能还有 Android 6,但我无法验证]。您不能直接在 Nougat 下提取 .apk 文件(除非在 root 模式下,但这需要有 root 权限的手机)。但是,您可以使用 adb shell 将 .apk 复制到手机上的备用路径(例如 /sdcard/Download),然后您可以从备用路径执行 adb pull。

【讨论】:

接受的答案(包括来自@Isa A 评论的adb shell 命令)对我来说在Android 7.1.1 上运行良好,没有root。【参考方案15】:

对于从设备检索到的每个 apk 文件,所有这些答案都需要多个步骤。 1.确定包名,2.找到文件,3.下载。我构建了一个简单的apk_grabber python script 来为任何匹配给定正则表达式的应用程序执行此操作,然后将这些 apk 反编译为 jar 文件。

【讨论】:

【参考方案16】:

这是你的做法:

在您的设备上下载并安装 APK Extractor。它是免费的,并且兼容几乎所有的 Android 设备。另一个优点是它甚至不需要 root 或任何东西来工作。 安装后,启动它。在那里,您将看到设备中的应用程序列表,其中包括您稍后安装的应用程序以及系统应用程序。长按您要提取的任何应用程序(您可以一次选择多个或所有应用程序),然后单击您在顶部看到的提取选项。您还可以选择通过蓝牙或消息共享。 大功告成,你会看到解压出来的应用是AppName_AppPackage_AppVersionName_AppVersionCode.apk,默认保存在/sdcard/ExtractedApks/路径下。

how to extract apk files in android的详细说明,请访问:http://appslova.com/how-to-extract-apk-files-in-android/

【讨论】:

【参考方案17】:

我收到了does not exist error

这是我的工作方式

adb shell pm list packages -f | findstr zalo
package:/data/app/com.zing.zalo-1/base.apk=com.zing.zalo

adb shell
mido:/ $ cp /data/app/com.zing.zalo-1/base.apk /sdcard/zalo.apk
mido:/ $ exit


adb pull /sdcard/zalo.apk Desktop

/sdcard/zalo.apk: 1 file pulled. 7.7 MB/s (41895394 bytes in 5.200s)

【讨论】:

这对我在 Android 7.0 华为设备上有所帮助。【参考方案18】:

无需 Root 且无需 ADB 工具的方法。 从 Play 商店安装 MyAppSharer 应用程序。

【讨论】:

“Jones Chi”的这款应用(截至 2020 年 12 月)拥有 1000 万次以上的下载量,147K 条评论,平均评分为 4.6,最后一次更新是在 2017 年 11 月 13 日,以防万一想知道。【参考方案19】:

我真的很喜欢所有这些答案。 大多数用于导出和重命名它们的脚本都是用 Bash 编写的。 我制作了一个小的 Perl 脚本,它的作用相同(它应该在 Windows 和 linux 的 Perl 中都可以工作,只在 Ubuntu 上测试过)。

这使用亚行:https://developer.android.com/studio/command-line/adb

下载-apk.pl

#!/usr/bin/perl -w
# Automatically export all available installed APK's using adb
use strict;
print "Connect your device...\n";
system("adb", "wait-for-device");
open(my $OUT, '-|', 'adb', 'shell', 'pm', 'list', 'package', '-f');
my $count = 0;
while(my $line = <$OUT>) 
        $line =~ s/^\s*|\s*$//g;
        my ($type, $path, $package) = $line =~ /^(.*?):(.*)=(.*)$/ ? ($1,$2,$3) : die('invalid line: '.$line);
        my $category = $path =~ /^\/(.*?)\// ? $1 : 'unknown';
        my $baseFile = $path =~ /\/([^\/]*)$/ ? $1 : die('Unknown basefile in path: '.$path);
        my $targetFile = "$category-$package.apk";
        print "$type $category $path $package $baseFile >> $targetFile\n";
        system("adb", "pull", $path);
        rename $baseFile, $targetFile;

    确保 adb(.exe) 位于您的路径或同一目录中 连接手机 运行 download-apk.pl

输出类似于:

# ./download-apk.pl
Connect your device...
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
package system /system/app/YouTube/YouTube.apk com.google.android.youtube YouTube.apk >> system-com.google.android.youtube.apk
5054 KB/s (11149871 bytes in 2.154s)
package data /data/app/com.ghostsq.commander-1/base.apk com.ghostsq.commander base.apk >> data-com.ghostsq.commander.apk
3834 KB/s (1091570 bytes in 0.278s)
package data /data/app/de.blinkt.open***-2/base.apk de.blinkt.open*** base.apk >> data-de.blinkt.open***.apk
5608 KB/s (16739178 bytes in 2.914s)
etc.

【讨论】:

【参考方案20】:

我没有使用代码从手机中提取 .apk 文件,但我一直在使用软件从手机中提取 .apk 文件,我使用的软件在下面带有 google play 链接:

    ES File Explorer File Manager ASTRO Cloud & File Manager 3.Software Data Cable

希望对你有帮助。

【讨论】:

我使用了 ES 文件资源管理器。我没有扎根。我只是去了工具-> 应用程序管理器并长按我想要 APK 的应用程序。这选择了应用程序(并允许我选择其他应用程序)。我认为按下共享按钮并能够将 APK 发送给我自己(使用 Push Bullet,但对你有用)。 如果你没有腐烂那么你可以尝试应用备份和恢复play.google.com/store/apps/details?id=mobi.infolife.appbackup【参考方案21】:

想要非常、非常舒适的 1 分钟解决方案吗?

只有你这个应用程序https://play.google.com/store/apps/details?id=com.cvinfo.filemanager(来自 google play 的智能文件管理器)。

点按“应用程序”,选择一个并点按“备份”。它将最终出现在您的文件系统中 app_backup 文件夹中;)

【讨论】:

【参考方案22】:

另一个 bash 脚本(即适用于大多数基于 unix 的系统)。基于the answer by Pedro Rodrigues,但更易于使用。

对 Pedro 版本的改进:

    原来的方法在 Android 7 上对我不起作用:adb pull 一直抱怨 no such file or directoryadb shell 可以访问该文件。因此我使用了不同的方法,使用临时文件。 当不带参数启动时,我的脚本只会列出所有可用的包。当提供部分包名时,它会尝试猜测完整的包名。如果有几个可能的扩展,它会报错。 我没有硬编码目标路径;而是将 APK 保存到当前工作目录。

将此保存到可执行文件中:

#!/bin/bash
# Obtain APK file for given package from the device connected over ADB

if [ -z "$1" ]; then
    echo "Available packages: "
    adb shell pm list packages | sed 's/^package://'
    echo "You must pass a package to this function!"
    echo "Ex.: android_pull_apk \"com.android.contacts\""
    exit 1
fi

fullname=$(adb shell pm list packages | sed 's/^package://' | grep $1)
if [ -z "$fullname" ]; then
    echo "Could not find package matching $1"
    exit 1
fi
if [ $(echo "$fullname" | wc -l) -ne 1 ]; then
    echo "Too many packages matched:"
    echo "$fullname"
    exit 1
fi
echo "Will fetch APK for package $fullname"

apk_path="`adb shell pm path $fullname | sed -e 's/package://g' | tr '\n' ' ' | tr -d '[:space:]'`"
apk_name="`basename $apk_path | tr '\n' ' ' | tr -d '[:space:]'`"

destination="$fullname.apk"

tmp=$(mktemp --dry-run --tmpdir=/sdcard --suffix=.apk)
adb shell cp "$apk_path" "$tmp"
adb pull "$tmp" "$destination"
adb shell rm "$tmp"

[ $? -eq 0 ] && echo -e "\nAPK saved in \"$destination\""

【讨论】:

【参考方案23】:

最简单的一个是: 在手机上安装“ShareIt”应用程序。 现在在 PC 或其他手机上安装 shareIt 应用程序。 现在从安装了应用程序的手机上,打开 ShareIt 并发送。 在其他手机或 PC 上,打开 ShareIt 并接收。

【讨论】:

【参考方案24】:

这将有助于寻找非技术性答案的人

这很简单hack

从 google play store 下载应用程序App Share/Send Pro。选择您要发送的应用程序和方法发送应用程序。

我通常使用蓝牙将应用程序发送到我的电脑或其他手机。

【讨论】:

不好用

以上是关于如何从 Android 设备获取 apk 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 .apk 文件详细信息(如:名称、id、vercode ..etc)存储在 android 设备的外部存储中

如何从 Android 中的 apk 文件中获取源代码? [复制]

Android apk 系统签名

Android ADB 你想要的都在这

android adb 如何检测手机中某个软件的版本?

Android APK如何签名