温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

利用php怎么对apk包的信息进行获取

发布时间:2021-01-05 16:59:27 来源:亿速云 阅读:226 作者:Leah 栏目:开发技术

利用php怎么对apk包的信息进行获取?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

具体实现方法如下:

<?php /*解析安卓apk包中的压缩XML文件,还原和读取XML内容 依赖功能:需要PHP的ZIP包函数支持。*/ include('./Apkparser.php'); $appObj  = new Apkparser();  $targetFile = a.apk;//apk所在的路径地址 $res   = $appObj->open($targetFile); $appObj->getAppName();     // 应用名称 $appObj->getPackage();    // 应用包名 $appObj->getVersionName();  // 版本名称 $appObj->getVersionCode();  // 版本代码 ?>

以下是Apkparser类包,把以下代码复制出来保存为Apkparser.php就可以执行以上代码

<?php //------------------------------- //Apkparser类包开始 //------------------------------- class ApkParser{ //---------------------- // 公共函数,供外部调用 //----------------------   public 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;   }   public function parseString($xml){     $this->xml = $xml;     $this->length = strlen($xml);     $this->root = $this->parseBlock(self::AXML_FILE);     return true;   }   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("manifest/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');   }   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->getAttributeValue($a);       }     }     return NULL;   } //---------------------- // 类型常量定义 //----------------------   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; //---------------------- // 内部私有函数 //----------------------   private function getElement($path){     if (!$this->root) 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--;           }         }       }       // 没有找到节点       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->get32($o)),           'name' => $this->getString($this->get32($o)),           'flag' => $this->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->getNameSpace($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;         }         // 处理TAG字符串         $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->get32($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)$data;     }     return sprintf('<0x%X, type 0x%02X>', $data, $type);   }   private function _complexToFloat($data){     return (float)($data & 0xFFFFFF00) * self::$RADIX_MULTS[($data>>4) & 3];   }   private function _int2float($v) {     $x = ($v & ((1 << 23) - 1)) + (1 << 23) * ($v >> 31 | 1);     $exp = ($v >> 23 & 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类包结束  //--------------------- ?>

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI