1.   /**
      AndroidInfoUtils:安卓游戏包信息工具类
    **/
    1 public class AndroidInfoUtils
  2. {
  3. @SuppressWarnings("unchecked")
  4. public static ApkInfo getAndroidInfo(String apkPath) throws DocumentException
  5. {
  6. ApkInfo apkinfo = new ApkInfo();
  7. File file = new File(apkPath);
  8. // 获得APK文件名称
  9. apkinfo.setApkName(file.getName());
  10. // 获得APK文件大小
  11. apkinfo.setApkSize(convertFileSize(file.length()));
  12. // 获得APK文件原始大小
  13. apkinfo.setApkByteSize(file.length());
  14.  
  15. String xml = AXMLPrinter2.getManifestXMLFromAPK(apkPath);
  16. //System.out.println(xml);
  17. StringReader read = new StringReader(xml);
  18. InputSource scource = new InputSource(read);
  19. SAXReader sax = new SAXReader();
  20. Document root = sax.read(scource);
  21. Element uses_sdk = (Element) root.selectSingleNode("//uses-sdk");
  22. // 获取APK支持的Android SDK版本
  23. apkinfo.setApkMinsdkversion(uses_sdk.attributeValue("minSdkVersion"));
  24.  
  25. // zhouning 设置sdk目标版本
  26. apkinfo.setApkTargetSdkVersion(uses_sdk.attributeValue("targetSdkVersion"));
  27.  
  28. Element manifest = (Element) root.selectSingleNode("//manifest");
  29. // 获取APK版本
  30. apkinfo.setApkVersion(manifest.attributeValue("versionName"));
  31. // 获取APK包名
  32. apkinfo.setApkPageage(manifest.attributeValue("package"));
  33. // 获取APK版本代码
  34. apkinfo.setApkVersionCode(manifest.attributeValue("versionCode"));
  35. List<Element> elements = root.selectNodes("//uses-permission");
  36.  
  37. if (CommonUtil.isNotEmpty(elements)) {
  38. StringBuffer apkUserPermissionBuff = new StringBuffer();
  39. for (Element el : elements)
  40. {
  41. apkUserPermissionBuff.append("|").append(el.attributeValue("name"));
  42. }
  43.  
  44. String apkUserStr = apkUserPermissionBuff.toString();
  45.  
  46. if (CommonUtil.isNotEmpty(apkUserStr)) {
  47. apkinfo.setApkUserpermission(apkUserStr.substring(1));
  48. }
  49. }
  50.  
  51. //增加是否存在SDK的设置
  52. apkinfo.setExistSdk(AXMLPrinter2.isExistSdk(apkPath));
  53. // 设置SDK版本
  54. apkinfo.setSdkVersion(AXMLPrinter2.getSdkVersion(apkPath));
  55. // 设置SDK类型
  56. apkinfo.setApkSdkType(AXMLPrinter2.getSdkType(apkPath));
  57.  
  58. return apkinfo;
  59. }
  60.  
  61. public static String convertFileSize(long filesize)
  62. {
  63. String strUnit = "Bytes";
  64. String strAfterComma = "";
  65. int intDivisor = 1;
  66. if (filesize >= 1024 * 1024)
  67. {
  68. strUnit = "MB";
  69. intDivisor = 1024 * 1024;
  70. } else if (filesize >= 1024)
  71. {
  72. strUnit = "KB";
  73. intDivisor = 1024;
  74. }
  75. if (intDivisor == 1){
  76. return filesize + " " + strUnit;
  77. }
  78.  
  79. strAfterComma = "" + 100 * (filesize % intDivisor) / intDivisor;
  80. if (strAfterComma.equals(""))
  81. strAfterComma = ".0";
  82.  
  83. return filesize / intDivisor + "." + strAfterComma + " " + strUnit;
  84. }
  85.  
  86. public static ThreeNetsContent getThreeNetsContent(String apkPath)
  87. {
  88. return AXMLPrinter2.getThreeNetsContent(apkPath);
  89. }
  90. }

  所用到的ApkInfo

  

  1. public class ApkInfo {
  2.  
  3. // APK游戏名称
  4. private String apkName;
  5.  
  6. // APK游戏大小
  7. private String apkSize;
  8.  
  9. // APK游戏包名称
  10. private String apkPageage;
  11.  
  12. // APK游戏版本
  13. private String apkVersion;
  14.  
  15. // APK游戏版本代码
  16. private String apkVersionCode;
  17.  
  18. // APK游戏适应Android SDK版本
  19. private String apkMinsdkversion;
  20.  
  21. // APK游戏用户权限
  22. private String apkUserpermission;
  23.  
  24. // APK游戏字节大小
  25. private long apkByteSize;
  26.  
  27. // zhouning SDK目标版本
  28. private String apkTargetSdkVersion;
  29.  
  30. private boolean isExistSdk;
  31.  
  32. //add by mzz sdk类型
  33. private String apkSdkType;
  34.  
  35. /**
  36. * SDK版本
  37. */
  38. private String sdkVersion;
  39.  
  40. public boolean isExistSdk() {
  41. return isExistSdk;
  42. }
  43.  
  44. public void setExistSdk(boolean isExistSdk) {
  45. this.isExistSdk = isExistSdk;
  46. }
  47.  
  48. public String getApkName() {
  49. return apkName;
  50. }
  51.  
  52. public void setApkName(String apkName) {
  53. this.apkName = apkName;
  54. }
  55.  
  56. public String getApkSize() {
  57. return apkSize;
  58. }
  59.  
  60. public void setApkSize(String apkSize) {
  61. this.apkSize = apkSize;
  62. }
  63.  
  64. public String getApkPageage() {
  65. return apkPageage;
  66. }
  67.  
  68. public void setApkPageage(String apkPageage) {
  69. this.apkPageage = apkPageage;
  70. }
  71.  
  72. public String getApkVersion() {
  73. return apkVersion;
  74. }
  75.  
  76. public void setApkVersion(String apkVersion) {
  77. this.apkVersion = apkVersion;
  78. }
  79.  
  80. public String getApkVersionCode() {
  81. return apkVersionCode;
  82. }
  83.  
  84. public void setApkVersionCode(String apkVersionCode) {
  85. this.apkVersionCode = apkVersionCode;
  86. }
  87.  
  88. public String getApkMinsdkversion() {
  89. return apkMinsdkversion;
  90. }
  91.  
  92. public void setApkMinsdkversion(String apkMinsdkversion) {
  93. this.apkMinsdkversion = apkMinsdkversion;
  94. }
  95.  
  96. public String getApkUserpermission() {
  97. return apkUserpermission;
  98. }
  99.  
  100. public void setApkUserpermission(String apkUserpermission) {
  101. this.apkUserpermission = apkUserpermission;
  102. }
  103.  
  104. public long getApkByteSize() {
  105. return apkByteSize;
  106. }
  107.  
  108. public void setApkByteSize(long apkByteSize) {
  109. this.apkByteSize = apkByteSize;
  110. }
  111.  
  112. public String getApkTargetSdkVersion() {
  113. return apkTargetSdkVersion;
  114. }
  115.  
  116. public void setApkTargetSdkVersion(String apkTargetSdkVersion) {
  117. this.apkTargetSdkVersion = apkTargetSdkVersion;
  118. }
  119.  
  120. public String getSdkVersion()
  121. {
  122. return sdkVersion;
  123. }
  124.  
  125. public void setSdkVersion(String sdkVersion)
  126. {
  127. this.sdkVersion = sdkVersion;
  128. }
  129.  
  130. public void setApkSdkType(String apkSdkType) {
  131. this.apkSdkType = apkSdkType;
  132. }
  133.  
  134. public String getApkSdkType() {
  135. return apkSdkType;
  136. }
  137.  
  138. }

  

  解析Android 主文件  AndroidManifest.xml

  

  1. import java.io.BufferedReader;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.security.interfaces.RSAPublicKey;
  7. import java.security.spec.X509EncodedKeySpec;
  8. import java.util.zip.ZipEntry;
  9. import java.util.zip.ZipFile;
  10.  
  11. import org.apache.commons.codec.binary.Base64;
  12. import org.jdom.Document;
  13. import org.jdom.Element;
  14. import org.jdom.input.SAXBuilder;
  15.  
  16. import android.content.res.AXmlResourceParser;
  17.  
  18. import com.huawei.bme.commons.util.debug.DebugLog;
  19. import com.huawei.bme.commons.util.debug.LogFactory;
  20. import com.huawei.igop.common.constants.PropertyKey;
  21. import com.huawei.igop.common.plist.NSObject;
  22. import com.huawei.igop.common.plist.PropertyListParser;
  23. import com.huawei.igop.partner.bean.ThreeNetsContent;
  24. import com.huawei.igop2.common.utils.RSAUtils;
  25.  
  26. public class AXMLPrinter2 {
  27.  
  28. @SuppressWarnings("unused")
  29. private static final String DEFAULT_XML = "AndroidManifest.xml";
  30. private static final float[] RADIX_MULTS = { 0.0039063F, 3.051758E-005F,
  31. 1.192093E-007F, 4.656613E-010F };
  32. private static final String[] DIMENSION_UNITS = { "px", "dip", "sp", "pt",
  33. "in", "mm", "", "" };
  34. private static final String[] FRACTION_UNITS = { "%", "%p", "", "", "", "",
  35. "", "" };
  36.  
  37. public static String getManifestXMLFromAPK(String apkPath) {
  38. ZipFile file = null;
  39. StringBuilder xmlSb = new StringBuilder(100);
  40. try {
  41. int type;
  42. File apkFile = new File(apkPath);
  43. file = new ZipFile(apkFile, 1);
  44. ZipEntry entry = file.getEntry("AndroidManifest.xml");
  45.  
  46. AXmlResourceParser parser = new AXmlResourceParser();
  47. parser.open(file.getInputStream(entry));
  48.  
  49. StringBuilder sb = new StringBuilder(10);
  50. @SuppressWarnings("unused")
  51. String indentStep = "\t";
  52.  
  53. while ((type = parser.next()) != 1) {
  54. switch (type) {
  55. case 0:
  56. log(xmlSb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>",
  57. new Object[0]);
  58. break;
  59. case 2:
  60. log(false,
  61. xmlSb,
  62. "%s<%s%s",
  63. new Object[] { sb,
  64. getNamespacePrefix(parser.getPrefix()),
  65. parser.getName() });
  66. sb.append("\t");
  67.  
  68. int namespaceCountBefore = parser.getNamespaceCount(parser
  69. .getDepth() - 1);
  70. int namespaceCount = parser.getNamespaceCount(parser
  71. .getDepth());
  72.  
  73. for (int i = namespaceCountBefore; i != namespaceCount; ++i) {
  74. log(xmlSb,
  75. "%sxmlns:%s=\"%s\"",
  76. new Object[] {
  77. (i == namespaceCountBefore) ? " " : sb,
  78. parser.getNamespacePrefix(i),
  79. parser.getNamespaceUri(i) });
  80. }
  81.  
  82. int i = 0;
  83. for (int size = parser.getAttributeCount(); i != size; ++i) {
  84. log(false,
  85. xmlSb,
  86. "%s%s%s=\"%s\"",
  87. new Object[] {
  88. " ",
  89. getNamespacePrefix(parser
  90. .getAttributePrefix(i)),
  91. parser.getAttributeName(i),
  92. getAttributeValue(parser, i) });
  93. }
  94.  
  95. log(xmlSb, ">", new Object[0]);
  96. break;
  97. case 3:
  98. sb.setLength(sb.length() - "\t".length());
  99. log(xmlSb,
  100. "%s</%s%s>",
  101. new Object[] { sb,
  102. getNamespacePrefix(parser.getPrefix()),
  103. parser.getName() });
  104. break;
  105. case 4:
  106. log(xmlSb, "%s%s", new Object[] { sb, parser.getText() });
  107. case 1:
  108. }
  109.  
  110. }
  111.  
  112. parser.close();
  113. } catch (Exception e) {
  114. e.printStackTrace();
  115. } finally {
  116. if (file != null) {
  117. try {
  118. file.close();
  119. } catch (IOException e) {
  120.  
  121. }
  122. }
  123. }
  124. return xmlSb.toString();
  125. }
  126.  
  127. public static boolean isExistSdk(String apkPath) {
  128. ZipFile file = null;
  129. try {
  130. File apkFile = new File(apkPath);
  131. file = new ZipFile(apkFile, 1);
  132. ZipEntry entryCharge = file.getEntry("assets/Charge.xml");
  133. ZipEntry entryConsumeCode = file
  134. .getEntry("assets/ConsumeCodeInfo.xml");
  135. if (entryCharge != null && entryConsumeCode != null) {
  136. return true;
  137. }
  138. } catch (Exception e) {
  139. e.printStackTrace();
  140. } finally {
  141. if (file != null) {
  142. try {
  143. file.close();
  144. } catch (IOException e) {
  145. e.printStackTrace();
  146. }
  147. }
  148. }
  149. return false;
  150. }
  151.  
  152. private static String getNamespacePrefix(String prefix) {
  153. if ((prefix == null) || (prefix.length() == 0)) {
  154. return "";
  155. }
  156. return prefix + ":";
  157. }
  158.  
  159. private static String getAttributeValue(AXmlResourceParser parser, int index) {
  160. int type = parser.getAttributeValueType(index);
  161. int data = parser.getAttributeValueData(index);
  162. if (type == 3) {
  163. return parser.getAttributeValue(index);
  164. }
  165. if (type == 2) {
  166. return String.format("?%s%08X", new Object[] { getPackage(data),
  167. Integer.valueOf(data) });
  168. }
  169. if (type == 1) {
  170. return String.format("@%s%08X", new Object[] { getPackage(data),
  171. Integer.valueOf(data) });
  172. }
  173. if (type == 4) {
  174. return String.valueOf(Float.intBitsToFloat(data));
  175. }
  176. if (type == 17) {
  177. return String.format("0x%08X",
  178. new Object[] { Integer.valueOf(data) });
  179. }
  180. if (type == 18) {
  181. return ((data != 0) ? "true" : "false");
  182. }
  183. if (type == 5) {
  184. return Float.toString(complexToFloat(data))
  185. + DIMENSION_UNITS[(data & 0xF)];
  186. }
  187. if (type == 6) {
  188. return Float.toString(complexToFloat(data))
  189. + FRACTION_UNITS[(data & 0xF)];
  190. }
  191. if ((type >= 28) && (type <= 31)) {
  192. return String.format("#%08X",
  193. new Object[] { Integer.valueOf(data) });
  194. }
  195. if ((type >= 16) && (type <= 31)) {
  196. return String.valueOf(data);
  197. }
  198. return String.format("<0x%X, type 0x%02X>",
  199. new Object[] { Integer.valueOf(data), Integer.valueOf(type) });
  200. }
  201.  
  202. private static String getPackage(int id) {
  203. if (id >>> 24 == 1) {
  204. return "android:";
  205. }
  206. return "";
  207. }
  208.  
  209. private static void log(StringBuilder xmlSb, String format,
  210. Object[] arguments) {
  211. log(true, xmlSb, format, arguments);
  212. }
  213.  
  214. private static void log(boolean newLine, StringBuilder xmlSb,
  215. String format, Object[] arguments) {
  216. xmlSb.append(String.format(format, arguments));
  217. if (newLine)
  218. xmlSb.append("\n");
  219. }
  220.  
  221. public static float complexToFloat(int complex) {
  222. return ((complex & 0xFFFFFF00) * RADIX_MULTS[(complex >> 4 & 0x3)]);
  223. }
  224.  
  225. public static String getSdkVersion(String apkPath)
  226. {
  227. String sdkVersion = null;
  228. ZipFile zipfile = null;
  229. try
  230. {
  231. File apkFile = new File(apkPath);
  232. zipfile = new ZipFile(apkFile, 1);
  233. ZipEntry config = zipfile.getEntry("assets/Config.xml");
  234. if (null != config)
  235. {
  236. Document doc = new SAXBuilder().build(zipfile.getInputStream(config));
  237. sdkVersion = doc.getRootElement().getChildTextTrim("SDKVersion");
  238. }
  239. }
  240. catch (Exception e)
  241. {
  242. DEBUGGER.error("Failed to getSdkVersion", e);
  243. }
  244. finally
  245. {
  246. closeZipFile(zipfile);
  247. }
  248. return sdkVersion;
  249. }
  250.  
  251. public static String getSdkType(String apkPath)
  252. {
  253. String SdkType = null;
  254. ZipFile zipfile = null;
  255. try
  256. {
  257. File apkFile = new File(apkPath);
  258. zipfile = new ZipFile(apkFile, 1);
  259. ZipEntry config = zipfile.getEntry("assets/ConfigExt.xml");
  260. if (null != config)
  261. {
  262. //配置文件内容,由SDK通过RSA 私钥加密,iGop从包体读出时,通过RSA公钥解密(防止CP篡改)。
  263. BufferedReader in = new BufferedReader(new InputStreamReader(zipfile.getInputStream(config)));
  264. StringBuffer strBuffer = new StringBuffer();
  265. String buffer = null;
  266. while (null != (buffer = in.readLine()))
  267. {
  268. //得到密文
  269. strBuffer.append(buffer);
  270. }
  271. String key = PropertyUtil.getString(PropertyKey.SDK_TYPE_PUBLICKEY);
  272. X509EncodedKeySpec pubX509new = new X509EncodedKeySpec(Base64.decodeBase64(key.getBytes()));
  273. RSAPublicKey pukey1 = RSAUtils.getPublicKey(pubX509new);
  274. String jiewen = RSAUtils.decryptByPublicKey(strBuffer.toString(), pukey1);
  275. Document doc = new SAXBuilder().build(new ByteArrayInputStream(jiewen.getBytes()));
  276. SdkType = doc.getRootElement().getChildTextTrim("SDKType");
  277.  
  278. }
  279. }
  280. catch (Exception e)
  281. {
  282. DEBUGGER.error("Failed to getSdkType", e);
  283. }
  284. finally
  285. {
  286. closeZipFile(zipfile);
  287. }
  288. return SdkType;
  289. }
  290.  
  291. public static void closeZipFile(ZipFile zipfile)
  292. {
  293. if (null != zipfile)
  294. {
  295. try
  296. {
  297. zipfile.close();
  298. }
  299. catch (IOException e)
  300. {
  301. DEBUGGER.error("Failed to close ZipFile", e);
  302. }
  303. }
  304. }
  305.  
  306. public static ThreeNetsContent getThreeNetsContent(String apkPath)
  307. {
  308. ZipFile zipfile = null;
  309. ThreeNetsContent threeNetsContent = null;
  310. try
  311. {
  312. File file = new File(apkPath);
  313. zipfile = new ZipFile(file, 1);
  314. ZipEntry zipEntry = zipfile.getEntry("assets/touchpayservice.xml");
  315. if (null == zipEntry)
  316. {
  317. return null;
  318. }
  319.  
  320. threeNetsContent = new ThreeNetsContent();
  321. Document doc = new SAXBuilder().build(zipfile.getInputStream(zipEntry));
  322. Element element = doc.getRootElement();
  323. threeNetsContent.setCmServiceId(element.getChildTextTrim("cm_serviceid"));
  324. threeNetsContent.setCuServiceId(element.getChildTextTrim("cu_serviceid"));
  325. threeNetsContent.setCtServiceId(element.getChildTextTrim("ct_serviceid"));
  326. }
  327. catch (Exception e)
  328. {
  329. DEBUGGER.error("Failed to getThreeNetsContent", e);
  330. }
  331. finally
  332. {
  333. closeZipFile(zipfile);
  334. }
  335.  
  336. return threeNetsContent;
  337. }
  338.  
  339. public static boolean isExistsSdkFromIOS(String filePath, String projectName)
  340. {
  341. ZipFile file = null;
  342. try {
  343. File iosFile = new File(filePath);
  344. file = new ZipFile(iosFile, 1);
  345. ZipEntry entryCharge = file.getEntry("Payload/"+ projectName +"/Res.bundle/Charge.xml");
  346. ZipEntry entryConsumeCode = file.getEntry("Payload/"+ projectName +"/Res.bundle/ConsumeCodeInfo.xml");
  347. if (entryCharge != null && entryConsumeCode != null) {
  348. return true;
  349. }
  350. } catch (Exception e) {
  351. e.printStackTrace();
  352. } finally {
  353. closeZipFile(file);
  354. }
  355. return false;
  356. }
  357.  
  358. public static String getSdkVersionFromIOS(String filePath, String projectName)
  359. {
  360. String sdkVersion = null;
  361. ZipFile zipfile = null;
  362. try
  363. {
  364. File file = new File(filePath);
  365. zipfile = new ZipFile(file, 1);
  366. ZipEntry config = zipfile.getEntry("Payload/"+ projectName +"/Res.bundle/CM_iOS_Config.xml");
  367. if (null != config)
  368. {
  369. Document doc = new SAXBuilder().build(zipfile.getInputStream(config));
  370. sdkVersion = doc.getRootElement().getChildTextTrim("SDKVersion");
  371. }
  372. }
  373. catch (Exception e)
  374. {
  375. DEBUGGER.error("Failed to getSdkVersion4Ios", e);
  376. }
  377. finally
  378. {
  379. closeZipFile(zipfile);
  380. }
  381. return sdkVersion;
  382. }
  383.  
  384. public static String getXmlFromIOS(String filePath, String projectName)
  385. {
  386. ZipFile zipfile = null;
  387. NSObject nsObject = null;
  388. try
  389. {
  390. File file = new File(filePath);
  391. zipfile = new ZipFile(file, 1);
  392. ZipEntry entry = zipfile.getEntry("Payload/"+ projectName +"/Info.plist");
  393. nsObject = PropertyListParser.parse(zipfile.getInputStream(entry));
  394. }
  395. catch (Exception e)
  396. {
  397. DEBUGGER.error("Failed to getXmlFromIOS", e);
  398. }
  399. finally
  400. {
  401. closeZipFile(zipfile);
  402. }
  403. return nsObject.toXMLPropertyList();
  404. }
  405. }

  

  

  

  1. import java.io.IOException;
  2.  
  3. /**
  4. * Abstract interface for any object contained in a property list.
  5. * The names and functions of the various objects orient themselves
  6. * towards Apple's Cocoa API.
  7. * @author Daniel
  8. */
  9. public abstract class NSObject {
  10.  
  11. public final static String NEWLINE = System.getProperty("line.separator");
  12. public final static String INDENT = "\t";
  13.  
  14. /**
  15. * Generates the XML representation of the object (without XML headers or enclosing plist-tags).
  16. * @param xml The StringBuilder onto which the XML representation is appended.
  17. * @param level The indentation level of the object.
  18. */
  19. public abstract void toXML(StringBuilder xml, int level);
  20.  
  21. /**
  22. * Assigns IDs to all the objects in this NSObject subtree.
  23. */
  24. void assignIDs(BinaryPropertyListWriter out) {
  25. out.assignID(this);
  26. }
  27.  
  28. /**
  29. * Generates the binary representation of the object.
  30. * @param out The output stream to serialize the object to.
  31. */
  32. abstract void toBinary(BinaryPropertyListWriter out) throws IOException;
  33.  
  34. /**
  35. * Generates a valid XML property list including headers using this object as root.
  36. * @return The XML representation of the property list
  37. */
  38. public String toXMLPropertyList() {
  39. StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
  40. xml.append(NSObject.NEWLINE);
  41. xml.append("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
  42. xml.append(NSObject.NEWLINE);
  43. xml.append("<plist version=\"1.0\">");
  44. xml.append(NSObject.NEWLINE);
  45. toXML(xml, 0);
  46. xml.append(NSObject.NEWLINE);
  47. xml.append("</plist>");
  48. return xml.toString();
  49. }
  50.  
  51. protected void indent(StringBuilder xml, int level) {
  52. for(int i=0;i<level;i++)
  53. xml.append(INDENT);
  54. }
  55. }

  PropertyListParser.java

  1. /**
  2. * Parses any given property list
  3. * @author Daniel Dreibrodt
  4. */
  5. public class PropertyListParser {
  6.  
  7. /**
  8. * Reads all bytes from an InputStream and stores them in an array, up to
  9. * a maximum count.
  10. * @param in The InputStream
  11. * @param max The maximum number of bytes to read.
  12. **/
  13. static byte[] readAll(InputStream in, int max) throws IOException {
  14. ByteArrayOutputStream buf = new ByteArrayOutputStream();
  15. while (max > 0) {
  16. int n = in.read();
  17. if (n == -1) break; // EOF
  18. buf.write(n);
  19. max--;
  20. }
  21. return buf.toByteArray();
  22. }
  23.  
  24. /**
  25. * Parses a property list from a file. It can either be in XML or binary format.
  26. * @param f The property list file
  27. * @return The root object in the property list
  28. * @throws Exception If an error occurred while parsing
  29. */
  30. public static NSObject parse(File f) throws Exception {
  31. FileInputStream fis = new FileInputStream(f);
  32. String magicString = new String(readAll(fis, 8), 0, 8);
  33. fis.close();
  34. if (magicString.startsWith("bplist00")) {
  35. return BinaryPropertyListParser.parse(f);
  36. } else if (magicString.startsWith("<?xml")) {
  37. return XMLPropertyListParser.parse(f);
  38. } else {
  39. throw new UnsupportedOperationException("The given data is neither a binary nor a XML property list. ASCII property lists are not supported.");
  40. }
  41. }
  42.  
  43. /**
  44. * Parses a property list from a byte array. It can either be in XML or binary format.
  45. * @param bytes The property list data
  46. * @return The root object in the property list
  47. * @throws Exception If an error occurred while parsing.
  48. */
  49. public static NSObject parse(byte[] bytes) throws Exception {
  50. String magicString = new String(bytes, 0, 8);
  51. if (magicString.startsWith("bplist00")) {
  52. return BinaryPropertyListParser.parse(bytes);
  53. } else if (magicString.startsWith("<?xml")) {
  54. return XMLPropertyListParser.parse(bytes);
  55. } else {
  56. throw new UnsupportedOperationException("The given data is neither a binary nor a XML property list. ASCII property lists are not supported.");
  57. }
  58. }
  59.  
  60. /**
  61. * Parses a property list from an InputStream. It can either be in XML or binary format.
  62. * @param is The InputStream delivering the property list data
  63. * @return The root object of the property list
  64. * @throws Exception If an error occurred while parsing.
  65. */
  66. public static NSObject parse(InputStream is) throws Exception {
  67. if(is.markSupported()) {
  68. is.mark(10);
  69. String magicString = new String(readAll(is, 8), 0, 8);
  70. is.reset();
  71. if (magicString.startsWith("bplist00")) {
  72. return BinaryPropertyListParser.parse(is);
  73. } else if (magicString.startsWith("<?xml")) {
  74. return XMLPropertyListParser.parse(is);
  75. } else {
  76. throw new UnsupportedOperationException("The given data is neither a binary nor a XML property list. ASCII property lists are not supported.");
  77. }
  78. } else {
  79. //Now we have to read everything, because if one parsing method fails
  80. //the whole InputStream is lost as we can't reset it
  81. return parse(readAll(is, Integer.MAX_VALUE));
  82. }
  83. }
  84.  
  85. /**
  86. * Saves a property list with the given object as root into a XML file
  87. * @param root the root object
  88. * @param out the output file
  89. * @throws IOException if an error occurs during writing
  90. */
  91. public static void saveAsXML(NSObject root, File out) throws IOException {
  92. OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(out), "UTF-8");
  93. w.write(root.toXMLPropertyList());
  94. w.close();
  95. }
  96.  
  97. /**
  98. * Converts a given property list file into the xml format
  99. * @param in the source file
  100. * @param out the target file
  101. * @throws Exception if an error occurs during parsing
  102. * @throws IOException if an error occurs during writing
  103. */
  104. public static void convertToXml(File in, File out) throws Exception {
  105. NSObject root = parse(in);
  106. saveAsXML(root, out);
  107. }
  108.  
  109. /**
  110. * Saves a property list with the given object as root into a binary file
  111. * @param root the root object
  112. * @param out the output file
  113. * @throws IOException if an error occurs during writing
  114. */
  115. public static void saveAsBinary(NSObject root, File out) throws IOException {
  116. BinaryPropertyListWriter.write(out, root);
  117. }
  118.  
  119. /**
  120. * Converts a given property list file into the binary format
  121. * @param in the source file
  122. * @param out the target file
  123. * @throws Exception if an error occurs during parsing
  124. * @throws IOException if an error occurs during writing
  125. */
  126. public static void convertToBinary(File in, File out) throws Exception {
  127. NSObject root = parse(in);
  128. saveAsBinary(root, out);
  129. }
  130. }

