PHP: Как получить версию из файла .apk для android?

Я пытаюсь создать PHP-скрипт, чтобы получить версию приложения из файла APK от Android. Извлечение XML-файла из файла APK (zip), а затем синтаксический анализ XML – один из способов, но я думаю, это должно быть проще. Что-то вроде PHP Manual , пример # 3. Любые идеи о том, как создать скрипт?

Если на сервере установлен Android SDK, вы можете использовать exec (или аналогичный) PHP для выполнения инструмента aapt$ANDROID_HOME/platforms/android-X/tools ).

  $ aap dump badging myapp.apk 

И выход должен включать:

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

Если вы не можете установить Android SDK, по какой-то причине, вам нужно будет разобрать бинарный XML-формат Android. Файл AndroidManifest.xml внутри структуры ZIP APK не является простым текстом.

Вам нужно будет перенести утилиту, такую ​​как AXMLParser, с Java на PHP.

Я создал набор функций PHP, которые найдут только код версии APK. Это основано на том, что файл AndroidMainfest.xml содержит код версии в качестве первого тега и основан на формате axml (двоичный формат Android XML), как описано здесь

  <?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++; } } ?> 

Используйте это в CLI:

 apktool if 1.apk aapt dump badging 1.apk 

Эти команды можно использовать в PHP с помощью exec или shell_exec .

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

Вы получите читаемую человеком форму.

 sdkVersion:'14' targetSdkVersion:'14' 

Просто зайдите в свою систему, если у вас установлен Android SDK. Мой находится в:

 <SDKPATH>/build-tools/19.0.3/aapt 

Формат дампа немного странный и не самый простой для работы. Чтобы расширить некоторые другие ответы, это скрипт оболочки, который я использую для анализа имени и версии из файлов 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] }' 

Вот варианты, подходящие как для gawk, так и для 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 }'