java解析APK
- - Linux - 操作系统 - ITeye博客1、结合安卓提供apktool工具,用java执行cmd解析命令获取apk信息. 2、利用相关jar包里的集成方法解析apk. 这里只给出第二种方法,因为第一种方法在linux服务器下会出现不在控制范围之内的结果. // 将解压文件对象转列举对象. // 获得名为AndroidManifest.xml的文件.
public class ApkUtil { /** * 日志对象 */ private static Logger log = LoggerFactory.getLogger(ApkUtil.class); private static final float RADIX_MULTS[] = { 0.00390625F, 3.051758E-005F, 1.192093E-007F, 4.656613E-010F }; private static final String DIMENSION_UNITS[] = { "px", "dip", "sp", "pt", "in", "mm", "", "" }; private static final String FRACTION_UNITS[] = { "%", "%p", "", "", "", "", "", "" }; /** * 获取apk信息 * * @param apkPath * @return */ public static String[] getApkInfo(String apkName) { // apk信息的返回结果 final String[] apkResult = new String[3]; ZipFile zipFile = null; try { final String apkPath = Toolkit.getTomcatRealPath() + CommonConstant.UPLOAD_SOFTVERSION + apkName; // 获得一个解压文件对象 zipFile = new ZipFile(apkPath); // 将解压文件对象转列举对象 final Enumeration enumeration = zipFile.entries(); ZipEntry zipEntry = null; // 遍历列举对象元素 while (enumeration.hasMoreElements()) { // 获得一个解压条目对象 zipEntry = (ZipEntry) enumeration.nextElement(); if (zipEntry.isDirectory()) { } else { // 获得名为AndroidManifest.xml的文件 if ("AndroidManifest.xml".equals(zipEntry.getName())) { try { final AXmlResourceParser parser = new AXmlResourceParser(); parser.open(zipFile.getInputStream(zipEntry)); // 遍历文件里的内容 while (true) { final int type = parser.next(); if (type == XmlPullParser.END_DOCUMENT) { break; } switch (type) { // 满足条件开始遍历内容提取需要的信息 case XmlPullParser.START_TAG: { for (int i = 0; i != parser.getAttributeCount(); ++i) { if ("package".equals(parser.getAttributeName(i))) { apkResult[0] = ApkUtil.getAttributeValue(parser, i); } else if ("versionCode".equals(parser.getAttributeName(i))) { apkResult[1] = ApkUtil.getAttributeValue(parser, i); } else if ("versionName".equals(parser.getAttributeName(i))) { apkResult[2] = ApkUtil.getAttributeValue(parser, i); } } } } } } catch (final Exception e) { ApkUtil.log.error("get file fail...!", e); } } } } } catch (final IOException e) { ApkUtil.log.error("analyzing fail...", e); } finally { if (zipFile != null) { try { zipFile.close(); } catch (final IOException e) { ApkUtil.log.error("Zipfile close fail.", e); } } } return apkResult; } private static String getAttributeValue(AXmlResourceParser parser, int index) { final int type = parser.getAttributeValueType(index); final int data = parser.getAttributeValueData(index); if (type == TypedValue.TYPE_STRING) { return parser.getAttributeValue(index); } if (type == TypedValue.TYPE_ATTRIBUTE) { return String.format("?%s%08X", ApkUtil.getPackage(data), data); } if (type == TypedValue.TYPE_REFERENCE) { return String.format("@%s%08X", ApkUtil.getPackage(data), data); } if (type == TypedValue.TYPE_FLOAT) { return String.valueOf(Float.intBitsToFloat(data)); } if (type == TypedValue.TYPE_INT_HEX) { return String.format("0x%08X", data); } if (type == TypedValue.TYPE_INT_BOOLEAN) { return data != 0 ? "true" : "false"; } if (type == TypedValue.TYPE_DIMENSION) { return Float.toString(ApkUtil.complexToFloat(data)) + ApkUtil.DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK]; } if (type == TypedValue.TYPE_FRACTION) { return Float.toString(ApkUtil.complexToFloat(data)) + ApkUtil.FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK]; } if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) { return String.format("#%08X", data); } if (type >= TypedValue.TYPE_FIRST_INT && type <= TypedValue.TYPE_LAST_INT) { return String.valueOf(data); } return String.format("<0x%X, type 0x%02X>", data, type); } private static String getPackage(int id) { if (id >>> 24 == 1) { return "android:"; } return ""; } public static float complexToFloat(int complex) { return (complex & 0xFFFFFF00) * ApkUtil.RADIX_MULTS[complex >> 4 & 3]; }