在做移动MDM功能的时候,就遇到了这样一个问题,当用户上传IPA文件时,我如何知道这个IPA文件的相关信息呢?IPA文件有一个很重要的文件Info.plist 就类似于Android程序的Manifest.xml,只要能够从IPA文件中提取出来Info.plist,然后在进行解析提起相关信息,那就马到成功了。那么,按照上面步骤开始了。
1、Java解压IPA文件,只获取 Info.plist
/** * 解压IPA文件,只获取IPA文件的Info.plist文件存储指定位置 * @param file * zip文件 * @param unzipDirectory * 解压到的目录 * @throws Exception */ private static File getZipInfo(File file, String unzipDirectory) throws Exception { // 定义输入输出流对象 InputStream input = null; OutputStream output = null; File result = null; File unzipFile = null; ZipFile zipFile = null; try { // 创建zip文件对象 zipFile = new ZipFile(file); // 创建本zip文件解压目录 String name = file.getName().substring(0,file.getName().lastIndexOf(".")); unzipFile = new File(unzipDirectory + "/" + name); if (unzipFile.exists()){ unzipFile.delete(); } unzipFile.mkdir(); // 得到zip文件条目枚举对象 Enumeration<ZipEntry> zipEnum = zipFile.getEntries(); // 定义对象 ZipEntry entry = null; String entryName = null; String names[] = null; int length; // 循环读取条目 while (zipEnum.hasMoreElements()) { // 得到当前条目 entry = zipEnum.nextElement(); entryName = new String(entry.getName()); // 用/分隔条目名称 names = entryName.split("\\/"); length = names.length; for (int v = 0; v < length; v++) { if(entryName.endsWith(".app/Info.plist")){ // 为Info.plist文件,则输出到文件 input = zipFile.getInputStream(entry); result = new File(unzipFile.getAbsolutePath()+ "/Info.plist"); output = new FileOutputStream(result); byte[] buffer = new byte[1024 * 8]; int readLen = 0; while ((readLen = input.read(buffer, 0, 1024 * 8)) != -1){ output.write(buffer, 0, readLen); } break; } } } } catch (Exception ex) { ex.printStackTrace(); } finally { if (input != null) input.close(); if (output != null) { output.flush(); output.close(); } // 必须关流,否则文件无法删除 if(zipFile != null){ zipFile.close(); } } // 如果有必要删除多余的文件 if(file.exists()){ file.delete(); } return result; }
/** * IPA文件的拷贝,把一个IPA文件复制为Zip文件,同时返回Info.plist文件 * 参数 oldfile 为 IPA文件 */ private static File getIpaInfo(File oldfile) throws IOException { try{ int byteread = 0; String filename = oldfile.getAbsolutePath().replaceAll(".ipa", ".zip"); File newfile = new File(filename); if (oldfile.exists()){ // 创建一个Zip文件 InputStream inStream = new FileInputStream(oldfile); FileOutputStream fs = new FileOutputStream(newfile); byte[] buffer = new byte[1444]; while ((byteread = inStream.read(buffer)) != -1){ fs.write(buffer,0,byteread); } if(inStream != null){ inStream.close(); } if(fs != null){ fs.close(); } // 解析Zip文件 return unzip(newfile, newfile.getParent()); } }catch(Exception e){ e.printStackTrace(); } return null; }
2、Java读取Info.plist文件,获取需要的信息
/** * 通过IPA文件获取Info信息 * 这个方法可以重构,原因是指获取了部分重要信息,如果想要获取全部,那么应该返回一个Map<String,Object> * 对于plist文件中的数组信息应该序列化存储在Map中,那么只需要第三发jar提供的NSArray可以做到! */ public static Map<String,String> getIpaInfoMap(File ipa) throws Exception{ Map<String,String> map = new HashMap<String,String>(); File file = getIpaInfo(ipa); // 第三方jar包提供 NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(file); // 应用包名 NSString parameters = (NSString) rootDict.objectForKey("CFBundleIdentifier"); map.put("CFBundleIdentifier", parameters.toString()); // 应用名称 parameters = (NSString) rootDict.objectForKey("CFBundleName"); map.put("CFBundleName", parameters.toString()); // 应用版本 parameters = (NSString) rootDict.objectForKey("CFBundleVersion"); map.put("CFBundleVersion", parameters.toString()); // 应用展示的名称 parameters = (NSString) rootDict.objectForKey("CFBundleDisplayName"); map.put("CFBundleDisplayName", parameters.toString()); // 应用所需IOS最低版本 parameters = (NSString) rootDict.objectForKey("MinimumOSVersion"); map.put("MinimumOSVersion", parameters.toString()); // 如果有必要,应该删除解压的结果文件 file.delete(); file.getParentFile().delete(); return map; }
3、程序测试
public static void main(String[] args) throws Exception { File file = new File("d:/UniAccess.ipa"); Map<String,String> map = getIpaInfoMap(file); for(String key : map.keySet()){ System.out.println(key+" : "+map.get(key)); } }
4、测试结果
CFBundleIdentifier : com.qihoo.installSafety CFBundleDisplayName : 360手机卫士 CFBundleName : 360MobileSafe CFBundleVersion : 4.2.0.2 MinimumOSVersion : 5.0
5、相关jar包,以及IPA文件,可以到如下指定地址下载
1)http://download.csdn.net/detail/wp562846864/8474481
2)http://m1.app111.org/2014/09/19/20140919142959.ipa