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();// 获取包nameSystem.out.println(apkMeta.getPackageName());// 获取app名称System.out.println(apkMeta.getName());// 获取版本信息System.out.println(apkMeta.getVersionCode());System.out.println(apkMeta.getVersionName());// 获取全部iconapkFile.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/bashif [ ! -s "${1}" ];thenecho "apk file is not exist";exit;
ficons=`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;doecho $icon;
doneecho "-----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 $anchorIFS='|' read -r -a array <<< "$anchor"
for element in "${array[@]}"; do
if [[ "$element" == *.png* ]]; thenecho `echo $element | cut -d' ' -f2`
fi
doneecho "-----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图的地址了,到此完毕。从工程化的角度看,还是使用封装好的包更简单。
参考文档
- https://zpp0196.me/2018/11/23/java-apk-parser/
- https://blog.csdn.net/chenqioulin/article/details/119357526
- https://code.google.com/p/android-apktool
- https://sq.sf.163.com/blog/article/172788280990601216
如有侵权,烦请联系删除