Как узнать номер сборки / версии вашего Android-приложения?

Мне нужно выяснить, как получить или сделать номер сборки для моего приложения Android. Мне нужен номер сборки для отображения в пользовательском интерфейсе.

Мне нужно что-то делать с AndroidManifest.xml?


person Fahad Ali Shaikh    schedule 06.01.2011    source источник
comment
Не уверен, но я думаю, что вы можете получить его, проанализировав файл AndroidManifest.xml.   -  person Sunit Kumar Gupta    schedule 06.07.2011
comment
Дублировано: stackoverflow.com/questions/4471025/   -  person xpto    schedule 26.09.2016
comment
Чтобы получить код версии, используйте int versionCode = BuildConfig.VERSION_CODE; и чтобы получить имя версии String versionName = BuildConfig.VERSION_NAME;   -  person Lukas    schedule 21.12.2019


Ответы (31)


Использовать:

try {
    PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
    String version = pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}

И вы можете получить код версии, используя этот

int verCode = pInfo.versionCode;
person plus-    schedule 06.07.2011
comment
@Felix вы не можете вызвать getPackageManager () вне контекста, поэтому может потребоваться getApplicationContext () (или переданный контекст). - person Sver; 24.09.2012
comment
Если вы получили значение null, проверьте файл AndroidManifest: возможно, отсутствует android: versionName. - person 18446744073709551615; 24.05.2013
comment
что, если вам нужно это число внутри некоторого статического метода, в котором вы не можете передать контекст? плохой дизайн с моей стороны? - person Gubatron; 31.08.2013
comment
@Gubatron, если вы не можете передать контекст, я бы сказал вашу часть :) вы можете просто управлять номером версии в статическом конечном поле ... - person Warpzit; 26.09.2013
comment
Итак, как получить последнюю версию Playstore? - person Ahmad Arslan; 24.06.2014
comment
@ArslanAhmad Найдите имя пакета магазина воспроизведения и замените его на getPackageName(). - person Kayla; 03.07.2014
comment
И не забывайте try... catch.., когда getPackageInfo() - person anticafe; 07.07.2014
comment
Добавьте нулевую проверку для pInfo. - person AndroidGuy; 12.08.2014
comment
Для статического контекста сохраните getapplicationContext () в классе, который расширяет Application (убедитесь, что вы объявили этот класс в манифесте в теге приложения) и используйте его во всем своем приложении. - person Isham; 08.09.2014
comment
@Gubatron, мой ответ ниже позволяет получать эти значения статически. - person Sam Dozor; 07.10.2014
comment
Как вы можете сравнить две версии, значение до и после кода версии в Android? - person EngineSense; 14.12.2015
comment
Если вы хотите получить только версию приложения, это два скомпилированных. Вы должны использовать BuildConfig.VERSION_**, как это предлагается здесь. - person Timo Bähr; 20.06.2016
comment
@AndroidGuy нам это действительно нужно? Если запущенное приложение не может получить информацию о собственном пакете, я бы сказал, что сбой очень уместен. - person TWiStErRob; 12.03.2017
comment
@TWiStErRob На практике вы также можете перехватить TransactionTooLargeException. Параллельное выполнение getPackageName часто вызывает исключение TransactionTooLargeException. - person Carlos Parker; 08.08.2017
comment
Этот ответ ужасно устарел. - person Konrad Morawski; 07.11.2017
comment
Просто нужно импортировать android.content.pm.PackageManager; import android.content.pm.PackageInfo; - person malajisi; 20.01.2018
comment
pInfo.versionCode устарел в API 28 - person MHSFisher; 14.10.2018
comment
склонен к ошибкам и нуждается в попытках поймать - person Aishik kirtaniya; 13.01.2020

Если вы используете плагин Gradle / Android Studio, версии 0.7.0, код версии и название версии доступны статически в BuildConfig. Убедитесь, что вы импортируете пакет своего приложения, а не другой BuildConfig:

import com.yourpackage.BuildConfig;
...
int versionCode = BuildConfig.VERSION_CODE;
String versionName = BuildConfig.VERSION_NAME;

Объект контекста не требуется!