Android 包信息工具类的更多相关文章

  1. 获取 Android APP 版本信息工具类(转载)

    获取 Android APP 版本信息工具类 获取手机APP版本信息工具类 1.获取版本名称 2.获取版本号 3.获取App的名称 package com.mingyue.nanshuibeidiao ...

  2. android 获取手机信息工具类

    package com.yqy.yqy_listviewheadview; import android.content.Context; import android.telephony.Telep ...

  3. Android 软件管理工具类Utils

    Android 软件管理工具类Utils /** * Created by uilubo on 2015/9/30. * 工具类 */ public class Utils { public stat ...

  4. (转载)实例详解Android快速开发工具类总结

    实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...

  5. 一个使用命令行编译Android项目的工具类

    一个使用命令行编译Android项目的工具类 简单介绍 编译apk项目须要使用的几个工具,基本都在sdk中,它们各自是(Windows系统): 1.aapt.exe 资源打包工具 2.android. ...

  6. Android开发常用工具类

    来源于http://www.open-open.com/lib/view/open1416535785398.html 主要介绍总结的Android开发中常用的工具类,大部分同样适用于Java. 目前 ...

  7. Android常用的工具类

    主要介绍总结的Android开发中常用的工具类,大部分同样适用于Java.目前包括HttpUtils.DownloadManagerPro.ShellUtils.PackageUtils. Prefe ...

  8. Android常用的工具类(转)

    主要介绍总结的Android开发中常用的工具类,大部分同样适用于Java.目前包括HttpUtils.DownloadManagerPro.ShellUtils.PackageUtils.Prefer ...

  9. 2013最新Android常用的工具类整理

    主要介绍总结的Android开发中常用的工具类,大部分同样适用于Java. 目前包括HttpUtils.DownloadManagerPro.ShellUtils.PackageUtils. Pref ...

随机推荐

  1. java之正则表达式的使用1

    正则表达式: 主要作用: a.匹配 b.切割 c.替换 d.获取 1.反斜杠和转义字符 废话不多说,直接上demo public static void main(String[] args) { / ...

  2. 高级浏览器-SRWare Iron 29.0.1600.0 版本发布

    SRWare Iron是德国一安全公司srware改造的Chrome(铬)命名为铁(iron)的浏览器.于2008年9月18日首次发布. 据官方介绍,Iron浏览器砍掉了Chromium原程序中的很多 ...

  3. 『转』Bitdefender Internet Security 2013 – 免费1年

    活动中可以选择获取Bitdefender Internet Security 2013+Bitdefender Mobile Security (手机版)各一年激活码申请地址:https://part ...

  4. Custom Ribbon in SharePoint 2010 & which not wrok when migrate from 2010 to 2013

    博客地址 http://blog.csdn.net/foxdave 1. First of all, let me show you the ribbon modal in our project w ...

  5. 20181009-7 选题 Scrum立会报告+燃尽图 06

    Scrum立会报告+燃尽图(06)选题 此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2196 一.小组介绍 组长:刘莹莹 ...

  6. 归并排序算法-Java实现

    简介: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序 基本思想: 将一个无序数组,利用 ...

  7. react native 获取 软键盘高度 和 新增软键盘的组件

    import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, Keyboard, Te ...

  8. AI人工智能专业词汇集

    作为最早关注人工智能技术的媒体,机器之心在编译国外技术博客.论文.专家观点等内容上已经积累了超过两年多的经验.期间,从无到有,机器之心的编译团队一直在积累专业词汇.虽然有很多的文章因为专业性我们没能尽 ...

  9. Spring的JDBC Template

    Spring的JDBC Template(JDBC模板)简化JDBC API开发,使用上和Apache公司的DBUtils框架非常类似) 快速入门实例 1.创建项目后,导入Spring基础核心开发包. ...

  10. centOS上安装MySQL5.7

    在centos上安装mysql,前提得有sudo的权限.没有的话先去跟管理员申请一个. STEP 1 - 安装MySQL 首先打开浏览器访问下 https://dev.mysql.com/downlo ...