PHPスクリプトを作成して、Android APKファイルからアプリのバージョンを取得しようとしています。APK(Zip)ファイルからXMLファイルを抽出してからXMLを解析していますは1つの方法ですが、もっと簡単なはずです。 PHP Manual 、例#3のようなものです。スクリプトを作成する方法について何かアイデアはありますか?
サーバーにAndroid SDKがインストールされている場合は、PHPのexec(または同様のもの)を使用してaapt
ツールを実行できます($Android_HOME/platforms/Android-X/tools
)。
$ aapt dump badging myapp.apk
また、出力には次のものが含まれている必要があります。
パッケージ:name = 'com.example.myapp' versionCode = '1530' versionName = '1.5.3'
何らかの理由でAndroid SDK)をインストールできない場合は、AndroidのバイナリXML形式を解析する必要があります。AndroidManifest.xml
APK Zip構造内のファイルはnotプレーンテキストです。
AXMLParserのようなユーティリティ をJavaからPHPに移植する必要があります。
APKのバージョンコードのみを検索するPHP関数のセットを作成しました。これは、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++;
}
}
?>
ダンプ形式は少し奇妙で、操作が簡単ではありません。他のいくつかの答えを拡張するために、これは私が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 }'
aapt dump badging ./apkfile.apk | grep sdkVersion -i
人間が読める形式になります。
sdkVersion:'14'
targetSdkVersion:'14'
Android SDKがインストールされている場合は、システムでaaptを探してください。私のものは次の場所にあります。
<SDKPATH>/build-tools/19.0.3/aapt
CLIでこれを使用します。
apktool if 1.apk
aapt dump badging 1.apk
これらのコマンドは、PHP using exec
またはShell_exec
。