Также не забудьте указать их в вашем build.gradle файле вместо AndroidManifest.xml.

defaultConfig {
    versionCode 1
    versionName "1.0"
}
person Sam Dozor    schedule 14.01.2014
comment
Остерегайтесь, для многомодульного проекта вы можете получить неожиданные результаты при запросе этого в конкретном модуле. Вероятно, лучше всего привязать это к некоторому глобальному пространству имен в вашем основном классе Application / Activity. - person inder; 14.01.2015
comment
Есть ли способ получить код версии моего приложения, которое находится в игровом магазине? - person AndroidManifester; 18.04.2015
comment
Это не сработает, если вы хотите использовать его в модуле библиотеки для получения информации о приложении. В библиотечном модуле нет файла BuildConfig - person dumazy; 08.10.2015
comment
@dumazy. для модуля библиотеки может быть BuildConfig, но вы не получите информацию о сборке приложения. Вы будете получать информацию о библиотеке. - person John Cummings; 02.12.2015
comment
Я полагаю, что результат этого метода в пустой строке вызван тем, что при написании этого кода был импортирован неправильный файл BuildConfig. Когда я вставил его в свой проект, у меня было множество вариантов на выбор для всех библиотек, которые я использовал, а также для модулей. Я только что импортировал тот, который связан с моим собственным именем пакета - person Kaloyan Roussev; 07.12.2015
comment
это не работает с com.android.tools.build:gradle:1.3.0 - person Kushal; 18.02.2016
comment
Это не работает, если ваша сборка gradle использует versionNameOverride для динамической установки версии. Он покажет все, что было установлено вашим gradle как versionCode, но это может отличаться от значения, хранящегося в вашем выпуске. В случае versionName Это может также отличаться от того, что показано в списке магазинов. - person tobltobs; 06.11.2019

Версия немного короче, если вам просто нужно название версии.

try{
    String versionName = context.getPackageManager()
    .getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        return false;
}
person scottyab    schedule 26.04.2011
comment
Превосходно. Вероятно, это должно быть окружено try / catch для NameNotFoundException. - person IgorGanapolsky; 06.12.2012
comment
+1 Я реализовал ваше решение, которое отлично работает! Однако это решение должно быть окружено попыткой поймать, как сказал Игорь, И рекомендуется (например, для отладки) помещать каждый вызов метода в отдельную строку вместо вызова context.methodName (). SubMethod (). AnotherSubMethod () и т. Д. .. в одной строке. Поэтому я предоставил более чистое решение ниже - person Michael; 20.12.2013
comment
Это правильное решение, спасибо;) Но, как предлагает @IgorGanapolsky, его нужно окружить try / catch :) - person andrea.rinaldi; 20.06.2014
comment
для тех, кто использует Gradle - есть более простое решение. Смотрите мой ответ ниже. - person Sam Dozor; 01.07.2014
comment
@ Игорь Ганапольский: Просто используйте Exception вместо NameNotFoundException, чтобы перехватить все возможные исключения, это сделает ваш код / ​​программу более надежной. - person Codebeat; 23.05.2015
comment
@Erwinus Я полностью не согласен с идеей использования универсального исключения для отлова подобных вещей. Более подробные исключения демонстрируют понимание разработчиками возможных ошибок. - person IgorGanapolsky; 26.05.2015
comment
@IgorGanapolsky: Это правда, но что делать, если программист этого не понимает? Я не думаю, что пользователь приложения ценит какие-либо исключения. Во всех разновидностях Android есть такое изменение, что происходит что-то неожиданное, и будет глупо, если что-то простое, например, отключит ваше приложение. Если это произойдет, вы можете предположить, что программист не понимает, чего хочет пользователь, потому что этого очень легко избежать. Кроме того, вы можете регистрировать исключения, если хотите знать, что не так, есть описание. Независимо от того, какое исключение, необработанное исключение неверно. - person Codebeat; 26.05.2015
comment
В каких случаях может возникнуть исключение? Если приложение запущено и ищет собственную версию, есть ли вероятность, что PackageManager ее не найдет? - person nsk; 04.03.2021

