{"id":2231,"date":"2015-04-03T10:21:29","date_gmt":"2015-04-03T02:21:29","guid":{"rendered":"http:\/\/blog.qdac.cc\/?p=2231"},"modified":"2015-04-03T10:21:29","modified_gmt":"2015-04-03T02:21:29","slug":"%e3%80%90delphi%e3%80%91axmlprinter-android-xml","status":"publish","type":"post","link":"https:\/\/blog.qdac.cc\/?p=2231","title":{"rendered":"\u3010Delphi\u3011AXMLPrinter (Android XML)"},"content":{"rendered":"<p>\u627e\u8fd9\u4e2a\u7684\u4eba\u80af\u5b9a\u77e5\u9053\u8fd9\u662f\u5e72\u4ec0\u4e48\u7684\u3002\u6ca1\u9519\uff0c\u6211\u82b1\u4e86\u534a\u5929\u65f6\u95f4\u5c06Java\u4ee3\u7801\u6539\u5199\u6210\u4e86Delphi\uff0c\u5728D2007\u4e0b\u8c03\u8bd5\u901a\u8fc7\u3002<\/p>\n<p>\u7528\u6cd5\u5f88\u7b80\u5355\uff0c\u5c06APK\u6587\u4ef6\u6539\u540d\u6210.zip\uff0c\u5c31\u53ef\u4ee5\u89e3\u538b\u7f29\u4e86\u3002\u89e3\u538b\u4ee5\u540e\u53ef\u4ee5\u770b\u5230\u5f88\u591a\u6587\u4ef6\uff0c\u5176\u4e2d\u6709\u5f88\u591a\u662f.xml\u540e\u7f00\u7684\u3002\u6253\u5f00\u53d1\u73b0\u5168\u662f\u4e71\u7801\u3002\u662f\u7684\uff0c\u4f60\u73b0\u5728\u9700\u8981AXMLPrinter\u4e86\u3002<\/p>\n<p>\u6bd4\u5982\u6211\u4eec\u77e5\u9053\uff0c\u5176\u4e2d\u7684AndroidManifest.XML\u6587\u4ef6\u5b58\u653e\u4e86\u4e00\u4e2aAPK\u7684\u5305\u540d\u3001\u7248\u672c\u53f7\u3001\u7248\u672c\u4ee3\u7801\u3001\u6743\u9650\u7b49\u4fe1\u606f\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 TXmlPullParser.ReadAndroidManifestFile \u6765\u8bfb\u53d6\u51fa\u8fd9\u4e9b\u4fe1\u606f\u3002\u4f60\u4e5f\u53ef\u4ee5\u53c2\u8003ReadAndroidManifestFile\u7684\u5199\u6cd5\uff0c\u5199\u51fa\u81ea\u5df1\u7684\u5904\u7406\u4ee3\u7801\uff0c\u83b7\u53d6\u66f4\u591a\u7684\u4fe1\u606f\u3002<\/p>\n<p>\u751a\u81f3\u4f60\u53ef\u4ee5\u914d\u5408unZip\u7684\u6a21\u5757\uff0c\u76f4\u63a5\u8bfb\u53d6APK\u4e2d\u6307\u5b9aXML\u6587\u4ef6\u3002<\/p>\n<pre class=\"lang:delphi decode:true \">{*******************************************************}\r\n{                                                       }\r\n{       AXMLPrinter (Android XML\u53cd\u7f16\u8bd1)                 }\r\n{                                                       }\r\n{       \u7248\u6743\u6240\u6709 (C) 2015 YangYxd                       }\r\n{                                                       }\r\n{*******************************************************}\r\n\r\nunit YxdAXMLPrinter;\r\n\r\ninterface\r\n\r\nuses\r\n  SysUtils, Classes;\r\n  \r\nconst\r\n  CHUNK_TYPE = $1C0001;\r\n  CHUNK_AXML_FILE = 524291;\r\n  CHUNK_RESOURCEIDS = 524672;\r\n  CHUNK_XML_FIRST = 1048832;\r\n  CHUNK_XML_START_NAMESPACE = 1048832;\r\n  CHUNK_XML_END_NAMESPACE = 1048833;\r\n  CHUNK_XML_START_TAG = 1048834;\r\n  CHUNK_XML_END_TAG = 1048835;\r\n  CHUNK_XML_TEXT = 1048836;\r\n  CHUNK_XML_LAST = 1048836;\r\n\r\nconst\r\n  RADIX_MULTS: array [0..3] of Double = (\r\n\t    0.0039063, 3.051758E-005, 1.192093E-007, 4.656613E-010);\r\n\tDIMENSION_UNITS: array [0..7] of String = (\r\n\t    'px', 'dip', 'sp', 'pt', 'in', 'mm', '', '');\r\n\tFRACTION_UNITS: array [0..7] of String = (\r\n\t    '%', '%p', '', '', '', '', '', '');\r\n\r\ntype\r\n  TIntegers = array of Integer;\r\ntype\r\n  TIntReader = class(TObject)\r\n  private\r\n    FStream: TStream;\r\n    FBigEndian: Boolean;\r\n    FPosition: Integer;\r\n  protected\r\n  public\r\n    constructor Create; overload;\r\n    constructor Create(AStream: TStream; bigEndian: Boolean); overload;\r\n    constructor Create(const AFileName: string; bigEndian: Boolean); overload;\r\n    destructor Destroy; override;\r\n\r\n    procedure reset(AStream: TStream; bigEndian: Boolean);\r\n    procedure Close();\r\n\r\n    function readByte(): ShortInt;\r\n    function readShort(): ShortInt;\r\n    function readInt(): Integer; overload;\r\n    function readInt(ALen: Integer): Integer; overload;\r\n    function readIntArray(ALen: Integer): TIntegers; overload;\r\n    procedure readIntArray(var AData: TIntegers); overload;\r\n    procedure readIntArray(var AData: TIntegers; AOffset, ALen: Integer); overload;\r\n    function readByteArray(ALen: Integer): TBytes;\r\n    procedure skip(bytes: Integer);\r\n    procedure skipInt();\r\n    function available(): Integer;\r\n\r\n    property Stream: TStream read FStream;\r\n    property IsBigEndian: Boolean read FBigEndian write FBigEndian;\r\n    property Position: Integer read FPosition write FPosition;\r\n  end;\r\n\r\ntype\r\n  TStringBlock = class\r\n  private\r\n    FStringOffset: TIntegers;\r\n    FStrings: TIntegers;\r\n    function GetCount: Integer;\r\n    function GetString(index: Integer): string;\r\n  protected\r\n    FStyleOffset: TIntegers;\r\n    FStyles: TIntegers;\r\n  public\r\n    constructor Create(); \r\n    destructor Destroy; override;\r\n    class function read(reader: TIntReader): TStringBlock;\r\n    function find(const str: string): Integer;\r\n    function getShort(const datas: TIntegers; offset: Integer): Integer;\r\n    property Count: Integer read GetCount;\r\n    property Items[index: Integer]: string read GetString;\r\n  end;\r\n\r\ntype\r\n  TNamespaceStack = class;\r\n  TXmlPullParser = class(TObject)\r\n  private\r\n    m_operational: Boolean;\r\n    m_strings: TStringBlock;\r\n    m_reader: TIntReader;\r\n    m_resourceIDs: TIntegers;\r\n    m_namespaces: TNamespaceStack;\r\n    m_decreaseDepth: Boolean;\r\n    m_event: Integer;\r\n    m_lineNumber: Integer;\r\n    m_name: Integer;\r\n    m_namespaceUri: Integer;\r\n    m_attributes: TIntegers;\r\n    m_idAttribute: Integer;\r\n    m_classAttribute: Integer;\r\n    m_styleAttribute: Integer;\r\n\r\n    procedure doNext();\r\n  protected\r\n  public\r\n    constructor Create; virtual;\r\n    destructor Destroy; override;\r\n\r\n    procedure Open(AStream: TStream); overload;\r\n    procedure Open(const AFileName: string); overload;\r\n    procedure Close();\r\n\r\n    class function getPackage(id: Integer): string;\r\n    class function complexToFloat(complex: Integer): Double;\r\n\r\n    \/\/ \u8bfb\u53d6 APK \u6587\u4ef6\u4e2dzip\u89e3\u538b\u540e\u7684 AndroidManifest.xml \u6587\u4ef6\u83b7\u53d6\u57fa\u672c\r\n    \/\/ \u4fe1\u606f \uff08\u5305\u540d\u3001\u7248\u672c\u540d\u79f0\u3001\u7248\u672c\u4ee3\u7801\uff09\r\n    class function ReadAndroidManifestFile(const AFileName: string;\r\n      var packageName, versionName: string; var versionCode: Integer): Boolean; overload;\r\n    \/\/ \u8bfb\u53d6 APK \u6587\u4ef6\u4e2dzip\u89e3\u538b\u540e\u7684 AndroidManifest.xml \u6587\u4ef6\u83b7\u53d6\u57fa\u672c\r\n    \/\/ \u4fe1\u606f \uff08\u5305\u540d\u3001\u7248\u672c\u540d\u79f0\u3001\u7248\u672c\u4ee3\u7801\uff09\r\n    class function ReadAndroidManifestFile(AStream: TStream;\r\n      var packageName, versionName: string; var versionCode: Integer): Boolean; overload;\r\n\r\n    function next(): Integer;\r\n    function nextToken(): Integer;\r\n    function nextTag(): Integer;\r\n    function nextText(): string;\r\n    procedure require(atype: Integer; const namespace, name: string);\r\n    function getDepth(): Integer;\r\n    function getEventType(): Integer;\r\n    function getLineNumber(): Integer;\r\n    function getName(): string;\r\n    function getText(): string;\r\n    function getNamespace(): string;\r\n    function getPrefix(): string;\r\n    function getPositionDescription(): string;\r\n    function getNamespaceCount(depth: Integer): Integer;\r\n    function getNamespacePrefix(apos: Integer): string;\r\n    function getNamespaceUri(apos: Integer): string;\r\n    function getClassAttribute(): string;\r\n    function getIdAttribute(): string;\r\n    function getIdAttributeResourceValue(defaultValue: Integer = 0): Integer;\r\n    function getStyleAttribute(): Integer;\r\n    function getAttributeCount(): Integer;\r\n    function getAttributeNamespace(index: Integer): string;\r\n    function getAttributePrefix(index: Integer): string;\r\n    function getAttributeName(index: Integer): string;\r\n    function getAttributeNameResource(index: Integer) :Integer;\r\n    function getAttributeValueType(index: Integer): Integer;\r\n    function getAttributeValueData(index: Integer): Integer;\r\n    function getAttributeValue(index: Integer): string; overload;\r\n    function getAttributeBooleanValue(index: Integer; defaultValue: Boolean = false): Boolean; overload;\r\n    function getAttributeFloatValue(index: Integer; defaultValue: Double = 0): Double; overload;\r\n    function getAttributeIntValue(index: Integer; defaultValue: Integer = 0): Integer; overload;\r\n    function getAttributeUnsignedIntValue(index: Integer; defaultValue: Cardinal = 0): Cardinal; overload;\r\n    function getAttributeResourceValue(index: Integer; defaultValue: Integer = 0): Integer; overload;\r\n    function getAttributeValue(const namespace, attribute: string): string; overload;\r\n    function getAttributeBooleanValue(const namespace, attribute: string; defaultValue: Boolean = False): Boolean; overload;\r\n    function getAttributeFloatValue(const namespace, attribute: string; defaultValue: Double = 0): Double; overload;\r\n    function getAttributeIntValue(const namespace, attribute: string; defaultValue: Integer = 0): Integer; overload;\r\n    function getAttributeUnsignedIntValue(const namespace, attribute: string; defaultValue: Cardinal = 0): Cardinal; overload;\r\n    function getAttributeResourceValue(const namespace, attribute: string; defaultValue: Integer = 0): Integer; overload;\r\n    function getAttributeListValue(index: Integer; options: array of string; defaultValue: Integer = 0): Integer; overload;\r\n    function getAttributeListValue(const namespace, attribute: string; options: array of string; defaultValue: Integer = 0): Integer; overload;\r\n    function getAttributeType(index: Integer): string;\r\n    function isAttributeDefault(index: Integer): Boolean;\r\n    function getInputEncoding(): string;\r\n    function getColumnNumber(): Integer;\r\n    function isEmptyElementTag(): Boolean;\r\n    function isWhitespace(): Boolean;\r\n    function getProperty(const name: string): TObject;\r\n    function getFeature(const feature: string): Boolean;\r\n    function getStrings(): TStringBlock;\r\n    function getAttributeOffset(index: Integer): Integer;\r\n    function findAttribute(const namespace, attribute: string): Integer;\r\n    function getAttributeValueEx(index: Integer): string;\r\n\r\n    procedure resetEventInfo();\r\n  end;<\/pre>\n<p>\u5b8c\u6574\u4ee3\u7801\u8bf7\u70b9\u51fb\u4e0b\u9762\u7684\u4e0b\u8f7d\u94fe\u63a5\uff0c\u6216\u52a0\u5165QDAC\u5b98\u65b9\u7fa4\uff08250530692\uff09\u7d22\u53d6\u3002<\/p>\n<p><strong>\u4e0b\u8f7d\u5730\u5740<\/strong>\uff1a <a title=\"http:\/\/pan.baidu.com\/s\/1sjK895r\" href=\"http:\/\/pan.baidu.com\/s\/1sjK895r\" target=\"_blank\">http:\/\/pan.baidu.com\/s\/1sjK895r<\/a> \u5bc6\u7801: aq7c<\/p>\n<p>\u5982\u53d1\u73b0\u6709Bug\uff0c\u8bf7\u5728\u8fd9\u91cc\u7559\u8a00\u544a\u8bc9\u6211\u3002<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u627e\u8fd9\u4e2a\u7684\u4eba\u80af\u5b9a\u77e5\u9053\u8fd9\u662f\u5e72\u4ec0\u4e48\u7684\u3002\u6ca1\u9519\uff0c\u6211 [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[8],"tags":[],"class_list":["post-2231","post","type-post","status-publish","format-standard","hentry","category-delphi"],"views":5026,"_links":{"self":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/2231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2231"}],"version-history":[{"count":1,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/2231\/revisions"}],"predecessor-version":[{"id":2232,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/2231\/revisions\/2232"}],"wp:attachment":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2231"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2231"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}