Android应用开发之PHP获取android文件的相关信息
白羽 2018-08-10 来源 :网络 阅读 942 评论 0

摘要:本文将带你了解Android应用开发之PHP获取android文件的相关信息,希望本文对大家学Android有所帮助

        本文将带你了解Android应用开发之PHP获取android文件的相关信息,希望本文对大家学Android有所帮助


Php代码  /** 解析安卓apk包中的压缩XML文件,还原和读取XML内容 依赖功能:需要PHP的ZIP包函数支持。 */  include('Apkparser.php');  $appObj  = new Apkparser();  $targetFile = 'baidu.apk';//apk所在的路径地址  $res = $appObj->open($targetFile);  echo $appObj->getAppName();         // 应用名称  echo '
'.$appObj->getPackage();        // 应用包名  echo '
'.$appObj->getVersionName();    // 版本名称  echo '
'.$appObj->getVersionCode();    // 版本代码  /**
解析安卓apk包中的压缩XML文件,还原和读取XML内容
依赖功能:需要PHP的ZIP包函数支持。
*/
include('Apkparser.php');
$appObj  = new Apkparser();
$targetFile = 'baidu.apk';//apk所在的路径地址
$res = $appObj->open($targetFile);
echo $appObj->getAppName();         // 应用名称
echo '
'.$appObj->getPackage();        // 应用包名
echo '
'.$appObj->getVersionName();    // 版本名称
echo '
'.$appObj->getVersionCode();    // 版本代码
以下是Apkparser类包,把以下代码复制出来保存为Apkparser.php就可以执行以上代码
 
Php代码  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' => ''                  );              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 (emptyempty($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 (emptyempty($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'] = "";                  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="" 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 (!emptyempty($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 <= return="" arr="unpack('V*'," 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;      }  }  ?>  <?php
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' => ''
    );
   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'] = "";
    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="" 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;
 }

     

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程