Вам понадобятся две части:

  • android: versionCode
  • android: versionName

versionCode - это число, и каждая версия приложения, которую вы представляете на рынок, должна иметь большее число, чем предыдущая.

VersionName - это строка, которая может быть чем угодно. Здесь вы определяете свое приложение как 1.0, 2.5 или 2 Alpha EXTREME! или что-то еще.

Пример:

Котлин:

val manager = this.packageManager
val info = manager.getPackageInfo(this.packageName, PackageManager.GET_ACTIVITIES)
toast("PackageName = " + info.packageName + "\nVersionCode = "
            + info.versionCode + "\nVersionName = "
            + info.versionName + "\nPermissions = " + info.permissions)

Джава:

PackageManager manager = this.getPackageManager();
PackageInfo info = manager.getPackageInfo(this.getPackageName(), PackageManager.GET_ACTIVITIES);
Toast.makeText(this,
     "PackageName = " + info.packageName + "\nVersionCode = "
       + info.versionCode + "\nVersionName = "
       + info.versionName + "\nPermissions = " + info.permissions, Toast.LENGTH_SHORT).show();
person Merkidemis    schedule 08.02.2011
comment
Официальное описание Android для android:versionCode и android:versionName можно найти здесь: developer.android.com/ инструменты / публикация / - person Jeffro; 19.07.2012
comment
это в данном случае - Context .ie Activity, Service .etc. - person peterchaula; 28.06.2017
comment
когда вы вставляете какой-то образец кода, это полезно для объяснения значения параметров .... хотя каждый может понять, что this.getPackageName() представляет 0, на который вы просто плюете, понятия не имеют о значении - person Rafael Lima; 02.08.2018
comment
Android Studio утверждает, что версия versionCode устарела - person Roman Gherta; 19.04.2019
comment
@RomanGherta Это с API 28. Если вы пишете код, используя что-то меньшее (или 8 лет назад, когда был написан этот ответ), вам все равно должно быть хорошо. Другой ответ здесь - обновленный метод. - person Merkidemis; 01.05.2019
comment
дает мне предупреждение: versionCode устарел (на kotlin). Что мне использовать вместо этого? - person gundrabur; 01.03.2020

Использование Gradle и BuildConfig

Получение VERSION_NAME из BuildConfig

BuildConfig.VERSION_NAME

Ага, теперь это так просто.

Возвращает ли он пустую строку для VERSION_NAME?

Если вы получаете пустую строку для BuildConfig.VERSION_NAME, продолжайте читать.

Я продолжал получать пустую строку для BuildConfig.VERSION_NAME, потому что я не устанавливал versionName в моем файле сборки Grade (я перешел с Ant в Gradle). Итак, вот инструкции по настройке VERSION_NAME через Gradle.

Файл build.gradle

def versionMajor = 3
def versionMinor = 0
def versionPatch = 0
def versionBuild = 0 // Bump for dogfood builds, public betas, etc.

android {

  defaultConfig {
    versionCode versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild

    versionName "${versionMajor}.${versionMinor}.${versionPatch}"
  }

}

Примечание. Это от искусного Джейка Уортона.

Удаление versionName и versionCode из AndroidManifest.xml

А поскольку вы сейчас установили versionName и versionCode в файле build.gradle, вы также можете удалить их из своего AndroidManifest.xml файла, если они там есть.

