亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

php上傳apk后怎么自動提取apk包信息

發布時間:2021-07-24 10:01:41 來源:億速云 閱讀:140 作者:chen 欄目:開發技術

本篇內容介紹了“php上傳apk后怎么自動提取apk包信息”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

進入公司第一個項目就是做market市場。所以后臺要上傳APK軟件之類。為了方便,上傳APK后由系統自動提取APK文件的相關信息,比如:apk包名、產品名稱、版本信息、APK Code、程序大小、ICON等。起初處理方式

通過命令:java -jar AXMLPrinter2.jar AndroidManifest.xml > cmdAfter.xml
得到cmdAfter.xml文件,然后分析cmdAfter.xml文件獲取相關信息。

但是遺憾的是,從這文件中可以得到apk包名,但無法得到ico圖標文件名及其它相關信息。如下圖所示

php上傳apk后怎么自動提取apk包信息

上圖中,比如label、icon等都是標志值,無法直接得到需要的結果。曾經分析該值與APK文件內部文件的關系,但不同的APK構造不同,實現過于麻煩。事實上,網上一些安桌市場等網站,當你上傳APK時,除了提取出APK包名外,還包括ICON圖標、大小等信息。因此,即然別人可以實現,我想肯定有辦法來解決這個事情。于是經過研究,得到預期結果。在此將方法做個記錄,歡迎交流。

核心提取APK信息代碼

