Получить Android .apk-файл VersionName или VersionCode БЕЗ установки apk

Как я могу получить программный код версии или имя версии apk из файла AndroidManifest.xml после загрузки и без его установки.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="xxx.xx.xxx" android:versionCode="1" android:versionName="1.1" > 

Например, я хочу проверить, загружена ли новая версия моей службы IIS после ее установки на устройство, если не новая версия, которую я не хочу устанавливать.

После этого работала для меня из командной строки:

 aapt dump badging myapp.apk 

ПРИМЕЧАНИЕ. Файл aapt.exe находится в подпапке build-tools SDK. Например:

 <sdk_path>/build-tools/23.0.2/aapt.exe 
 final PackageManager pm = getPackageManager(); String apkName = "example.apk"; String fullPath = Environment.getExternalStorageDirectory() + "/" + apkName; PackageInfo info = pm.getPackageArchiveInfo(fullPath, 0); Toast.makeText(this, "VersionCode : " + info.versionCode + ", VersionName : " + info.versionName , Toast.LENGTH_LONG).show(); 

Если вы используете версию 2.2 и выше для Android Studio, то в Android Studio используйте BuildAnalyze APK, затем выберите файл AndroidManifest.xml.

Теперь я могу успешно получить версию файла APK из своих двоичных XML-данных.

В этом разделе я получил ключ к моему ответу (я также добавил свою версию кода Ribo): как анализировать файл AndroidManifest.xml внутри пакета .apk

Кроме того, вот код XML-анализа, который я написал, специально для получения версии:

XML-анализ

 /** * Verifies at Conductor APK path if package version if newer * * @return True if package found is newer, false otherwise */ public static boolean checkIsNewVersion(String conductorApkPath) { boolean newVersionExists = false; // Decompress found APK's Manifest XML // Source: https://stackoverflow.com/questions/2097813/how-to-parse-the-androidmanifest-xml-file-inside-an-apk-package/4761689#4761689 try { if ((new File(conductorApkPath).exists())) { JarFile jf = new JarFile(conductorApkPath); InputStream is = jf.getInputStream(jf.getEntry("AndroidManifest.xml")); byte[] xml = new byte[is.available()]; int br = is.read(xml); //Tree tr = TrunkFactory.newTree(); String xmlResult = SystemPackageTools.decompressXML(xml); //prt("XML\n"+tr.list()); if (!xmlResult.isEmpty()) { InputStream in = new ByteArrayInputStream(xmlResult.getBytes()); // Source: http://developer.android.com/training/basics/network-ops/xml.html XmlPullParser parser = Xml.newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(in, null); parser.nextTag(); String name = parser.getName(); if (name.equalsIgnoreCase("Manifest")) { String pakVersion = parser.getAttributeValue(null, "versionName"); //NOTE: This is specific to my project. Replace with whatever is relevant on your side to fetch your project's version String curVersion = SharedData.getPlayerVersion(); int isNewer = SystemPackageTools.compareVersions(pakVersion, curVersion); newVersionExists = (isNewer == 1); } } } } catch (Exception ex) { android.util.Log.e(TAG, "getIntents, ex: "+ex); ex.printStackTrace(); } return newVersionExists; } 

Сравнение версий (рассматривается как SystemPackageTools.compareVersions в предыдущем фрагменте) ПРИМЕЧАНИЕ. Этот код вдохновлен следующим тестом: Эффективный способ сравнения строк версии в Java

 /** * Compare 2 version strings and tell if the first is higher, equal or lower * Source: https://stackoverflow.com/questions/6701948/efficient-way-to-compare-version-strings-in-java * * @param ver1 Reference version * @param ver2 Comparison version * * @return 1 if ver1 is higher, 0 if equal, -1 if ver1 is lower */ public static final int compareVersions(String ver1, String ver2) { String[] vals1 = ver1.split("\\."); String[] vals2 = ver2.split("\\."); int i=0; while(i<vals1.length&&i<vals2.length&&vals1[i].equals(vals2[i])) { i++; } if (i<vals1.length&&i<vals2.length) { int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i])); return diff<0?-1:diff==0?0:1; } return vals1.length<vals2.length?-1:vals1.length==vals2.length?0:1; } 

Надеюсь, это поможет.

  EditText ET1 = (EditText) findViewById(R.id.editText1); PackageInfo pinfo; try { pinfo = getPackageManager().getPackageInfo(getPackageName(), 0); String versionName = pinfo.versionName; ET1.setText(versionName); //ET2.setText(versionNumber); } catch (NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

Для сценария обновления конкретным альтернативным подходом может быть веб-служба, которая доставляет текущий номер версии и проверяет, что вместо загрузки всего apk просто для проверки его версии. Это сэкономит некоторую полосу пропускания, будет немного более результативным (гораздо быстрее загружать, чем apk, если весь apk не требуется большую часть времени) и намного проще реализовать.

В простейшей форме у вас может быть простой текстовый файл на вашем сервере … http://some-place.com/current-app-version.txt

Внутри этого текстового файла есть что-то вроде

 3.1.4 

А затем загрузить этот файл и проверить его на установленную версию.

Создание более продвинутого решения для этого будет заключаться в том, чтобы внедрить надлежащий веб-сервис и запустить api-вызов при запуске, который может вернуть некоторый json, то есть http://api.some-place.com/versionCheck :

 { "current_version": "3.1.4" } 
Intereting Posts
Возможно ли иметь ScrollingViewBehavior в сочетании с поведением Snackbar? Включить MIC в genymotion / Любой другой хороший эмулятор Android Android: Мое приложение поддерживает 0 устройств Android: невозможно выполнить операцию / ClassNotFoundException Кинжал 2: @ Компонент.Builder пропускает сеттеры для необходимых модулей или компонентов: ` Android: Выровняйте кнопку в правом нижнем углу экрана с помощью FrameLayout? Как программно удалить уведомление из панели уведомлений в android? Изменение цвета строки состояния при изменении фрагмента Установка minHeight в RelativeLayout, отключает alignBaseline? AutoLink с событием onClick Повторная установка броска исключения IllegalArgumentException для асинхронного вызова DELETE FormUrlEncoded Как быстро загрузить WebView и добавить к нему индикатор выполнения Как улучшить производительность рендеринга пинг-понга (для размытия) в OpenGL ES Новый Intent () запускает новый экземпляр с Android: launchMode = "singleTop" ContentObserver onChange