android解析apk中manifest文件

通过 android 私有方法,快速解析 manifest,步骤如下:

  1. 首先通过 AssetManager 的 addAssetPath 方法获取 cookie,注意这个方法是隐藏的,所以需要通过反射来调用
  2. 然后通过 AssetManager 的 openXmlResourceParser 方法,传入 cookie, 返回解析器
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
41
42
43
44
public class TestLoadApk {
private static String TAG = "TestLoadApk";

public String getAppPackageId(Context context, String apkPath) {
String packageId = "";
try {
XmlResourceParser parser = getBinaryXmlParser(context, apkPath, "AndroidManifest.xml");
if (parser != null) {
int eventType;
while ((eventType = parser.nextToken()) != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
Log.i(TAG, "eventType:" + eventType + " name:" + parser.getName());
if (parser.getName().equals("manifest")) {
for (int i = 0; i < parser.getAttributeCount(); i++)
if (parser.getAttributeName(i).equals("package"))
packageId = parser.getAttributeValue(i);
break;
}
}
}

parser.close();
}
} catch (Exception e) {
e.printStackTrace();
}

Log.i(TAG, "packageId:" + packageId);

return packageId;
}

private static XmlResourceParser getBinaryXmlParser(Context context, String binaryFilePath, String binaryXmlFileName)
throws ReflectiveOperationException, IOException {
if (TextUtils.isEmpty(binaryFilePath) || TextUtils.isEmpty(binaryXmlFileName)) {
return null;
}
AssetManager assetManager = context.getAssets();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.setAccessible(true);
int cookie = (int) addAssetPath.invoke(assetManager, binaryFilePath);
return assetManager.openXmlResourceParser(cookie, binaryXmlFileName);
}
}
发布于

2023-02-24

更新于

2023-08-18

许可协议

评论