1 packagecom.apkutils;2
3 importjava.io.BufferedReader;4 importjava.io.Closeable;5 importjava.io.File;6 importjava.io.FileInputStream;7 importjava.io.IOException;8 importjava.io.InputStream;9 importjava.io.InputStreamReader;10 importjava.util.HashMap;11 importjava.util.Map;12 importjava.util.Properties;16
17
18 /**
19 * apk工具类。封装了获取Apk信息的方法。20 *21 *@author @authortony22 *23 *
24 * version description
25 * V0.2.1 修改程序名字为从路径中获得。26 *
28 public classApkUtil {29 public static final String VERSION_CODE = "versionCode";30 public static final String VERSION_NAME = "versionName";31 public static final String SDK_VERSION = "sdkVersion";32 public static final String TARGET_SDK_VERSION = "targetSdkVersion";33 public static final String USES_PERMISSION = "uses-permission";34 public static final String APPLICATION_LABEL = "application-label";35 public static final String APPLICATION_ICON = "application-icon";36 public static final String USES_FEATURE = "uses-feature";37 public static final String USES_IMPLIED_FEATURE = "uses-implied-feature";38 public static final String SUPPORTS_SCREENS = "supports-screens";39 public static final String SUPPORTS_ANY_DENSITY = "supports-any-density";40 public static final String DENSITIES = "densities";41 public static final String PACKAGE = "package";42 public static final String APPLICATION = "application:";43 public static final String LAUNCHABLE_ACTIVITY = "launchable-activity";44
45 //api ---- os
46 static Map OSVersion = new HashMap();47
48 static{49 OSVersion.put("3", "1.5");50 OSVersion.put("4", "1.6");51 OSVersion.put("5", "2.0");52 OSVersion.put("6", "2.0.1");53 OSVersion.put("7", "2.1");54 OSVersion.put("8", "2.2");55 OSVersion.put("9", "2.3");56 OSVersion.put("10", "2.3.3");57 OSVersion.put("11", "3.0");58 OSVersion.put("12", "3.1");59 OSVersion.put("13", "3.2");60 OSVersion.put("14", "4.0");61 OSVersion.put("15", "4.0.3");62 OSVersion.put("16", "4.1.1");63 OSVersion.put("17", "4.2");64 OSVersion.put("18", "4.3");65 OSVersion.put("19", "4.4");66 }67
68 private static final String SPLIT_REGEX = "(: )|(=')|(' )|'";69 private static final String FEATURE_SPLIT_REGEX = "(:')|(',')|'";70 /**
71 * aapt所在的目录。72 */
73 private String mAaptPath = "D:\\App\\";//winOS74 //private String mAaptPath = ApkUtil.class.getClassLoader().getResource("").getPath();//linux
75
76 staticString[] shellCommand;77 static String softName = "";78 static{79 shellCommand = new String[2];80 final String anOSName = System.getProperty("os.name");81 if (anOSName.toLowerCase().startsWith("windows")) {82 //Windows XP, Vista ...
83 shellCommand[0] = "cmd";84 shellCommand[1] = "/C";85 softName = "aapt.exe";86 } else{87 //Unix, Linux ...
88 shellCommand[0] = "/bin/sh";89 shellCommand[1] = "-c";90 softName = "aapt";91 }92 }93
94 /***95 * apkPath96 */
97 static String apkPath = "C:/Users/win7/Desktop/Android/baiduyinyue_49.apk";98
99 /**
100 * 返回一个apk程序的信息。101 *102 *@paramapkPath103 * apk的路径。104 *@returnapkInfo 一个Apk的信息。105 */
106 public ApkInfo getApkInfo(String apkPath) throwsException {107 String command = mAaptPath + softName + " d badging \"" +apkPath108 + "\"";109 Process process;110 try{111 process =Runtime.getRuntime().exec(112 new String[] {shellCommand[0], shellCommand[1], command});113 } catch(IOException e) {114 process = null;115 throwe;116 }117
118 ApkInfo apkInfo = null;119 if(process != null){120 InputStream is =process.getInputStream();121 BufferedReader br = newBufferedReader(122 new InputStreamReader(is, "utf8"));123 String tmp =br.readLine();124 try{125 if (tmp == null || !tmp.startsWith("package")) {126 throw new Exception("参数不正确,无法正常解析APK包。输出结果为:\n" + tmp + "...");127 }128 apkInfo = newApkInfo();129 do{130 setApkInfoProperty(apkInfo, tmp);131 } while ((tmp = br.readLine()) != null);132 } catch(Exception e) {133 throwe;134 } finally{135 process.destroy();136 closeIO(is);137 closeIO(br);138 }139 }140 returnapkInfo;141 }142
143 /**
144 * 设置APK的属性信息。145 *146 *@paramapkInfo147 *@paramsource148 */
149 private voidsetApkInfoProperty(ApkInfo apkInfo, String source) {150 if(source.startsWith(PACKAGE)) {151 splitPackageInfo(apkInfo, source);152 } else if(source.startsWith(LAUNCHABLE_ACTIVITY)) {153 apkInfo.setLaunchableActivity(getPropertyInQuote(source));154 } else if(source.startsWith(SDK_VERSION)) {155 apkInfo.setSdkVersion(getPropertyInQuote(source));156 apkInfo.setMinOSVersion(OSVersion.get(getPropertyInQuote(source)));157 } else if(source.startsWith(TARGET_SDK_VERSION)) {158 apkInfo.setTargetSdkVersion(getPropertyInQuote(source));159 } else if(source.startsWith(USES_PERMISSION)) {160 apkInfo.addToUsesPermissions(getPropertyInQuote(source));161 } else if(source.startsWith(APPLICATION_LABEL)) {162 apkInfo.setApplicationLable(getPropertyInQuote(source));163 } else if(source.startsWith(APPLICATION_ICON)) {164 apkInfo.addToApplicationIcons(getKeyBeforeColon(source),165 getPropertyInQuote(source));166 } else if(source.startsWith(APPLICATION)) {167 String[] rs = source.split("( icon=')|'");168 apkInfo.setApplicationIcon(rs[rs.length - 1]);169 } else if(source.startsWith(USES_FEATURE)) {170 apkInfo.addToFeatures(getPropertyInQuote(source));171 } else if(source.startsWith(USES_IMPLIED_FEATURE)) {172 apkInfo.addToImpliedFeatures(getFeature(source));173 } else{174
175 }176 try{177 apkInfo.setApkFileSize(getFileSizes(newFile(apkPath)));178 } catch(Exception e) {179 e.printStackTrace();180 }181 }182
183 privateImpliedFeature getFeature(String source) {184 String[] result =source.split(FEATURE_SPLIT_REGEX);185 ImpliedFeature impliedFeature = new ImpliedFeature(result[1], result[2]);186 returnimpliedFeature;187 }188
189 /**
190 * 返回出格式为name: 'value'中的value内容。191 *192 *@paramsource193 *@return
194 */
195 privateString getPropertyInQuote(String source) {196 int index = source.indexOf("'") + 1;197 return source.substring(index, source.indexOf('\'', index));198 }199
200 /**
201 * 返回冒号前的属性名称202 *203 *@paramsource204 *@return
205 */
206 privateString getKeyBeforeColon(String source) {207 return source.substring(0, source.indexOf(':'));208 }209
210 /**
211 * 分离出包名、版本等信息。212 *213 *@paramapkInfo214 *@parampackageSource215 */
216 private voidsplitPackageInfo(ApkInfo apkInfo, String packageSource) {217 String[] packageInfo =packageSource.split(SPLIT_REGEX);218 apkInfo.setPackageName(packageInfo[2]);219 apkInfo.setVersionCode(packageInfo[4]);220 apkInfo.setVersionName(packageInfo[6]);221 }222
223 /**
224 * 释放资源。225 *226 *@paramc227 * 将关闭的资源228 */
229 private final voidcloseIO(Closeable c) {230 if (c != null) {231 try{232 c.close();233 } catch(IOException e) {234 e.printStackTrace();235 }236 }237 }238
239 public static voidmain(String[] args) {240 try{241 ApkInfo apkInfo = newApkUtil().getApkInfo(apkPath);242 System.out.println(apkInfo);243 IconUtil.extractFileFromApk(apkPath, apkInfo.getApplicationIcon(),244 "D:\\icon.png");245 } catch(Exception e) {246 e.printStackTrace();247 }248 }249
250 publicString getmAaptPath() {251 returnmAaptPath;252 }253
254 public voidsetmAaptPath(String mAaptPath) {255 this.mAaptPath =mAaptPath;256 }257
258 //取得文件大小
259 public static long getFileSizes(File f) throwsException {260 long s = 0;261 if(f.exists()) {262 FileInputStream fis = null;263 fis = newFileInputStream(f);264 s =fis.available();265 } else{266 System.out.println("文件不存在");267 }268 returns;269 }270 }