復制代碼 代碼如下:


  /***
   * 分析已上傳的APK文件,提取所需要的數據
   */
  function upAPK(){
    global $_config_product_apktool_count;//使用apktool.jar解壓的次數,原因下面有說明。
    if($this->msg!='')return;//如果有錯誤,返回
    $dir=$this->upload_path;//上傳路徑
    $stringsXML_exists=false;
    if(file_exists($dir.'package/res/values/strings.xml'))unlink($dir.'package/res/values/strings.xml');
    for($i=0;$i<$_config_product_apktool_count && !$stringsXML_exists;$i++){
      //針對UC的APK包或其類似的APK包,解壓一次并不能完全得到strings.xml文件或相關文件。目前只有采用這個辦法了。
      //在系統cmd下直接使用java -jar ...執行解壓,有時可以得到strings.xml文件,有時也得不到,不知道是不是jar包的問題。
      exec('java -jar ../apktool.jar d -f '.$this->tmpFile.' '.$dir.'package');//注釋:解壓完畢再往下執行
      $stringsXML_exists=file_exists($dir.'package/res/values/strings.xml');
    }
    //檢查AndroidManifest.xml文件是否存在,如果不存在,則不是合法的APK文件
    if(!file_exists($dir.'package/AndroidManifest.xml')){$this->msg='不是合法的APK文件,請重新上傳!';return;}
    $AndroidManifestXML=file_get_contents($dir.'package/AndroidManifest.xml');//讀取AndroidManifest.xml

    if(preg_match('/package=\"([^\"]*)\"/i',$AndroidManifestXML,$package))$returnVal['package']=$package[1];//如果有包名,返回到數組

    //增加versionCode
    if(preg_match('/versionCode=\"([^\"]*)\"/i',$AndroidManifestXML,$versionCode))$returnVal['versionCode']=$versionCode[1];//如果有版本代碼,返回到數組

    //檢測到包名后判斷數據庫中是否已經存在。
    if($this->id==0){//添加新產品時檢測,修改產品不檢測
      if($returnVal['package']!=''){
        $sql='select id from product where package='.SqlEncode($package[1]);
        $result=mysql_query($sql);
        if(mysql_num_rows($result)>0){
          $this->msg='該APK已經存在,請更換!';
          return;
        }
      }else{
        $this->msg='系統無法檢測該APK信息,請聯系管理員!';
        return;
      }
    }

    if($stringsXML_exists)$stringXML=file_get_contents($dir.'package/res/values/strings.xml');//如果有strings.xml則讀取strings.xml文件
    if(preg_match('/versionName=\"([^\"]*)\"/i',$AndroidManifestXML,$ver))$returnVal['ver']=$ver[1];//如果有版本號,返回到數組
    //版本號的情況目前發現有兩種:1、版本號在AndroidManifest.xml中直接列出;通過以上正則即可提取
    //2、版本號同label一樣,放到strings.xml文件中
    //2011-11-23 add
    if($stringXML!='' && strstr($ver[1],'@')){
      if(preg_match('/^@string\/(.*)/i',$ver[1],$findVer)){
        if(preg_match('/<string name=\"'.$findVer[1].'\">([^<]*)<\/string>/',$stringXML,$a))$returnVal['ver']=$a[1];
      }
    }
    ////////////////////////////////////////////
    if(preg_match('/<application[\s\S]*? android:icon="@drawable\/([^"]*)"/i',$AndroidManifestXML,$icon))$returnVal['thumbimg']=$icon[1];//如果有圖標,返回到數組
    if($stringsXML_exists && preg_match('/<application[\s\S]*? android:label="@string\/([^"]*)"/i',$AndroidManifestXML,$label)){
      if(preg_match('/<string name=\"'.$label[1].'\">([^<]*)<\/string>/',$stringXML,$name)){
        $returnVal['name']=$name[1];//如果有產品名稱,返回到數組
        /**
        百度:strings.xml
        特殊情況1:<string name="app_name">"  掌上百度  "</string>
        */
        $returnVal['name']=preg_replace('/\s|"/','',$returnVal['name']);
      }
    }
    //$this->msg=$returnVal['package'].'--'.$returnVal['ver'].'--'.$returnVal['thumbimg'].'--'.$returnVal['name'];
    if($this->oldAPK!=''){//重新上傳則刪除原apk文件和icon.png圖片
      unlink($dir.$this->oldAPK);
      unlink($dir.$this->oldAPK.'.png');
    }
    //遍歷package/res目錄下的目錄[drawable|drawable-hdpi|drawable-nodpi|drawable-ldpi|drawable-mdpi]
    //系統取icon尺寸最大的圖標
    $tmpArr[0]=0;$tmpArr[1]=0;$tmpArr[2]='drawable';
    $dirs=opendir($dir.'package/res');
    while(($file=readdir($dirs))){
      preg_match('/(drawable(-.*?dpi)?)/i',$file,$drawable_folder);
      $iconPath=$dir.'package/res/'.$drawable_folder[1].'/'.$returnVal['thumbimg'].'.png';
      if(file_exists($iconPath)){
        $iconInfo=getimagesize($iconPath);
        if($iconInfo[0]>$tmpArr[0] && $iconInfo[1]>$tmpArr[1]){
          $tmpArr[0]=$iconInfo[0];$tmpArr[1]=$iconInfo[1];$tmpArr[2]=$drawable_folder[1];
        }
      }
    }
    //$this->msg=$iconInfo[0].'---'.$iconInfo[1];
    closedir($dirs);
    if(rename($dir.'package/res/'.$tmpArr[2].'/'.$returnVal['thumbimg'].'.png',$dir.$this->iframe_key.'.apk.png')){//找到目錄并成功移動
      $returnVal['thumbimg']=$this->iframe_key.'.apk.png';
    }
    if(!move_uploaded_file($this->tmpFile,$dir.$this->iframe_key.'.apk')){$this->msg='上傳失敗!';return;}//轉移apk文件
    $returnVal['filename']=$this->iframe_key.'.apk';
    $returnVal['size']=$this->size;
    $this->result=$returnVal;
  }   


提取信息流程

1、首先,通過apktool.jar命令提取apk文件中package/res/values/string.xml文件。不知為什么原因,釋放apk文件時,有時并不一定得到string.xml文件。所以,后臺增加:$_config_product_apktool_count參數,來控制釋放的最大次數。

2、讀取釋放根目錄下的AndroidManifest.xml文件。從該文件中可以獲取到APK包名、版本信息。

3、檢測,如果是新上傳的APK,則其包名在數據庫中是否存在。就是禁止上傳相同包名的APK。修改時不檢測。