person Joshua Pinter    schedule 05.02.2015
comment
Это отлично работает, пока вы обращаетесь к BuildConfig из проекта приложения, а не из библиотеки, используемой в проекте приложения. В противном случае вы получите BuildConfig для проекта библиотеки, а не для приложения. - person John Cummings; 02.12.2015
comment
@JohnCummings Интересно ... не думал об этом. - person Joshua Pinter; 03.12.2015
comment
Совсем не работает, versionName "1.2" и BuildConfig.VERSION_NAME возвращают empty. API ›21 - person Sojtin; 10.08.2016
comment
В дальнейшем мы фактически перестали использовать этот метод в пользу статического целого числа и статической строки для versionCode и versionName соответственно. Только потому, что некоторые инструменты, такие как Code Push, пытаются получить номер вашей версии путем анализа вашего build.gradle файла и не могут заполнить динамическое значение. - person Joshua Pinter; 16.03.2018
comment
@JoshuaPinter PackageManager действительно самый безопасный вариант. Если вы используете переопределения кода версии для разбиения, константа BuildConfig по-прежнему сохраняет исходное (хотя и измененное) значение. - person Eugen Pechanec; 16.04.2018
comment
Я использовал это решение, но обнаружил недостаток. Если у вас есть 2.6.23, а в следующий раз вы хотите обновить 2.7.0, вы получите код версии меньше, чем раньше. Поэтому я применил это: versionCode versionMajor * 10000 + versionMinor * 100 + versionPatch versionPatch от 0 до 100 - person 0x131313; 28.01.2019
comment
@JohnCummings работает, если вы import com.package.name.BuildConfig; или напрямую ссылаетесь на него в коде, даже в библиотеке проекта;) - person SkyzohKey; 01.06.2021

Вот чистое решение, основанное на решение scottyab (отредактировал Xavi). Он показывает, как сначала получить контекст, если он не предоставляется вашим методом. Кроме того, он использует несколько строк вместо вызова нескольких методов в каждой строке. Это упрощает отладку приложения.

Context context = getApplicationContext(); // or activity.getApplicationContext()
PackageManager packageManager = context.getPackageManager();
String packageName = context.getPackageName();

String myVersionName = "not available"; // initialize String

try {
    myVersionName = packageManager.getPackageInfo(packageName, 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}

Теперь, когда вы получили название версии в String myVersionName, вы можете установить его как TextView или что угодно.

// Set the version name to a TextView
TextView tvVersionName = (TextView) findViewById(R.id.tv_versionName);
tvVersionName.setText(myVersionName);
person Michael    schedule 21.08.2013
comment
Вы думаете, что NNFE действительно можно бросить? Было бы странно не найти в диспетчере пакетов работающее приложение :) - person TWiStErRob; 17.04.2016
comment
Я согласен с вами, что это может быть странно, но это исключение по умолчанию для этого метода - см. API: там написано Throws PackageManager.NameNotFoundException if a package with the given name can not be found on the system.. Однако я не мог представить себе такого сценария! - person Michael; 17.04.2016

Используйте следующее, чтобы получить версию приложения или код сборки, который используется для идентификации файла APK по его коду версии. Код версии используется для определения фактической конфигурации сборки во время обновления, публикации и т. Д.

int versionCode = BuildConfig.VERSION_CODE;

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

String versionName = BuildConfig.VERSION_NAME;
person Rohit Patil    schedule 10.05.2019
comment
Из всех ответов это самый простой способ. Если вы можете сделать то же самое с одной строкой, зачем делать это с более чем 10 строками кода. Я этого не понимаю. - person Amir Dora.; 15.03.2021

Используйте класс BuildConfig:

String versionName = BuildConfig.VERSION_NAME;
int versionCode = BuildConfig.VERSION_CODE;

Файл build.gradle (приложение)

defaultConfig {
    applicationId "com.myapp"
    minSdkVersion 19
    targetSdkVersion 27
    versionCode 17
    versionName "1.0"
}
person Velayutham M    schedule 25.07.2018

Kotlin однострочные

val versionCode = BuildConfig.VERSION_CODE
val versionName = BuildConfig.VERSION_NAME

Обязательно импортируйте BuildConfig в свой класс.

Однострочники Java

String versionCode = String.valueOf(BuildConfig.VERSION_CODE);
String versionName = String.valueOf(BuildConfig.VERSION_NAME);
person Gastón Saillén    schedule 07.01.2020
comment
Недостатком этого подхода является то, что если у вас есть этот код в модуле библиотеки, он покажет вам версию библиотеки, а не само приложение. - person Eugene Krivenja; 16.10.2020
comment
В этом случае OP запросил приложение для Android, но большое спасибо за это замечание о библиотеках, палец вверх - person Gastón Saillén; 16.10.2020

Если вы используете PhoneGap, создайте собственный плагин PhoneGap:

Создайте новый класс в пакете вашего приложения:

package com.Demo; //replace with your package name

