PHP Get APK Package Info

Source: Internet
Author: User
Tags constant definition sprintf unpack

This time is too busy, one months did not write a blog, a little idle to feel the development of the problems encountered in the record

When PHP uploads the Android APK package, you need to get the information inside the Android APK package.


<?php/* resolves the compressed XML file in the Android APK package, restoring and reading the XML content dependency feature: Requires PHP's ZIP package function support. */include ('./apkparser.php '); $APPOBJ    = new Apkparser (); $targetFile = a.apk;//apk path address $res     = $APPOBJ Open ($targetFile); $appObj->getappname ();         Application name $appobj->getpackage ();        Application Package name $appobj->getversionname ();    Version name $appobj->getversioncode ();    Version Code?>


The following is the Apkparser class package, copy the following code to save as apkparser.php can execute the above code


-------------------------------//apkparser Class Package start//-------------------------------<?phpclass apkparser{//---- ------------------//Public function, for external call//----------------------Common function open ($apk _file, $xml _file= '        Androidmanifest.xml ') {$zip = new \ziparchive;            if ($zip->open ($apk _file) = = = TRUE) {$xml = $zip->getfromname ($xml _file);            $zip->close ();                if ($xml) {try {return $this->parsestring ($xml);    }catch (Exception $e) {}}} return false;        The Public Function parsestring ($xml) {$this->xml = $xml;         $this->length = strlen ($xml);        $this->root = $this->parseblock (self::axml_file);    return true;        The Public Function GetXML ($node =null, $lv =-1) {if ($lv = =-1) $node = $this->root;         if (! $node) return ';        if ($node [' type '] = = Self::end_tag) $lv--; $xml = @ ($node [' line '] = = 0 | | $node [' line '] = = $this->line)?        ': ' \ n '. Str_repeat (', $LV);        $xml. = $node [' tag '];        $this->line = @ $node [' line '];        foreach ($node [' child '] as $c) {$xml. = $this->getxml ($c, $LV + 1);    } return $xml;    } public Function Getpackage () {return $this->getattribute (' Manifest ', ' package ');    } public Function Getversionname () {return $this->getattribute (' Manifest ', ' android:versionname ');    } public Function Getversioncode () {return $this->getattribute (' Manifest ', ' android:versioncode ');    } public Function Getappname () {return $this->getattribute (' manifest/application ', ' android:name '); Public Function getmainactivity () {for ($id =0; true; $id + +) {$act = $this->getattribute ("Manife            st/application/activity[{$id}]/intent-filter/action ", ' android:name ');            if (! $act) break; if ($act = = ' Android.intent.action.MAIN ') return $this-&Gt;getactivity ($id);    } return NULL;        Public Function getactivity ($idx =0) {$idx = Intval ($IDX);    return $this->getattribute ("manifest/application/activity[{$idx}]", ' android:name ');        The Public function getattribute ($path, $name) {$r = $this->getelement ($path);         if (Is_null ($r)) return null; if (Isset ($r [' attrs '])) {foreach ($r [' attrs '] as $a) {if ($a [' ns_name '] = = $name) return $this-&            Gt;getattributevalue ($a);    }} return NULL;    }//----------------------//Type constant definition//----------------------const AXML_FILE = 0x00080003;    Const STRING_BLOCK = 0x001c0001;    Const RESOURCEIDS = 0x00080180;    Const START_NAMESPACE = 0x00100100;    Const END_NAMESPACE = 0x00100101;    Const START_TAG = 0x00100102;    Const END_TAG = 0x00100103;     Const TEXT = 0x00100104;          Const TYPE_NULL   = 0;    Const TYPE_REFERENCE = 1;    Const Type_attribute = 2;    Const TYPE_STRING = 3;    Const TYPE_FLOAT = 4;    Const TYPE_DIMENSION = 5;    Const TYPE_FRACTION = 6;    Const TYPE_INT_DEC = 16;    Const TYPE_INT_HEX = 17;    Const Type_int_boolean = 18;    Const TYPE_INT_COLOR_ARGB8 = 28;    Const TYPE_INT_COLOR_RGB8 = 29;    Const TYPE_INT_COLOR_ARGB4 = 30;     Const TYPE_INT_COLOR_RGB4 = 31;    Const UNIT_MASK = 15;    private static $RADIX _mults = Array (0.00390625, 3.051758E-005, 1.192093E-007, 4.656613E-010);    private static $DIMENSION _units = Array ("px", "dip", "SP", "PT", "in", "MM", "", "");     private static $FRACTION _units = Array ("%", "%p", "" "" "" "" "" "" "" "" "");    Private $xml = ';    Private $length = 0;    Private $stringCount = 0;    Private $styleCount = 0;    Private $stringTab = Array ();    Private $styleTab = Array ();    Private $resourceIDs = Array ();    Private $ns = Array (); Private $Cur_ns = NULL;    Private $root = NULL; Private $line = 0; ----------------------//internal private functions//----------------------Private Function GetElement ($path) {if (! $this->roo        T) return NULL;        $ps = explode ('/', $path);        $r = $this->root;                foreach ($ps as $v) {if (Preg_match ('/([^\[]+) \[([0-9]+] \]$/', $v, $ms)) {$v = $ms [1];            $off = $ms [2];            }else {$off = 0; } foreach ($r [' child '] as $c) {if ($c [' type '] = = Self::start_tag && $c [' ns_name '] = = $v)                    {if ($off = = 0) {$r = $c; continue 2;                    }else {$off--;        }}}//did not find the node return NULL;    } return $r;        } Private Function Parseblock ($need = 0) {$o = 0;        $type = $this->get32 ($o); if ($need && $type! = $need) throW New Exception (' Block Type Error ', 1);        $size = $this->get32 ($o);        if ($size < 8 | | $size > $this->length) throw new Exception (' Block size Error ', 2);         $left = $this->length-$size;        $props = false;                    Switch ($type) {case Self::axml_file: $props = Array (' line ' = = 0,            ' Tag ' = ' <?xml version= ' 1.0 ' encoding= ' utf-8 '?> ');            Break                Case Self::string_block: $this->stringcount = $this->get32 ($o);                $this->stylecount = $this->get32 ($o);                $o + = 4;                $strOffset = $this->get32 ($o);                $styOffset = $this->get32 ($o);                $strListOffset = $this->get32array ($o, $this->stringcount);                $styListOffset = $this->get32array ($o, $this->stylecount); $this->stringtab = $this->stringcount > 0? $this->getstrIngtab ($strOffset, $strListOffset): Array (); $this->styletab = $this->stylecount > 0?                $this->getstringtab ($styOffset, $styListOffset): Array ();            $o = $size;            Break                Case Self::resourceids: $count = $size/4-2;            $this->resourceids = $this->get32array ($o, $count);            Break                Case Self::start_namespace: $o + = 8;                $prefix = $this->get32 ($o);                 $uri = $this->get32 ($o);                    if (Empty ($this->cur_ns)) {$this->cur_ns = array ();                $this->ns[] = & $this->cur_ns;            } $this->cur_ns[$uri] = $prefix;            Break                Case Self::end_namespace: $o + = 8;                $prefix = $this->get32 ($o);                 $uri = $this->get32 ($o);                if (Empty ($this->cur_ns)) break; Unset ($this->cur_ns[$uri]);            Break                 Case Self::start_tag: $line = $this->get32 ($o);                $o + = 4;                $attrs = Array (); $props = Array (' line ' = = $line, ' ns ' = $this->getnamespace ($this->get3 2 ($o)), ' name ' = $this->getstring ($this->get32 ($o)), ' flag ' + $this-&G                    T;get32 ($o), ' count ' = $this->get16 ($o), ' id ' = $this->get16 ($o)-1,                    ' Class ' = $this->get16 ($o)-1, ' style ' = $this->get16 ($o)-1,                ' Attrs ' = & $attrs);                $props [' ns_name '] = $props [' NS ']. $props [' name ']; for ($i =0; $i < $props [' count ']; $i + +) {$a = array (' ns ' = = $this->getn Amespace ($this->get32 ($o)), ' name ' + = $thiS->getstring ($this->get32 ($o)), ' val_str ' + $this->get32 ($o), '                    Val_type ' = $this->get32 ($o), ' val_data ' + $this->get32 ($o));                    $a [' ns_name '] = $a [' ns ']. $a [' name '];                    $a [' Val_type '] >>= 24;                $attrs [] = $a;                }//handling tag string $tag = "<{$props [' Ns_name ']}";                    foreach ($this->cur_ns as $uri = + $prefix) {$uri = $this->getstring ($uri);                    $prefix = $this->getstring ($prefix);                $tag. = "xmlns:{$prefix}=\" {$uri}\ "";                            } foreach ($props [' attrs '] as $a) {$tag. = "{$a [' ns_name ']}=\" ".                            $this->getattributevalue ($a).                '"';                } $tag. = ' > ';  $props [' tag '] = $tag;               unset ($this->cur_ns);                $this->cur_ns = Array ();                $this->ns[] = & $this->cur_ns;            $left =-1;            Break                Case Self::end_tag: $line = $this->get32 ($o);                $o + = 4; $props = Array (' line ' = = $line, ' ns ' = $this->getnamespace ($this->get3                2 ($o)), ' name ' = $this->getstring ($this->get32 ($o)));                $props [' ns_name '] = $props [' NS ']. $props [' name '];                $props [' tag '] = "</{$props [' Ns_name ']}>";                    if (count ($this->ns) > 1) {array_pop ($this->ns);                    unset ($this->cur_ns);                    $this->cur_ns = Array_pop ($this->ns);                $this->ns[] = & $this->cur_ns;            } break;           Case Self::text: $o + = 8;     $props = Array (' tag ' = = $this->getstring ($this->get32 ($o)));            $o + = 8;            Break            Default:throw new Exception (' Block Type Error ', 3);        Break        } $this->skip ($o);        $child = Array ();            while ($this->length > $left) {$c = $this->parseblock ();            if ($props && $c) $child [] = $c;                if ($left = =-1 && $c [' type '] = = Self::end_tag) {$left = $this->length;            Break        }} if ($this->length! = $left) throw new Exception (' Block Overflow Error ', 4);            if ($props) {$props [' type '] = $type;            $props [' size '] = $size;            $props [' child '] = $child;        return $props;        }else {return false;        }} Private Function Getattributevalue ($a) {$type = & $a [' Val_type ']; $data = & $a [' VAL_data '];            Switch ($type) {case Self::type_string:return $this->getstring ($a [' val_str ']);            Case Self::type_attribute:return sprintf ('%s%08x ', Self::_getpackage ($data), $data);            Case Self::type_reference:return sprintf (' @%s%08x ', Self::_getpackage ($data), $data);            Case Self::type_int_hex:return sprintf (' 0x%08X ', $data); Case Self::type_int_boolean:return ($data! = 0?            ' True ': ' false ');            Case Self::type_int_color_argb8:case Self::type_int_color_rgb8:case SELF::TYPE_INT_COLOR_ARGB4:            Case Self::type_int_color_rgb4:return sprintf (' #%08x ', $data); Case Self::type_dimension:return $this->_complextofloat ($data). Self:: $DIMENSION _units[$data & self:            : Unit_mask]; Case Self::type_fraction:return $this->_complextofloat ($data). Self:: $FRAction_units[$data & Self::unit_mask];        Case Self::type_float:return $this->_int2float ($data); if ($type >=self::type_int_dec && $type < Self::type_int_color_argb8) {return (string) $d        Ata    } return sprintf (' <0x%x, type 0x%02x> ', $data, $type); } Private Function _complextofloat ($data) {return (float) ($data & 0xffffff00) * Self:: $RADIX _mults[($data &G    T;&GT;4) & 3]; } Private Function _int2float ($v) {$x = ($v & ((1 << 1)) + (1 << All) * ($v >> 31 |        1);        $exp = ($v >> & 0xFF)-127;    return $x * POW (2, $exp-23); } private static function _getpackage ($data) {return ($data >> 24 = = 1)?    ' Android: ': ';        } Private Function Getstringtab ($base, $list) {$tab = array ();            foreach ($list as $off) {$off + = $base;            $len = $this->get16 ($off); $mask = ($len >> 0x8) & 0xFF;            $len = $len & 0xFF; if ($len = = $mask) {if ($off + $len > $this->length) throw new Exception (' String Table Overflow ', 11)                ;            $tab [] = substr ($this->xml, $off, $len);                }else {if ($off + $len * 2 > $this->length) throw new Exception (' String Table Overflow ', 11);                $str = substr ($this->xml, $off, $len * 2);            $tab [] = mb_convert_encoding ($str, ' UTF-8 ', ' ucs-2le ');    }} return $tab;  } Private Function GetString ($id) {if ($id >-1 && $id < $this->stringcount) {return        $this->stringtab[$id];        }else {return '; }} Private Function GetNamespace ($uri) {for ($i =count ($this->ns); $i > 0;)            {$ns = $this->ns[--$i];                if (Isset ($ns [$uri])) {$ns = $this->getstring ($ns [$uri]); if (!Empty ($ns)) $ns. = ': ';            return $ns;    }} "return";        } Private Function Get32 (& $off) {$int = unpack (' V ', substr ($this->xml, $off, 4));        $off + = 4;    Return Array_shift ($int);        } Private Function Get32array (& $off, $size) {if ($size <= 0) return NULL;        $arr = Unpack (' v* ', substr ($this->xml, $off, 4 * $size));        if (count ($arr)! = $size) throw new Exception (' Array size Error ', 10);        $off + = 4 * $size;    return $arr;        } Private Function Get16 (& $off) {$int = unpack (' V ', substr ($this->xml, $off, 2));        $off + = 2;    Return Array_shift ($int);        } Private Function Skip ($size) {$this->xml = substr ($this->xml, $size);    $this->length-= $size; }}?>//---------------------//apkparser End of Class Package//---------------------






Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.