自学内容网 自学内容网

如何批量获取安卓设备上所有应用的桌面图标


概述

在 Android 设备上,应用程序的桌面图标通常存储在应用的 APK 文件中。我们可以通过反编译 APK 文件并解析 AndroidManifest.xml 文件,找到桌面图标的路径,并批量提取出这些图标。本文将详细介绍如何编写 Python 工具,结合 ADB、Apktool 等工具,实现批量获取安卓设备所有应用的桌面图标。


一、准备工作

1.1 安装 ADB

ADB(Android Debug Bridge)是与安卓设备进行交互的重要工具。首先需要确保你的电脑已经安装 ADB,并且设备开启了 USB 调试模式。

安装 ADB:

macOS:

brew install android-platform-tools

Windows:
下载ADB工具

1.2 获取设备上的应用包名

我们可以通过 ADB 工具获取 Android 设备上所有已安装应用的包名:

adb shell pm list packages

输出类似如下内容:

package:com.sina.weibo
package:com.tencent.mm
package:com.android.chrome

包名表示设备上的每一个应用,接下来我们将通过这些包名批量获取对应的 APK 文件。

1.3 使用 ADB 导出 APK 文件

通过以下命令可以导出每个应用的 APK 文件:

adb shell pm path <package_name>
adb pull <APK 路径> <本地存储路径>

例如:

adb shell pm path com.sina.weibo
adb pull /data/app/com.sina.weibo/base.apk ~/Downloads/apkList/com.sina.weibo.apk

将 APK 文件存储到 apkList 目录中。

二、提取桌面图标流程

2.1 反编译 APK 文件

为了解析 APK 文件的资源,我们需要使用 Apktool 进行反编译。

安装 Apktool:

macOS:

brew install apktool

反编译 APK:

apktool d <APK 文件路径> -o <输出目录>

例如:

apktool d ~/Downloads/apkList/com.sina.weibo.apk -o ~/Downloads/apkList/com.sina.weibo_decompiled

这样就可以得到应用的所有资源文件和 XML 文件。

2.2 解析 AndroidManifest.xml

每个应用的 AndroidManifest.xml 文件中会包含应用的图标路径,通过 android:icon 属性可以找到对应图标:

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">
</application>

我们提取 android:icon 属性中的值,并通过该值定位到 res/drawable 或 res/mipmap 文件夹中的图标资源。

2.3 搜索图标资源文件

APK 文件的资源文件一般会存放在 res 文件夹下,分为 drawable 和 mipmap 两大类,根据设备的分辨率还会有 hdpi、xxhdpi 等不同目录。我们可以根据 AndroidManifest.xml 提取到的图标名,在 res 目录中搜索对应的图片文件。

三、 编写 Python 自动化工具

为了简化这一流程,我们编写一个 Python 工具,批量提取所有应用的桌面图标。

3.1 代码结构

我们将代码分为几步,分别进行 APK 反编译、图标解析、文件查找和图标导出。

import os
import shutil
import xml.etree.ElementTree as ET

# 定义 APK 目录和目标图标目录
apk_dir = "/Users/zhengkewen/Downloads/apkList"
icon_output_dir = "/Users/zhengkewen/Downloads/apkList/apkGetIcon"

# 创建目标图标目录
if not os.path.exists(icon_output_dir):
    os.makedirs(icon_output_dir)

# 提取 AndroidManifest.xml 中的 icon 值
def extract_icon_value(manifest_path):
    try:
        tree = ET.parse(manifest_path)
        root = tree.getroot()
        namespace = {'android': 'http://schemas.android.com/apk/res/android'}
        icon_value = root.attrib.get('{http://schemas.android.com/apk/res/android}icon')
        if icon_value:
            return icon_value.split('/')[-1]
        return None
    except Exception as e:
        print(f"Error parsing {manifest_path}: {e}")
        return None

# 搜索图标文件(查找 res 目录)
def find_icon_file(res_dir, icon_name):
    potential_folders = ['drawable', 'mipmap']
    for root, dirs, files in os.walk(res_dir):
        if any(folder in root for folder in potential_folders):
            for file in files:
                if icon_name in file:
                    return os.path.join(root, file)
    return None

# 批量处理 APK
def batch_process(apk_dir, icon_output_dir):
    failed_packages = []
    for apk_folder in os.listdir(apk_dir):
        apk_path = os.path.join(apk_dir, apk_folder)
        if os.path.isdir(apk_path):
            manifest_path = os.path.join(apk_path, "AndroidManifest.xml")
            if os.path.exists(manifest_path):
                icon_name = extract_icon_value(manifest_path)
                if icon_name:
                    res_dir = os.path.join(apk_path, "res")
                    icon_file = find_icon_file(res_dir, icon_name)
                    if icon_file:
                        output_dir = os.path.join(icon_output_dir, apk_folder)
                        if not os.path.exists(output_dir):
                            os.makedirs(output_dir)
                        try:
                            shutil.copy(icon_file, output_dir)
                            print(f"Icon for {apk_folder} copied to {output_dir}")
                        except Exception as e:
                            print(f"Failed to copy icon for {apk_folder}: {e}")
                            failed_packages.append(apk_folder)
                    else:
                        print(f"Icon file not found for {apk_folder}")
                        failed_packages.append(apk_folder)
                else:
                    print(f"No android:icon property found in manifest for {apk_folder}")
                    failed_packages.append(apk_folder)
            else:
                print(f"Manifest not found for {apk_folder}")
                failed_packages.append(apk_folder)
    
    # 记录失败的包
    if failed_packages:
        with open(os.path.join(icon_output_dir, 'failed_packages.txt'), 'w') as f:
            for package in failed_packages:
                f.write(f"{package}\n")
        print(f"Failed packages written to: {os.path.join(icon_output_dir, 'failed_packages.txt')}")

# 运行批量处理
batch_process(apk_dir, icon_output_dir)

3.2 运行脚本

将上述脚本保存为 find_icons.py,并执行:

python3 find_icons.py

四、错误处理与优化

1.没有 android:icon 的情况:部分应用可能没有定义 android:icon,我们增加了判断逻辑,如果没有这个属性,则记录到失败的包名列表中。
2.图标文件不存在的情况:对于提取出的图标名称,我们通过全局搜索 drawable 和 mipmap 目录进行查找,确保找到图标文件。
3.自动创建输出目录:如果没有目标目录,脚本会自动创建。
4.失败包名记录:将处理失败的包名记录到 failed_packages.txt 文件中,便于后续分析。

五、总结

通过这篇文章,我们实现了一个完整的工具,能够批量获取安卓设备上所有应用的桌面图标。文章从基础准备、ADB 使用、APK 反编译、资源解析到 Python 自动化工具编写进行了全面讲解。希望对想要批量处理 APK 图标的开发者有所帮助。


原文地址:https://blog.csdn.net/qq_40791475/article/details/142482057

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!