通过 android 私有方法,快速解析 manifest,步骤如下:
- 首先通过 AssetManager 的 addAssetPath 方法获取 cookie,注意这个方法是隐藏的,所以需要通过反射来调用
- 然后通过 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); } }
|