Java 解析 apk 信息

apk-parser,一个纯 Java 实现的解析 Apk 的 lib,用于解码二进制 xml 文件,获取 Apk 信息。

Features

  •  查看 Apk 的信息,如应用名、图标、包名、SDK 版本、权限、版本等
  • 将二进制 xml 文件解析并转换为文本
  • 从 dex 文件中获取类
  • 获取签名信息

Get apk-parser

Maven

1
2
3
4
5
<dependency>
<groupId>net.dongliu</groupId>
<artifactId>apk-parser</artifactId>
<version>2.6.10</version>
</dependency>

Maven Repository: net.dongliu » apk-parser

Gradle

1
2
// compile group: 'net.dongliu', name: 'apk-parser', version: '2.6.10'
compile 'net.dongliu:apk-parser:2.6.10'

GitHub

Releases · hsiafan/apk-parser

Jar

Central Repository: net/dongliu/apk-parser

Usage

使用 ApkFile 类来获取 AndroidManifest.xml、apk 的信息。

Apk info

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ApkFile apkFile = null;
try {
apkFile = new ApkFile(new File(apkPath));
ApkMeta apkMeta = apkFile.getApkMeta();
// System.out.println(apkMeta);
System.out.println("应用名:" + apkMeta.getLabel());
System.out.println("包名:" + apkMeta.getPackageName());
System.out.println("版本:" + apkMeta.getVersionName());
System.out.println("版本号:" + apkMeta.getVersionCode());
} catch (IOException e) {
e.printStackTrace();
} finally {
// TODO close apkFile
}

ApkFile 使用完后记得释放资源。

Get binary xml and manifest xml file

1
2
3
4
5
6
7
8
9
10
ApkFile apkFile = null;
try {
apkFile = new ApkFile(new File(apkPath));
String manifestXml = apkFile.getManifestXml();
String menuXml = apkFile.transBinaryXml("res/menu/main.xml");
} catch (IOException e) {
e.printStackTrace();
} finally {
// TODO close apkFile
}

Get dex classes

1
2
3
4
5
6
7
8
9
10
11
12
ApkFile apkFile = null;
try {
apkFile = new ApkFile(new File(apkPath));
DexClass[] classes = apkFile.getDexClasses();
for (DexClass dexClass : classes) {
System.out.println(dexClass);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// TODO close apkFile
}

Get Apk Sign info

1
2
3
4
5
6
7
8
9
10
ApkFile apkFile = null;
try {
apkFile = new ApkFile(new File(apkPath));
List<ApkSigner> signers = apkFile.getApkSingers(); // apk v1 signers
List<ApkV2Signer> v2signers = apkFile.getApkV2Singers(); // apk v2 signers
} catch (IOException e) {
e.printStackTrace();
} finally {
// TODO close apkFile
}

Save icon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public static void main(String[] args) {
ApkFile apkFile = null;
String apkPath = "C:/test.apk";
try {
apkFile = new ApkFile(new File(apkPath));
// 保存所有 icon
for (IconFace iconFace : apkFile.getAllIcons()) {
saveIcon(savePath, iconFace);
}
// 保存主 icon
// saveIcon(savePath, apkFile.getIconFile());
} catch (IOException e) {
e.printStackTrace();
} finally {
// TODO close apkFile
}
}

/**
* 保存 apk 的 icon
*
* @param savePath 保存的目录
* @param icon
* @throws IOException
*/
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();
}