前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >提取APK图标脚本

提取APK图标脚本

作者头像
KAAAsS
发布2022-01-14 16:53:03
9640
发布2022-01-14 16:53:03
举报
文章被收录于专栏:KAAAsS's Blog

最近同学换手机,看不爽3×0那个ui,打算自己做主题,找我提取Flyme自带的图标。嘛,虽然不是啥复杂的东西,手动也能解决,不过一旦图标多起来就受不了了。于是我就写了个Python脚本批量处理。

代码语言:javascript
复制
import os
import re
import shutil
import xml.dom.minidom
from xml.dom.minidom import parse

apk_path = 'apks/'
icons_path = 'icons/'


def decomp(apk_name):
    os.system("apktool d %s%s" % (apk_path, apk_name))


def search_for_icon(base_path, icon_str):
    if icon_str is None or icon_str == "":
        return None
    matches = re.match(r'@(.*)\/(.*)', icon_str)
    path_name = matches.group(1)
    icon_name = matches.group(2)
    ls = os.listdir(base_path)
    ls.reverse()
    for p in ls:
        if p.startswith(path_name):
            path = os.path.join(base_path, p, icon_name+".png")
            if os.path.exists(path):
                return path
    return None


def parse_for_icon(apk_name):
    base_path = apk_name[:-4]
    dom = parse(base_path+"/AndroidManifest.xml")
    collection = dom.documentElement
    tag = collection.getElementsByTagName("application")[0]
    # Something like: @mipmap/ic_launcher
    icon_android_path = tag.getAttribute("android:icon")
    return search_for_icon("%s/res/" % base_path, icon_android_path)


def del_file(path):
    list = os.listdir(path)
    for l in list:
        c_path = os.path.join(path, l)
        if os.path.isdir(c_path):
            del_file(c_path)
        else:
            os.remove(c_path)
    os.rmdir(path)


def move_apk_out(path):
    ls = os.listdir(path)
    for i in ls:
        c_path = os.path.join(path, i)
        if os.path.isdir(c_path):
            move_apk_out(c_path)
        elif i[-3:] == 'apk':
            shutil.move(c_path, apk_path+i)


if __name__ == '__main__':
    move_apk_out(apk_path)
    apk_list = []
    list = os.listdir(apk_path)
    for l in list:
        path = os.path.join(apk_path, l)
        if os.path.isfile(path) and l[-3:] == 'apk':
            apk_list.append(l)
    print(apk_list)
    for apk in apk_list:
        print("Geting icon for: %s" % apk)
        decomp(apk)
        icon_path = parse_for_icon(apk)
        if icon_path is not None and os.path.exists(icon_path):
            shutil.move(icon_path, "%s%s.png" % (icons_path, apk[:-4]))
        else:
            print("Failed to get: " + apk)
        if os.path.exists(apk[:-4]):
            del_file(apk[:-4])

Gist地址

由于比较偷懒,用了直接apktool反编译这种很慢的方式。其实只用提取AndroidManifest.xml,解码之后获取图标就好,而apktool则会把资源全都解码并反编译smali码。还有,一个应用的图标一般都会配备多个尺寸,我的方法也很偷懒,就是选个最大的(倒序lsdir的结果23333)。不过竟然能跑,虽然慢是慢了一点,不过还是很方便的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档