我需要弄清楚如何获取或制作Android应用程序的版本号。我需要在UI中显示内部版本号。

我必须使用AndroidManifest.xml吗?


当前回答

如果您使用Gradle插件/AndroidStudio,从0.7.0版起,版本代码和版本名称在BuildConfig中静态可用。确保导入应用程序的包,而不是另一个BuildConfig:

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

不需要Context对象!

还要确保在build.gradle文件中指定它们,而不是AndroidManifest.xml。

defaultConfig {
    versionCode 1
    versionName "1.0"
}

其他回答

Kotlin单层

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

Java一行程序

String versionCode = String.valueOf(BuildConfig.VERSION_CODE);
String versionName = String.valueOf(BuildConfig.VERSION_NAME);

确保将BuildConfig导入到类中。

有一些方法可以通过编程方式获取versionCode和versionName。

从PackageManager获取版本。这是大多数情况下的最佳方式。尝试{字符串versionName=packageManager.getPackageInfo(packageName,0).versionName;int versionCode=packageManager.getPackageInfo(packageName,0).versionCode;}catch(PackageManager.NameNotFoundException e){e.printStackTrace();}从生成的BuildConfig.java中获取它。但请注意,如果您在库中访问此值,它将返回使用此库的库版本,而不是应用程序版本。所以只能在非库项目中使用!字符串版本名称=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。因此,您的应用程序将在设备上具有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
    }
}

使用Gradle和BuildConfig

从BuildConfig获取VERSION_NAME

BuildConfig.VERSION_NAME

是的,现在就这么简单了。

它是否返回VERSION_NAME的空字符串?

如果您正在获取BuildConfig.VERSION_NAME的空字符串,请继续阅读。

我一直得到BuildConfig.VERSION_NAME的空字符串,因为我没有在Grade构建文件中设置versionName(我从Ant迁移到Gradle)。因此,以下是确保您通过Gradle设置VERSION_NAME的说明。

文件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}"
  }

}

注:这是大师杰克·沃顿的作品。

从AndroidManifest.xml中删除versionName和versionCode

而且,既然您现在已经在build.gradle文件中设置了versionName和versionCode,那么您也可以将它们从AndroidManifest.xml文件中删除(如果有的话)。

PackageInfo pinfo = null;
try {
    pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
}
catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}
int versionNumber = pinfo.versionCode;
String versionName = pinfo.versionName;

始终使用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());
}