如何从 Android 设备获取 apk 文件?或者我如何将apk文件从设备传输到系统?
24 回答
这些建议都不适合我,因为 Android 会在包名称后附加一个序列号以生成最终的 APK 文件名。在更新的 Android 版本(Oreo 和 Pie)上,附加了一个不可预测的随机字符串。以下命令序列在无根设备上对我有用:
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
或
package:/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
使用亚行。当设备通过 USB 连接时,您可以使用adb pull 将文件从设备复制到系统。
当然,您还需要正确的权限才能访问您的文件所在的目录。如果没有,您需要先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)这是一种删除/卸载的方法(不是从手机中删除,因为它会恢复出厂设置)几乎任何没有 root 的应用程序包括系统应用程序(提示更新手机的烦人更新应用程序是否可以通过 grepping for "ccc" 找到它)
不需要根:
此代码将获得带有名称的 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
如果你在 cmd 上面执行C:>\
,那么你会在那里找到那个包。
我已经看到很多解决这个问题的方法,要么你必须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 内容并完成。
希望它对你们有用
将 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/
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)
一种适用于所有 Android 版本的衬垫:
adb shell 'cat `pm path com.example.name | cut -d':' -f2`' > app.apk
在 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
完成@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”。应该是“微不足道的”来修复。
试试这个 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 的脚本。我刚刚将所有 apk 重命名为它们的包名称,以解决elcuco 脚本的问题,即同一base.apk
文件在 Android 6.0“Marshmallow”及更高版本上被覆盖。
请注意,此命令仅备份 3rd 方应用程序,因为我看不到备份内置应用程序的意义。但是,如果您也想备份系统应用程序,请忽略该-3
选项。
如上所述,您可以通过在 adb 中使用 pull 命令来获取 apk。
因为,您正在谈论已安装的应用程序,请继续查看 Android 文件系统的/data/app目录。您会在那里找到 APK。
然后使用 adb 命令 - adb pull /data/data/appname.apk
- 在手机上打开要从中提取 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
如果您知道(或者如果您可以“猜测”)路径.apk
(它似乎是to 的格式/data/app/com.example.someapp-{1,2,..}.apk
,那么您也可以从中复制它/data/app
。这甚至在我的非根目录下的 Android 手机上也有效。
只需使用终端仿真器应用程序(例如这个)并运行:
# 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
文件执行某些操作时,它会让您的生活变得更加轻松。
此处概述的程序不适用于 Android 7 (Nougat) [可能还有 Android 6,但我无法验证]。您不能直接在 Nougat 下提取 .apk 文件(除非在 root 模式下,但这需要有 root 权限的手机)。但是,您可以使用 adb shell 将 .apk 复制到手机上的备用路径(例如 /sdcard/Download),然后您可以从备用路径执行 adb pull。
对于从设备检索到的每个 apk 文件,所有这些答案都需要多个步骤。1.确定包名,2.找到文件,3.下载。我构建了一个简单的apk_grabber
python 脚本来为任何匹配给定正则表达式的应用程序执行此操作,然后将这些 apk 反编译为 jar 文件。
这是你如何做到的:
在您的设备中下载并安装 APK Extractor。它是免费的,并且兼容几乎所有的 Android 设备。另一个优点是它甚至不需要 root 或任何东西来工作。安装后,启动它。在那里,您将看到设备中的应用程序列表,其中包括您稍后安装的应用程序以及系统应用程序。长按您要提取的任何应用程序(您可以一次选择多个或所有应用程序),然后单击您在顶部看到的提取选项。您还可以选择通过蓝牙或消息共享。大功告成,您将看到提取的应用程序为 AppName_AppPackage_AppVersionName_AppVersionCode.apk,默认保存在路径 /sdcard/ExtractedApks/ 中。
有关如何在 android 中提取 apk 文件的详细说明,请访问:http ://appslova.com/how-to-extract-apk-files-in-android/
我有一个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)
无需 Root 且无需 ADB 工具的方法。从 Play 商店安装MyAppSharer应用程序。
我真的很喜欢所有这些答案。大多数用于导出和重命名它们的脚本都是用 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) 在您的路径或同一目录中
- 连接你的手机
- 运行下载-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.openvpn-2/base.apk de.blinkt.openvpn base.apk >> data-de.blinkt.openvpn.apk
5608 KB/s (16739178 bytes in 2.914s)
etc.
我没有使用代码从手机中提取 .apk 文件,但我一直在使用软件从手机中提取 .apk 文件,我使用的软件在下面带有 google play 链接:
希望对您有所帮助。
想要非常非常舒适的 1 分钟解决方案?
只有你这个应用程序https://play.google.com/store/apps/details?id=com.cvinfo.filemanager(来自 google play 的智能文件管理器)。
点击“应用程序”,选择一个并点击“备份”。它将最终出现在文件app_backup
夹中的文件系统上;)
最简单的一个是:在手机上安装“ShareIt”应用程序。现在在 PC 或其他手机上安装 shareIt 应用程序。现在从安装了应用程序的手机上,打开 ShareIt 并发送。在其他手机或 PC 上,打开 ShareIt 并接收。
另一个 bash 脚本(即适用于大多数基于 unix 的系统)。基于Pedro Rodrigues 的回答,但使用起来稍微容易一些。
对 Pedro 版本的改进:
- 原始方法在 Android 7 上对我不起作用:
adb pull
一直抱怨no such file or directory
whileadb 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\""
这将有助于寻找非技术性答案的人
这是简单的黑客
App Share/Send Pro
从 google play store下载应用程序。选择您要发送的应用程序和方法发送应用程序。
我通常使用蓝牙将应用程序发送到我的电脑或其他手机。