java自动解析apk安装包内容信息
1.背景
项目需要根据用户提交的apk地址,自动的获取apk的相关信息,比如包名称、版本信息、Icon图、binary xml and manifest xml file、sign等,因此就搜索和研究了一下,接下来就提供几种方式来解决这个问题。
2.可行性方案
- 解压后读取AndroidManifest.xml,根据xml信息获取
- 官方sdk中提供的工具aapt
3 apk-parser工具包
pom.xml文件中增加依赖配置
<dependencies>
<dependency>
<groupId>net.dongliu</groupId>
<artifactId>apk-parser</artifactId>
<version>2.6.10</version>
</dependency>
</dependencies>
然后maven安装
public static void main(String[] args) {
// Press Opt+Enter with your caret at the highlighted text to see how
// IntelliJ IDEA suggests fixing it.
String apkUrl = "./2.apk";
try {
ApkFile apkFile = new ApkFile(apkUrl);
String manifestXml = apkFile.getManifestXml();
// System.out.println(manifestXml);
ApkMeta apkMeta = apkFile.getApkMeta();
// 获取包name
System.out.println(apkMeta.getPackageName());
// 获取app名称
System.out.println(apkMeta.getName());
// 获取版本信息
System.out.println(apkMeta.getVersionCode());
System.out.println(apkMeta.getVersionName());
// 获取全部icon
apkFile.getAllIcons();
// 能从iconFace.getData获取文件流
for (IconFace iconFace : apkFile.getAllIcons()) {
System.out.println(iconFace.getPath());
saveIcon("/Downloads/", iconFace);
}
} catch (java.io.IOException ex) {
System.out.println(ex.getMessage());
}
}
public static void saveIcon(String savePath, IconFace iconFace) throws IOException {
String iconPath = iconFace.getPath();
String iconName = iconPath.substring(iconPath.lastIndexOf("/") + 1);
File file = new File(savePath + iconName);
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(iconFace.getData());
fos.close();
}
com.xingye.app
星野
1350003
1.35.003
res/u3P.png
res/SDC.png
res/jyj.png
res/D21.png
res/CGK.png
res/EtS.png
4.aapt工具
#!/bin/bash
if [ ! -s "${1}" ];then
echo "apk file is not exist";
exit;
fi
cons=`aapt d badging $1 | grep -E "application-icon|application:" | sed -e 's/.*\(res\/\w\{1,\}\-\w\{1,\}\/\w\{1,\}\.png\).*/\1/' | uniq`;
# echo $icons;
for icon in $icons;do
echo $icon;
done
echo "-----apk name----";
name=`aapt d badging $1 | grep -E "application:" | sed -e "s/.*label='\(\w*\)'.*/\1/"`;
echo $name;
echo "-----apk versionCode----";
#获取apk versionCode
versionCode=`aapt d badging $1 | grep -E "package:" | sed -e "s/.*versionCode='\(\w\{1,\}\)'.*/\1/"`;
echo $versionCode;
echo "-----apk versionName----";
#获取apk versionName
versionName=`aapt d badging $1 | grep -E "package:" | sed -e "s/.*versionName='\(\S\{1,\}\)'.*/\1/"`;
echo $versionName;
echo "-----icon xml-----------";
iconXml=`aapt dump badging $1 | grep -E "application-icon|icon" | grep -oP "icon='([^']+)'" | cut -d"'" -f2`
echo "-----get backgroud and foreground-----------";
pic=`aapt dump xmltree $1 $iconXml | grep -oP "@0x[0-9a-zA-Z]+" | cut -d'@' -f2`
echo $pic
code=`aapt dump xmltree $1 $iconXml | grep -oP "@0x[0-9a-zA-Z]+" | cut -d'@' -f2 | tr '\n' '|' | awk -F "|" '{print $2}'`
echo $code
anchor=`aapt dump --values resources $1 | grep -iC4 $code `
echo $anchor
IFS='|' read -r -a array <<< "$anchor"
for element in "${array[@]}"; do
if [[ "$element" == *.png* ]]; then
echo `echo $element | cut -d' ' -f2`
fi
done
echo "-----unzip apk-----------";
out="./test/" #解压到当前目录下的test目录
unzip "$1" -d $out
#那么icon图的路径为 ./test/res/u3P.png
输出内容如下
-----apk name----
这是测试名称
-----apk versionCode----
1350003
-----apk versionName----
1.35.003
-----icon xml-----------
-----get backgroud and foreground-----------
0x7f0806ae 0x7f0f0001
0x7f0f0001
-----get icon-----------
“res/u3P.png”
“res/0yn.png”
“res/7cF.png”
“res/SDC.png”
“res/MbV.png”
“res/tfl.png”
“res/jyj.png”
“res/kbF.png”
“res/1Sy.png”
“res/D21.png”
“res/_eu.png”
“res/5QH.png”
“res/CGK.png”
“res/EtS.png”
“res/C9M.png”
分为mdpi、hdpi、xhdpi、xxhdpi,、xxxhdpi类型。其中
ic_launcher: 这是应用的主图标,用于应用抽屉(Launcher)和主屏幕。它代表了应用的主要视觉元素,因此通常需要具有较高的辨识度和设计感。
ic_launcher_foreground: 这个资源用于Android 8.0(API级别26)及以上版本的自适应图标。自适应图标可以根据不同设备的主题和用户设置动态改变形状。ic_launcher_foreground 通常包含图标的主要视觉元素,而背景则由系统提供,可以是圆形、方形或其他形状。
ic_launcher_round: 这也是用于自适应图标的资源,专门用于圆形图标。在支持自适应图标的设备上,系统可能会选择使用 ic_launcher_round 而不是 ic_launcher 或 ic_launcher_foreground,以适应设备图标的圆角设计。
这样就可以获取icon图的地址了,到此完毕。从工程化的角度看,还是使用封装好的包更简单。

参考文档
如有侵权,烦请联系删除
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)