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

embedded/2024/9/25 11:52:30/

文章目录

  • 概述
  • 一、准备工作
    • 1.1 安装 ADB
    • 安装 ADB:
    • 1.2 获取设备上的应用包名
    • 1.3 使用 ADB 导出 APK 文件
  • 二、提取桌面图标流程
    • 2.1 反编译 APK 文件
    • 2.2 解析 AndroidManifest.xml
    • 2.3 搜索图标资源文件
  • 三、 编写 Python 自动化工具
    • 3.1 代码结构
    • 3.2 运行脚本
  • 四、错误处理与优化
  • 五、总结


概述

在 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 属性可以找到对应图标:

<applicationandroid: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 反编译、图标解析、文件查找和图标导出。

python">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 Noneexcept 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 图标的开发者有所帮助。


http://www.ppmy.cn/embedded/116604.html

相关文章

架构面试题

架构基础 如何理解架构的演进&#xff1f; 架构的演进指的是随着技术、业务和需求的不断发展&#xff0c;架构在设计和实施上的变化和进化过程。这包括从单体应用向微服务架构的过渡、从传统的服务器部署向云原生架构的转变&#xff0c;以及在数据处理、安全性和性能优化等方…

MyBatis 缓存机制

MyBatis 缓存机制详解 MyBatis 提供了一种内置的缓存机制&#xff0c;用来提高数据查询的效率。通过缓存&#xff0c;MyBatis 可以减少对数据库的访问&#xff0c;提升系统性能。MyBatis 缓存分为 一级缓存&#xff08;Local Cache&#xff09; 和 二级缓存&#xff08;Global…

基于单片机的精确电压表DA-AD转换

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DAC0832和ADC0832检测电压&#xff0c;0到8.5V&#xff0c;设计复位电路 LED管显示实际稳压值&#xff0c;初始电压0 二、硬件资源 基于KEIL5编写C代码&#xff0c…

Mac 命令行常用操作笔记

1. 启用和禁用 Wi-Fi 打开 Wi-Fi&#xff1a; sudo networksetup -setairportpower "Wi-Fi" on 关闭 Wi-Fi&#xff1a; sudo networksetup -setairportpower "Wi-Fi" off 2. 搜索并连接 Wi-Fi 切换到 airport 工具目录&#xff1a; cd /System/Librar…

PAT甲级-1083 List Grades

题目 题目大意 学生有姓名&#xff0c;编号和分数&#xff0c;给定分数区间&#xff0c;输出在这个区间内的人名和编号。输出顺序按照分数从高到低&#xff0c;没有重复的分数。 思路 非常简单的结构体排序题&#xff0c;定义一个结构体&#xff0c;按照题目条件sort就可以了…

从 Tesla 的 TTPoE 看资源和算法

特斯拉的 ttpoe 出来有一段时间了&#xff0c;不出所料网上一如既往的一堆 pr 文&#xff0c;大多转译自 演讲 ppt 和 Replacing TCP for Low Latency Applications&#xff0c;看了不下 20 篇中文介绍&#xff0c;基本都是上面这篇文章里的内容&#xff0c;车轱辘话颠来倒去。…

MATLAB智能优化算法-学习笔记(3)——大规模邻域搜索算法求解旅行商问题【过程+代码】

一、问题描述 旅行商问题(TSP, Traveling Salesman Problem)是组合优化中的经典问题之一。给定一组城市和每对城市之间的距离,要求找到一条最短的路径,使旅行商从某个城市出发,访问每个城市一次并最终回到出发点。TSP问题广泛应用于物流配送、工厂调度、芯片制造等领域。…

mac输入法 cpu占用,解决mac使用输入法出现卡顿延迟

1、介绍 网上有各种方法&#xff0c;例如有touchbar的macbook关闭输入建议&#xff1b;定时重启“简体中文输入法”进程&#xff1b;关闭“显示器具有单独的空间” 这些方法网上都能看到&#xff0c;有些人说能解决&#xff0c;有些人说还是卡&#xff0c;我试过了问题依然存在…