import org.json.JSONArray;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;

import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
import com.phonegap.api.PluginResult.Status;

public class PackageManagerPlugin extends Plugin {

    public final String ACTION_GET_VERSION_NAME = "GetVersionName";

    @Override
    public PluginResult execute(String action, JSONArray args, String callbackId) {
        PluginResult result = new PluginResult(Status.INVALID_ACTION);
        PackageManager packageManager = this.ctx.getPackageManager();

        if(action.equals(ACTION_GET_VERSION_NAME)) {
            try {
                PackageInfo packageInfo = packageManager.getPackageInfo(
                                              this.ctx.getPackageName(), 0);
                result = new PluginResult(Status.OK, packageInfo.versionName);
            }
            catch (NameNotFoundException nnfe) {
                result = new PluginResult(Status.ERROR, nnfe.getMessage());
            }
        }

        return result;
    }
}

В plugins.xml добавьте следующую строку:

<plugin name="PackageManagerPlugin" value="com.Demo.PackageManagerPlugin" />

В свое событие deviceready добавьте следующий код:

var PackageManagerPlugin = function() {

};
PackageManagerPlugin.prototype.getVersionName = function(successCallback, failureCallback) {
    return PhoneGap.exec(successCallback, failureCallback, 'PackageManagerPlugin', 'GetVersionName', []);
};
PhoneGap.addConstructor(function() {
    PhoneGap.addPlugin('packageManager', new PackageManagerPlugin());
});

Затем вы можете получить атрибут versionName, выполнив:

window.plugins.packageManager.getVersionName(
    function(versionName) {
        //do something with versionName
    },
    function(errorMessage) {
        //do something with errorMessage
    }
);

Получено на основе здесь и .

person Sean Hall    schedule 12.03.2012
comment
Вопрос был не в PhoneGap. Ваш ответ может просто сбить с толку людей. - person likebobby; 27.06.2012
comment
@BobbyJ Нигде в вопросе, заголовке или тегах не указано, что вопрос касался собственного приложения. Это то, что пришло в голову в Google, когда я искал ответ, и сэкономило бы мне несколько часов. - person Sean Hall; 27.06.2012
comment
Спасибо Hall72215. Я буду этому рад ... неужели нет другого способа получить собственный номер версии? Я бы предпочел избегать плагинов, если это возможно! - person Magnus Smith; 10.12.2012
comment
@MagnusSmith Нет, если PhoneGap / Cordova не добавила его в свои встроенные функции. - person Sean Hall; 10.12.2012
comment
В этом примере вы можете увидеть, насколько глупо использовать сторонние решения для создания приложений. Когда вы писали его сами с нуля, код составлял всего пару строк. - person Codebeat; 20.05.2015

Как в 2020 году: с API 28 (Android 9 (Pie)), versionCode устарел, поэтому мы можем использовать longVersionCode.

Пример кода на Котлине

val manager = context?.packageManager
val info = manager?.getPackageInfo(
    context?.packageName, 0
)

val versionName = info?.versionName
val versionNumber = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                        info?.longVersionCode
                    } else {
                        info?.versionCode
                    }
person Mayank Sharma    schedule 26.08.2019

Для API 28 (Android 9 (Pie)) PackageInfo.versionCode равен устарело, поэтому используйте этот код ниже:

Context context = getApplicationContext();
PackageManager manager = context.getPackageManager();
try {
    PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
    myversionName = info.versionName;
    versionCode = (int) PackageInfoCompat.getLongVersionCode(info);
}
catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
    myversionName = "Unknown-01";
}
person Amir jodat    schedule 21.02.2019

Если вы хотите использовать его в XML-контенте, добавьте следующую строку в свой файл Gradle:

applicationVariants.all { variant ->
    variant.resValue "string", "versionName", variant.versionName
}

А затем используйте его в своем XML-контенте следующим образом:

<TextView
        android:gravity="center_horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/versionName" />
person Irfan Raza    schedule 26.05.2016
comment
Я получаю в своем xml ошибку: не удается разрешить символ '@ string / versionName' - person RJB; 11.09.2019

