在做移动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