Я пытаюсь создать PHP скрипт, чтобы получить версию приложения из файла APK от Android. Извлечение XML файла из файла APK (zip), а затем синтаксический анализ XML - один из способов, но я думаю, это должно быть проще. Что-то вроде Руководство PHP, пример № 3. Любые идеи о создании script?
PHP: Как получить версию из файла .apk для android?
Ответ 1
Если у вас установлен 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. Файл AndroidManifest.xml
внутри структуры ZIP APK является не простым текстом.
Вам нужно будет поместить утилиту такую как AXMLParser с Java на PHP.
Ответ 2
Я создал набор функций 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: /questions/40895/how-to-parse-the-androidmanifestxml-file-inside-an-apk-package/295587#295587
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++;
}
}
?>
Ответ 3
Используйте это в CLI:
apktool if 1.apk
aapt dump badging 1.apk
Вы можете использовать эти команды в PHP с помощью exec
или shell_exec
.
Ответ 4
aapt dump badging ./apkfile.apk | grep sdkVersion -i
Вы получите читаемую человеком форму.
sdkVersion:'14'
targetSdkVersion:'14'
Просто заходите в систему, если у вас установлен Android SDK. Моя находится в:
<SDKPATH>/build-tools/19.0.3/aapt
Ответ 5
Формат дампа немного странный и не самый простой для работы. Чтобы развернуть некоторые другие ответы, это оболочка script, которую я использую для анализа имени и версии из файлов 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 }'