PHP:如何从 android .apk 文件中获取版本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3014369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:19:11  来源:igfitidea点击:

PHP: How to get version from android .apk file?

phpxmlandroidversionapk

提问by Solata

I am trying to create a PHP script to get the app version from Android APK file. Extracting XML file from the APK (zip) file and then parsing XML is one way, but I guess it should be simpler. Something like PHP Manual, example #3. Any ideas how to create the script?

我正在尝试创建一个 PHP 脚本以从 Android APK 文件中获取应用程序版本。从 APK (zip) 文件中提取 XML 文件然后解析 XML 是一种方法,但我想它应该更简单。类似于PHP 手册,示例 #3。任何想法如何创建脚本?

回答by Christopher Orr

If you have the Android SDK installed on the server, you can use PHP's exec (or similar) to execute the aapttool (in $ANDROID_HOME/platforms/android-X/tools).

如果您在服务器上安装了 Android SDK,您可以使用 PHP 的 exec(或类似的)来执行该aapt工具(在 中$ANDROID_HOME/platforms/android-X/tools)。

$ aapt dump badging myapp.apk

And the output should include:

输出应包括:

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

If you can'tinstall the Android SDK, for whatever reason, then you will need to parse Android's binary XML format. The AndroidManifest.xmlfile inside the APK zip structure is notplain text.

如果您无法安装 Android SDK,无论出于何种原因,您都需要解析 Android 的二进制 XML 格式。在AndroidManifest.xml该APK拉链结构里面的文件是不是纯文本。

You would need to port a utility like AXMLParserfrom Java to PHP.

您需要将AXMLParser 等实用程序从 Java移植到 PHP。

回答by CHeil402

I've created a set of PHP functions that will find just the Version Code of an APK. This is based on the fact that the AndroidMainfest.xml file contains the version code as the first tag, and based on the axml (binary Android XML format) as described here

我创建了一组 PHP 函数,它们只会找到 APK 的版本代码。这是基于 AndroidMainfest.xml 文件包含版本代码作为第一个标签的事实,并基于 axml(二进制 Android XML 格式),如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++;
    }
}
    ?>

回答by Shing Kae

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

You will get a human readable form.

你会得到一个人类可读的表格。

sdkVersion:'14'
targetSdkVersion:'14'

Just look for aapt in your system if you have Android SDK installed. Mine is in:

如果您安装了 Android SDK,只需在您的系统中查找 aapt。我的是在:

<SDKPATH>/build-tools/19.0.3/aapt

回答by Six

The dump format is a little odd and not the easiest to work with. Just to expand on some of the other answers, this is a shell script that I am using to parse out name and version from APK files.

转储格式有点奇怪,而且不是最容易使用的。只是为了扩展其他一些答案,这是一个 shell 脚本,我用来从 APK 文件中解析出名称和版本。

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

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

If you just want the version then obviously it can be much simpler.

如果您只想要版本,那么显然它可以简单得多。

##代码##

Here are variations suitable for both gawk and mawk (a little less durable in case the dump format changes but should be fine):

以下是适用于 gawk 和 mawk 的变体(如果转储格式发生变化,那么耐用性稍差,但应该没问题):

##代码##

回答by habib

Use this in the CLI:

在 CLI 中使用它:

##代码##

You can use these commands in PHP using execor shell_exec.

您可以使用exec或在 PHP 中使用这些命令shell_exec