子兮子兮 子兮子兮

No can, but will.

目录
Java上传安卓apk安装包后获取应用的名称、包名、版本、图标等信息
/    

Java上传安卓apk安装包后获取应用的名称、包名、版本、图标等信息

在一个应用下载(应用市场)程序中,除了应用的信息显示、文件下载等功能,最重要的就是后台管理应用信息的功能,在 JavaWeb 程序中,可使用以下代码实现安卓安装包文件上传后的信息读取功能。需要导入 AXMLPrinter2.jar 包,用于反编译.apk 文件中的 AndroidManifest.xml 文件。

  1// package net.tanken.apps
  2import java.io.File;
  3import java.io.FileOutputStream;
  4import java.io.IOException;
  5import java.io.InputStream;
  6import java.io.OutputStream;
  7import java.util.Enumeration;
  8import java.util.zip.ZipEntry;
  9import java.util.zip.ZipFile;
 10import org.xmlpull.v1.XmlPullParser;
 11import android.content.res.AXmlResourceParser;
 12import android.util.TypedValue;`
 13
 14
 15/**
 16* 分析apk文件,获取apk应用的包名、版本信息及图标
 17*/
 18public class AnalysisApk {
 19
 20    private static final float RADIX_MULTS[] = { 0.00390625F, 3.051758E-005F, 1.192093E-007F, 4.656613E-010F };
 21    private static final String DIMENSION_UNITS[] = { "px", "dip", "sp", "pt", "in", "mm", "", "" };
 22    private static final String FRACTION_UNITS[] = { "%", "%p", "", "", "", "", "", "" };
 23
 24    /**
 25     * 解压.zip文件(apk可以当成一个zip文件),注意只能解压zip格式的文件,解压.rar文件会出现 java.io.IOException: Negative seek offset 异常
 26     * @param apkUrl apk应用(zip)文件的绝对路径
 27     * @param logoUrl 图标生成的地址
 28     * @throws IOException
 29     */
 30    public static String[] unZip(String apkUrl, String logoUrl) {
 31        String[] apkInfo = new String[3]; // [0]:版本号;[1]版本名;[2]包名
 32        byte b[] = new byte[1024];
 33        int length;
 34        ZipFile zipFile;
 35        try {
 36            zipFile = new ZipFile(new File(apkUrl));
 37            Enumeration enumeration = zipFile.entries();
 38            ZipEntry zipEntry = null;
 39            while (enumeration.hasMoreElements()) {
 40                zipEntry = (ZipEntry) enumeration.nextElement();
 41                if (!zipEntry.isDirectory()) { // 不是目录,即是文件
 42                    if ("AndroidManifest.xml".equals(zipEntry.getName())) { // 获取到安卓程序的清单文件
 43                        try {
 44                            AXmlResourceParser parser = new AXmlResourceParser();
 45                            parser.open(zipFile.getInputStream(zipEntry));
 46                            while (true) {
 47                                int type = parser.next();
 48                                if (type == XmlPullParser.END_DOCUMENT) {
 49                                    break;
 50                                }
 51                                switch (type) {
 52                                    case XmlPullParser.START_TAG: {
 53                                        for (int i = 0; i != parser.getAttributeCount(); ++i) {
 54                                            if ("versionCode".equals(parser.getAttributeName(i))) {
 55                                                apkInfo[0] = getAttributeValue(parser, i); // 版本号码
 56                                            } else if ("versionName".equals(parser.getAttributeName(i))) {
 57                                                apkInfo[1] = getAttributeValue(parser, i); // 版本名称
 58                                            } else if ("package".equals(parser.getAttributeName(i))) {
 59                                                apkInfo[2] = getAttributeValue(parser, i); // 包名
 60                                            }
 61                                        }
 62                                    }
 63                                }
 64                            }
 65                        } catch (Exception e) {
 66                            e.printStackTrace();
 67                        }
 68                    }
 69                    // 向指定路径logoUrl输出应用图标
 70                    if ("res/drawable-ldpi/icon.png".equals(zipEntry.getName())) {
 71                        OutputStream outputStream = new FileOutputStream(logoUrl);
 72                        InputStream inputStream = zipFile.getInputStream(zipEntry);
 73                        while ((length = inputStream.read(b)) > 0) {
 74                            outputStream.write(b, 0, length);
 75                        }
 76                        if(outputStream != null) {
 77                            outputStream.close();
 78                            outputStream = null;
 79                        }
 80                    }
 81                }
 82            }
 83        } catch (IOException e) {}
 84        return apkInfo;
 85    }
 86
 87    private static String getAttributeValue(AXmlResourceParser parser, int index) {
 88        int type = parser.getAttributeValueType(index);
 89        int data = parser.getAttributeValueData(index);
 90        if (type == TypedValue.TYPE_STRING) {
 91            return parser.getAttributeValue(index);
 92        }
 93        if (type == TypedValue.TYPE_ATTRIBUTE) {
 94            return String.format("?%s%08X", getPackage(data), data);
 95        }
 96        if (type == TypedValue.TYPE_REFERENCE) {
 97            return String.format("@%s%08X", getPackage(data), data);
 98        }
 99        if (type == TypedValue.TYPE_FLOAT) {
100            return String.valueOf(Float.intBitsToFloat(data));
101        }
102        if (type == TypedValue.TYPE_INT_HEX) {
103            return String.format("0x%08X", data);
104        }
105        if (type == TypedValue.TYPE_INT_BOOLEAN) {
106            return data == 0 ? "false" : "true";
107        }
108        if (type == TypedValue.TYPE_DIMENSION) {
109            return Float.toString(complexToFloat(data)) + DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
110        }
111        if (type == TypedValue.TYPE_FRACTION) {
112            return Float.toString(complexToFloat(data)) + FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
113        }
114        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);
115    }
116
117    private static String getPackage(int id) {
118        if (id >>> 24 == 1) {
119            return "android:";
120        }
121        return "";
122    }
123
124
125
126    // ILLEGAL STUFF, DONT LOOK 🙂
127    public static float complexToFloat(int complex) {
128        return (float) (complex & 0xFFFFFF00) * RADIX_MULTS[(complex >> 4) & 3];
129    }
130}

实例地址:https://www.itanken.cn/iTools/AppUpload/

源码与 jar 包官网下载

源码与 jar 包百度云下载(suzj)