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-≫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;>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//---------------------