/* * Copyright 2008 Android4ME * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test; import android.content.res.AXmlResourceParser; import android.util.TypedValue; import org.xmlpull.v1.XmlPullParser; import java.io.File; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * This is example usage of AXMLParser class. * * Prints xml document from Android's binary xml file. */ public class AXMLPrinter { private static final String DEFAULT_XML = "AndroidManifest.xml"; public static void main(String[] arguments) { // if (arguments.length<1) { // System.out.println("Usage: AXMLPrinter <APK FILE PATH>"); // return; // } // String apkPath = "E:/apk_file/201008300227127991.apk"; String apkPath = "C:\\Users\\kltz\\Desktop\\AtlasDemo\\plugin\\libcom_lizhangqu_test.so"; System.out.println(getManifestXMLFromAPK(apkPath)); } public static String getManifestXMLFromAPK(String apkPath) { ZipFile file = null; StringBuilder xmlSb = new StringBuilder(100); try { File apkFile = new File(apkPath); file = new ZipFile(apkFile, ZipFile.OPEN_READ); ZipEntry entry = file.getEntry(DEFAULT_XML); AXmlResourceParser parser=new AXmlResourceParser(); parser.open(file.getInputStream(entry)); StringBuilder sb=new StringBuilder(10); final String indentStep=" "; int type; while ((type=parser.next()) != XmlPullParser.END_DOCUMENT) { switch (type) { case XmlPullParser.START_DOCUMENT: { log(xmlSb,"<?xml version=\"1.0\" encoding=\"utf-8\"?>"); break; } case XmlPullParser.START_TAG: { log(false,xmlSb,"%s<%s%s",sb, getNamespacePrefix(parser.getPrefix()),parser.getName()); sb.append(indentStep); int namespaceCountBefore=parser.getNamespaceCount(parser.getDepth()-1); int namespaceCount=parser.getNamespaceCount(parser.getDepth()); for (int i=namespaceCountBefore;i!=namespaceCount;++i) { log(xmlSb,"%sxmlns:%s=\"%s\"", i==namespaceCountBefore?" ":sb, parser.getNamespacePrefix(i), parser.getNamespaceUri(i)); } for (int i=0,size=parser.getAttributeCount();i!=size;++i) { log(false,xmlSb, "%s%s%s=\"%s\""," ", getNamespacePrefix(parser.getAttributePrefix(i)), parser.getAttributeName(i), getAttributeValue(parser,i)); } // log("%s>",sb); log(xmlSb,">"); break; } case XmlPullParser.END_TAG: { sb.setLength(sb.length()-indentStep.length()); log(xmlSb,"%s</%s%s>",sb, getNamespacePrefix(parser.getPrefix()), parser.getName()); break; } case XmlPullParser.TEXT: { log(xmlSb,"%s%s",sb,parser.getText()); break; } } } parser.close(); } catch (Exception e) { e.printStackTrace(); } return xmlSb.toString(); } private static String getNamespacePrefix(String prefix) { if (prefix==null || prefix.length()==0) { return ""; } return prefix+":"; } private static String getAttributeValue(AXmlResourceParser parser,int index) { int type=parser.getAttributeValueType(index); int data=parser.getAttributeValueData(index); if (type==TypedValue.TYPE_STRING) { return parser.getAttributeValue(index); } if (type==TypedValue.TYPE_ATTRIBUTE) { return String.format("?%s%08X",getPackage(data),data); } if (type==TypedValue.TYPE_REFERENCE) { return String.format("@%s%08X",getPackage(data),data); } if (type==TypedValue.TYPE_FLOAT) { return String.valueOf(Float.intBitsToFloat(data)); } if (type==TypedValue.TYPE_INT_HEX) { return String.format("0x%08X",data); } if (type==TypedValue.TYPE_INT_BOOLEAN) { return data!=0?"true":"false"; } if (type==TypedValue.TYPE_DIMENSION) { return Float.toString(complexToFloat(data))+ DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK]; } if (type==TypedValue.TYPE_FRACTION) { return Float.toString(complexToFloat(data))+ FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK]; } 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); } private static String getPackage(int id) { if (id>>>24==1) { return "android:"; } return ""; } private static void log(StringBuilder xmlSb,String format,Object...arguments) { log(true,xmlSb, format, arguments); } private static void log(boolean newLine,StringBuilder xmlSb,String format,Object...arguments) { // System.out.printf(format,arguments); // if(newLine) System.out.println(); xmlSb.append(String.format(format, arguments)); if(newLine) xmlSb.append("\n"); } /////////////////////////////////// ILLEGAL STUFF, DONT LOOK :) public static float complexToFloat(int complex) { return (complex & 0xFFFFFF00)*RADIX_MULTS[(complex>>4) & 3]; } private static final float RADIX_MULTS[]={ 0.00390625F,3.051758E-005F,1.192093E-007F,4.656613E-010F }; private static final String DIMENSION_UNITS[]={ "px","dip","sp","pt","in","mm","","" }; private static final String FRACTION_UNITS[]={ "%","%p","","","","","","" }; }