4、通過正則獲取所需要的信息。

這里為什么要提取string.xml文件?

因為并不是所有信息,都在AndroidManifest.xml中。有的信息在AndroidManifest.xml中只是做為一個“引用”,真實記錄是在string.xml中的。比如

AndroidManifest.xml中關于Label和icon的值。

php上傳apk后怎么自動提取apk包信息

上圖中:label="@string/app_name" 表明在string.xml中string的name屬性為app_name的值,即為該APK的“軟件名稱”,這里是“Market市場”,如下圖所示:

php上傳apk后怎么自動提取apk包信息

@drawable/quickflick_icon,表示quickflick_icon為ICON的文件名。

由于特殊需要,我需要找到最大的ICON圖標,見下面代碼:

復制代碼 代碼如下:


     //遍歷package/res目錄下的目錄[drawable|drawable-hdpi|drawable-nodpi|drawable-ldpi|drawable-mdpi]
    //系統取icon尺寸最大的圖標
    $tmpArr[0]=0;$tmpArr[1]=0;$tmpArr[2]='drawable';
    $dirs=opendir($dir.'package/res');
    while(($file=readdir($dirs))){
      preg_match('/(drawable(-.*?dpi)?)/i',$file,$drawable_folder);
      $iconPath=$dir.'package/res/'.$drawable_folder[1].'/'.$returnVal['thumbimg'].'.png';
      if(file_exists($iconPath)){
        $iconInfo=getimagesize($iconPath);
        if($iconInfo[0]>$tmpArr[0] && $iconInfo[1]>$tmpArr[1]){
          $tmpArr[0]=$iconInfo[0];$tmpArr[1]=$iconInfo[1];$tmpArr[2]=$drawable_folder[1];
        }
      }
    }
    //$this->msg=$iconInfo[0].'---'.$iconInfo[1];
    closedir($dirs);
 


經過分析,一般APK中存放ICON圖標在以下幾個目錄:drawable|drawable-hdpi|drawable-nodpi|drawable-ldpi|drawable-mdpi,通過遍歷比較的方式獲取最大ICON圖標,并移到臨時目錄。

將所有需要提取的信息,存到一個數組中,并通過javascript寫到表單中。如下圖所示:

php上傳apk后怎么自動提取apk包信息

提取APK信息總結

上面的代碼,目前為止,在提取上傳的APK中,能能正常提取信息,未發現錯誤。在上面代碼的注釋中也看到,關于“掌上百度”這款APK,提取不了信息,是由于他的特殊處理方式,即:<string name="app_name">"  掌上百度  "</string>,他在名稱中加上了雙引號,這算是一個特例了吧。更多的特例我目前還未發現,所以,有可能會有特例出現,這需要分析APK的數據,并在程序中做特殊處理。

在實現這個APK提取功能中,關鍵是要找到APK包的組織規律,只有找到規律,程序實現就是在自然不過的事。

釋放APK文件注意內容

exec('java -jar ../apktool.jar d -f '.$this->tmpFile.' '.$dir.'package');

能順利執行上面的語句,要符合下面條件:

1、安裝java包,對java目錄,users用戶組的權限有:讀取和運行、列出文件夾目錄、讀取

2、cmd.exe文件,users用戶組的權限有:讀取和運行、讀取

3、PHP允許調用exec

4、上傳目錄要確保有寫入文件的權限

“php上傳apk后怎么自動提取apk包信息”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

尤溪县| 图木舒克市| 昔阳县| 深泽县| 崇义县| 龙陵县| 湘潭市| 三门峡市| 仙游县| 安溪县| 潮安县| 萨迦县| 盈江县| 湖州市| 同德县| 永康市| 湄潭县| 桓台县| 绥阳县| 磐石市| 宁南县| 曲水县| 江口县| 镶黄旗| 婺源县| 兴义市| 贺兰县| 阳谷县| 琼结县| 延边| 屏东市| 南漳县| 隆回县| 廉江市| 永福县| 济宁市| 都兰县| 平乡县| 嵩明县| 太康县| 昌图县|