سؤال

أحاول إنشاء برنامج نصي PHP للحصول على إصدار التطبيق من ملف Android APK. يعد استخراج ملف XML من ملف APK (ZIP) ثم تحليل XML طريقة واحدة ، لكنني أعتقد أنه يجب أن يكون أبسط. شيء مثل دليل PHP, ، مثال رقم 3. أي أفكار كيفية إنشاء البرنامج النصي؟

هل كانت مفيدة؟

المحلول

إذا كان لديك جهاز Android SDK مثبتًا على الخادم ، فيمكنك استخدام PHP's 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 ، لأي سبب من الأسباب ، ستحتاج إلى تحسين تنسيق XML الثنائي من Android. ال AndroidManifest.xml ملف داخل بنية zip apk ليس نص عادي.

ستحتاج إلى منفذ أ فائدة مثل Axmlparser من جافا إلى 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'

فقط ابحث عن AAPT في نظامك إذا قمت بتثبيت Android SDK. منجم في:

<SDKPATH>/build-tools/19.0.3/aapt

تنسيق التفريغ غريب بعض الشيء وليس الأسهل للعمل معه. فقط للتوسع في بعض الإجابات الأخرى ، هذا نص 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] }'

فيما يلي اختلافات مناسبة لكل من 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 }'
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top