Для пользователей Xamarin используйте этот код, чтобы получить название версии и код.

  1. Название версии:

     public string getVersionName(){
         return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionName;
     }
    
  2. Код версии:

     public string getVersionCode(){
         return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionCode;
     }
    
person Tushar patel    schedule 25.09.2016

Нет, с AndroidManifest.xml ничего делать не нужно.

Обычно название и код версии вашего приложения находятся внутри файла уровня приложения Gradle в теге defaultConfig:

defaultConfig {
   versionCode 1
   versionName "1.0"
}

Примечание. Если вы хотите загрузить приложение в игровой магазин, оно может дать любое имя в качестве имени версии, но код версии должен отличаться от кода текущей версии, если это приложение уже находится в магазине воспроизведения. < / em>

Просто используйте следующий фрагмент кода, чтобы получить код версии и название версии из любого места вашего приложения:

try {
    PackageInfo pInfo =   context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
    String version = pInfo.versionName;
    int verCode = pInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}
person Monir Zzaman    schedule 21.02.2019
comment
versionCode устарел в API 28. Как указано в документации, используйте вместо этого longVersionCode; developer.android.com/reference/android/content/pm/ - person Dan Abnormal; 31.01.2020

Всегда делайте это с try catch блоком:

String versionName = "Version not found";

try {
    versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
    Log.i(TAG, "Version Name: " + versionName);
} catch (NameNotFoundException e) {
    // TODO Auto-generated catch block
    Log.e(TAG, "Exception Version Name: " + e.getLocalizedMessage());
}
person Pratik Butani    schedule 28.05.2014
comment
Почему так должно быть всегда? - person Peter Mortensen; 02.12.2020

Вот способ получения кода версии:

public String getAppVersion() {
    String versionCode = "1.0";
    try {
        versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
    } catch (PackageManager.NameNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return versionCode;
}
person Gevaria Purva    schedule 30.06.2016
comment
Лучший способ - BuildConfig.VERSION_CODE - person Jaydev; 06.07.2016

Я решил эту проблему с помощью класса Preference.

package com.example.android;

import android.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;

public class VersionPreference extends Preference {
    public VersionPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        String versionName;
        final PackageManager packageManager = context.getPackageManager();
        if (packageManager != null) {
            try {
                PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
                versionName = packageInfo.versionName;
            } catch (PackageManager.NameNotFoundException e) {
                versionName = null;
            }
            setSummary(versionName);
        }
    }
}
person Shubham Gupta    schedule 02.03.2015

Есть несколько способов получить versionCode и versionName программно.

  1. Получите версию от PackageManager. Это лучший способ для большинства случаев.

     try {
         String versionName = packageManager.getPackageInfo(packageName, 0).versionName;
         int versionCode = packageManager.getPackageInfo(packageName, 0).versionCode;
     } catch (PackageManager.NameNotFoundException e) {
         e.printStackTrace();
     }
    
  2. Получите это из сгенерированного BuildConfig.java. Но обратите внимание, что если вы получите доступ к этим значениям в библиотеке, он вернет версию библиотеки, а не приложения, которые используют эту библиотеку. Так что используйте только в небиблиотечных проектах!

     String versionName = BuildConfig.VERSION_NAME;
     int versionCode = BuildConfig.VERSION_CODE;
    

Есть некоторые детали, кроме использования второго способа в библиотечном проекте. В новом плагине Android Gradle (3.0.0+) некоторые функциональные возможности удалены. Итак, на данный момент установка разных версий для разных вкусов не работает правильно.

Неправильный способ:

applicationVariants.all { variant ->
    println('variantApp: ' + variant.getName())

    def versionCode = {SOME_GENERATED_VALUE_IE_TIMESTAMP}
    def versionName = {SOME_GENERATED_VALUE_IE_TIMESTAMP}

    variant.mergedFlavor.versionCode = versionCode
    variant.mergedFlavor.versionName = versionName
}

Приведенный выше код правильно установит значения в BuildConfig, но с PackageManager вы получите 0 и null, если вы не установили версию в default конфигурации. Таким образом, ваше приложение будет иметь 0 код версии на устройстве.

