2010-06-10 42 views
18

我想創建一個PHP腳本來從Android APK文件中獲取應用程序版本。 從APK(zip)文件中提取XML文件,然後解析XML是一種方法,但我想它應該更簡單。例如PHP Manual,例#3。 任何想法如何創建腳本?PHP:如何從android.apk文件獲取版本?

+0

你必須在安裝Android SDK的可能性服務器? – 2010-06-10 13:13:17

+0

你想要獲取信息的郵編位於哪裏? – 2ndkauboy 2010-06-10 15:09:04

+0

@Francesco:沒有Android SDK @ Kau-Boy:zip(apk)文件位於服務器上,使用php腳本 是否有可能在我發佈的鏈接(示例#3)中執行類似操作? – Solata 2010-06-11 06:28:50

回答

47

如果你在服務器上安裝了Android SDK,你可以使用PHP的exec(或類似的)來執行aapt工具(在$ANDROID_HOME/platforms/android-X/tools)。

$ aapt dump badging myapp.apk

和輸出應包括:

package: name='com.example.myapp' versionCode='1530' versionName='1.5.3'

如果無法安裝Android SDK,無論出於何種原因,那麼你就需要解析Android的二進制XML格式。 APK zip結構內的AndroidManifest.xml文件是而不是純文本。

您需要將utility like AXMLParser從Java移植到PHP。

+0

服務器上沒有Android SDK,帶有PHP腳本。我正在尋找解決方案,如在我發佈的鏈接(例如#3) – Solata 2010-06-11 06:31:52

+0

我更新了我的答案。 – 2010-06-11 08:23:32

+0

@ChristopherOrr你能否提供一個關於第一種方式的例子,我不能通過我的Windows Server來運行它! – iSun 2013-08-01 14:15:46

1

在CLI中使用此:

apktool if 1.apk 
aapt dump badging 1.apk 

可以使用execshell_exec在PHP中使用這些命令。

6

我創建了一組PHP函數,它們只會查找APK的版本代碼。這是基於該AndroidMainfest.xml文件中包含的版本代碼作爲第一個標籤的事實,並基於axml(二進制的Android XML格式)爲described here

<?php 
$APKLocation = "PATH TO APK GOES HERE"; 

$versionCode = getVersionCodeFromAPK($APKLocation); 
echo $versionCode; 

//Based on the fact that the Version Code is the first tag in the AndroidManifest.xml file, this will return its value 
//PHP implementation based on the AXML format described here: https://stackoverflow.com/questions/2097813/how-to-parse-the-androidmanifest-xml-file-inside-an-apk-package/14814245#14814245 
function getVersionCodeFromAPK($APKLocation) { 

    $versionCode = "N/A"; 

    //AXML LEW 32-bit word (hex) for a start tag 
    $XMLStartTag = "00100102"; 

    //APK is esentially a zip file, so open it 
    $zip = zip_open($APKLocation); 
    if ($zip) { 
     while ($zip_entry = zip_read($zip)) { 
      //Look for the AndroidManifest.xml file in the APK root directory 
      if (zip_entry_name($zip_entry) == "AndroidManifest.xml") { 
       //Get the contents of the file in hex format 
       $axml = getHex($zip, $zip_entry); 
       //Convert AXML hex file into an array of 32-bit words 
       $axmlArr = convert2wordArray($axml); 
       //Convert AXML 32-bit word array into Little Endian format 32-bit word array 
       $axmlArr = convert2LEWwordArray($axmlArr); 
       //Get first AXML open tag word index 
       $firstStartTagword = findWord($axmlArr, $XMLStartTag); 
       //The version code is 13 words after the first open tag word 
       $versionCode = intval($axmlArr[$firstStartTagword + 13], 16); 

       break; 
      } 
     } 
    } 
    zip_close($zip); 

    return $versionCode; 
} 

//Get the contents of the file in hex format 
function getHex($zip, $zip_entry) { 
    if (zip_entry_open($zip, $zip_entry, 'r')) { 
     $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); 
     $hex = unpack("H*", $buf); 
     return current($hex); 
    } 
} 

    //Given a hex byte stream, return an array of words 
function convert2wordArray($hex) { 
    $wordArr = array(); 
    $numwords = strlen($hex)/8; 

    for ($i = 0; $i < $numwords; $i++) 
     $wordArr[] = substr($hex, $i * 8, 8); 

    return $wordArr; 
} 

//Given an array of words, convert them to Little Endian format (LSB first) 
function convert2LEWwordArray($wordArr) { 
    $LEWArr = array(); 

    foreach($wordArr as $word) { 
     $LEWword = ""; 
     for ($i = 0; $i < strlen($word)/2; $i++) 
      $LEWword .= substr($word, (strlen($word) - ($i*2) - 2), 2); 
     $LEWArr[] = $LEWword; 
    } 

    return $LEWArr; 
} 

//Find a word in the word array and return its index value 
function findWord($wordArr, $wordToFind) { 
    $currentword = 0; 
    foreach ($wordArr as $word) { 
     if ($word == $wordToFind) 
      return $currentword; 
     else 
      $currentword++; 
    } 
} 
    ?> 
+0

hi @ CHeil402如何獲取版本號 – 2015-02-25 13:13:23

1
aapt dump badging ./apkfile.apk | grep sdkVersion -i 

你會得到一個人類可讀形成。

sdkVersion:'14' 
targetSdkVersion:'14' 

如果您安裝了Android SDK,只需在系統中查找aapt即可。 Mine is in:

<SDKPATH>/build-tools/19.0.3/aapt 
1

轉儲格式有點奇怪,不是最簡單的工作。爲了擴展一些其他答案,這是一個shell腳本,我用它從APK文件中解析出名稱和版本。

aapt d badging PACKAGE | gawk $'match($0, /^application-label:\'([^\']*)\'/, a) { n = a[1] } 
           match($0, /versionName=\'([^\']*)\'/, b) { v=b[1] } 
           END { if (length(n)>0 && length(v)>0) { print n, v } }' 

如果你只是想要的版本,那麼顯然它可以更簡單。

aapt d badging PACKAGE | gawk $'match($0, /versionName=\'([^\']*)\'/, v) { print v[1] }' 

這裏有適合於觀看或mawk變化(有點不太耐用,以防轉儲格式的變化,但應該罰款):

aapt d badging PACKAGE | mawk -F\' '$1 ~ /^application-label:$/ { n=$2 } 
            $5 ~ /^ versionName=$/ { v=$6 } 
            END{ if (length(n)>0 && length(v)>0) { print n, v } }' 

aapt d badging PACKAGE | mawk -F\' '$5 ~ /^ versionName=$/ { print $6 }'