Есть обходной путь - установить версию для выходного apk файла вручную:

applicationVariants.all { variant ->
    println('variantApp: ' + variant.getName())

    def versionCode = {SOME_GENERATED_VALUE_IE_TIMESTAMP}
    def versionName = {SOME_GENERATED_VALUE_IE_TIMESTAMP}

    variant.outputs.all { output ->
        output.versionCodeOverride = versionCode
        output.versionNameOverride = versionName
    }
}
person mohax    schedule 31.10.2017

название версии: BuildConfig.VERSION_NAME код версии: BuildConfig.VERSION_CODE

person D.A.C. Nupun    schedule 18.01.2021

Этот код был упомянут выше по частям, но здесь он снова включен полностью. Вам нужен блок try / catch, потому что он может вызвать исключение NameNotFoundException.

try {
    String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
}
catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}

Я надеюсь, что это упростит жизнь кому-то в будущем. :)

person Jeff.H    schedule 14.02.2017

Для тех, кому не нужна информация BuildConfig для пользовательского интерфейса приложения, но желающих использовать эту информацию для настройки CI конфигурация задания или другие, такие как я:

Если вы успешно создаете проект, в каталоге вашего проекта есть автоматически сгенерированный файл BuildConfig.java.

{WORKSPACE} / build / generated / source / buildConfig / {debug | release} / {PACKAGE} /BuildConfig.java

/**
* Automatically generated file. DO NOT MODIFY
*/
package com.XXX.Project;

public final class BuildConfig {
    public static final boolean DEBUG = Boolean.parseBoolean("true");
    public static final String APPLICATION_ID = "com.XXX.Project";
    public static final String BUILD_TYPE = "debug";
    public static final String FLAVOR = "";
    public static final int VERSION_CODE = 1;
    public static final String VERSION_NAME = "1.0.0";
}

Разделите необходимую информацию с помощью скрипта Python или других инструментов. Вот пример:

import subprocess
# Find your BuildConfig.java
_BuildConfig = subprocess.check_output('find {WORKSPACE} -name BuildConfig.java', shell=True).rstrip()

# Get the version name
_Android_version = subprocess.check_output('grep -n "VERSION_NAME" ' + _BuildConfig, shell=True).split('"')[1]
print('Android version: ’ + _Android_version)
person JasonChiu    schedule 20.01.2016

Попробуй это:

try
{
    device_version =  getPackageManager().getPackageInfo("com.google.android.gms", 0).versionName;
}
catch (PackageManager.NameNotFoundException e)
{
    e.printStackTrace();
}
person Heenali Lakhani    schedule 03.02.2017

Первый:

import android.content.pm.PackageManager.NameNotFoundException;

а затем используйте это:

PackageInfo pInfo = null;
try {
     pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
} 
catch (NameNotFoundException e) {
     e.printStackTrace();
}

String versionName = pInfo.versionName;
person meduvigo    schedule 27.02.2015
comment
ни у кого нет на это времени. - person BlaShadow; 15.10.2015

Пример использования внутреннего фрагмента.

import android.content.pm.PackageManager;
.......

private String VersionName;
private String VersionCode;
.......


Context context = getActivity().getApplicationContext();

/* Getting application version name and code */
try
{
     VersionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;

     /* I find it useful to convert vervion code into String,
        so it's ready for TextViev/server side checks
     */

     VersionCode = Integer.toString(context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode);
}
catch (PackageManager.NameNotFoundException e)
{
     e.printStackTrace();
}

// Do something useful with that
person Sapphire91140    schedule 16.07.2017
comment
Вы должны посмотреть другие ответы, прежде чем публиковать свой ответ. например для контекста вы выполняете getActivity.getApplicationContext, если вы находитесь во фрагменте, тогда я могу понять, но если вы находитесь в действии, я не думаю, что вам нужно будет вызывать getActivity - person Sahil Manchanda; 16.07.2017
comment
В моем случае я сделал это для фрагмента. Код используется внутри onCreate - person Sapphire91140; 17.07.2017

Поскольку мне нужно было получить только код версии и проверить, обновлено ли приложение или нет, если да, мне пришлось запустить игровой магазин, чтобы его обновить. Я так и сделал.

public class CheckForUpdate {

    public static final String ACTION_APP_VERSION_CHECK = "app-version-check";

    public static void launchPlayStoreApp(Context context)
    {
        // getPackageName() from Context or Activity object
        final String appPackageName = context.getPackageName();
        try {
            context.startActivity(new Intent(Intent.ACTION_VIEW,
                                  Uri.parse("market://details?id=" + appPackageName)));
        }
        catch (android.content.ActivityNotFoundException anfe) {
            context.startActivity(new Intent(Intent.ACTION_VIEW,
                                  Uri.parse("https://play.google.com/store/apps/details?id=" +
                                             appPackageName)));
        }
    }

    public static int getRemoteVersionNumber(Context context)
    {
        int versionCode = 0;
        try {
            PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            String version = pInfo.versionName;
            versionCode = pInfo.versionCode;
        }
        catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode;
    }

}

Затем я сохранил код версии, используя общие предпочтения, создав класс util.

public class PreferenceUtils {

    // This is for version code
    private  final String APP_VERSION_CODE = "APP_VERSION_CODE";
    private  SharedPreferences sharedPreferencesAppVersionCode;
    private SharedPreferences.Editor editorAppVersionCode;
    private static Context mContext;

    public PreferenceUtils(Context context)
    {
        this.mContext = context;
        // This is for the app versioncode
        sharedPreferencesAppVersionCode = mContext.getSharedPreferences(APP_VERSION_CODE,MODE_PRIVATE);
        editorAppVersionCode = sharedPreferencesAppVersionCode.edit();
    }

    public void createAppVersionCode(int versionCode) {

        editorAppVersionCode.putInt(APP_VERSION_CODE, versionCode);
        editorAppVersionCode.apply();
    }

    public int getAppVersionCode()
    {
        return sharedPreferencesAppVersionCode.getInt(APP_VERSION_CODE,0); // As the default version code is 0
    }
}
person Ishwor Khanal    schedule 13.12.2018

Пример Котлина:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.act_signin)

    packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES).apply {
        findViewById<TextView>(R.id.text_version_name).text = versionName
        findViewById<TextView>(R.id.text_version_code).text =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) "$longVersionCode" else "$versionCode"
    }

    packageManager.getApplicationInfo(packageName, 0).apply{
        findViewById<TextView>(R.id.text_build_date).text =
            SimpleDateFormat("yy-MM-dd hh:mm").format(java.io.File(sourceDir).lastModified())
    }
}
person Alexander Gavriliuk    schedule 28.08.2019

Полезно для систем сборки: есть файл, созданный с вашим файлом APK с именем output.json, который содержит массив информации для каждого сгенерированного файла APK, включая versionName и versionCode.

Например,

[
    {
        "apkInfo": {
            "baseName": "x86-release",
            "enabled": true,
            "filterName": "x86",
            "fullName": "86Release",
            "outputFile": "x86-release-1.0.apk",
            "splits": [
                {
                    "filterType": "ABI",
                    "value": "x86"
                }
            ],
            "type": "FULL_SPLIT",
            "versionCode": 42,
            "versionName": "1.0"
        },
        "outputType": {
            "type": "APK"
        },
        "path": "app-x86-release-1.0.apk",
        "properties": {}
    }
]
person Tom    schedule 11.08.2019

person    schedule
comment
Привет, @donmj. Если вы используете официальный root-доступ для Android-устройства. Я вещь, которая вам понадобится. Это мой подход. - person Durul Dalkanat; 10.11.2015
comment
Спасибо за помощь @Durul Dalkanat :). - person donmj; 10.11.2015
comment
Объяснение было бы в порядке. - person Peter Mortensen; 02.12.2020

person    schedule
comment
Объяснение было бы в порядке. - person Peter Mortensen; 02.12.2020

person    schedule
comment
Что ваш ответ добавляет к предыдущим ответам? Пожалуйста, не повторяйте ответы - person David Miguel; 30.01.2019
comment
Объяснение было бы в порядке. - person Peter Mortensen; 02.12.2020