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

我必须使用AndroidManifest.xml吗?


当前回答

如果要在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" />

其他回答

如果您只需要版本名称,请稍微缩短版本。

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

Kotlin示例:

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())
    }
}

对于不需要应用程序UI的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)

对于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";
}

在这个问题中有两种不同的情况,在任何答案中都没有得到正确的解决。

场景1:您没有使用模块

如果您没有使用模块,则可以访问BuildConfig文件,并立即使用以下命令获取版本代码:

val versionCode = BuildConfig.VERSION_CODE 

这是有效的,因为这是应用程序级别的BuildConfig文件,因此它将包含对应用程序版本代码的引用

场景2:您的应用程序有许多模块,您假装从模块层次结构中的较低模块访问应用程序版本代码

对于您来说,有许多具有给定层次结构的模块是正常的,例如app->data->domain->ui等。在这种情况下,如果您从“ui”模块访问BuildConfig文件,它将不会向您提供应用程序版本代码的引用,而是该模块的版本代码。

为了获得应用程序版本代码,您可以使用给定的kotlin扩展函数:

fun Activity.getVersionCode(): Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    packageManager.getPackageInfo(packageName, 0).longVersionCode.toInt()
} else {
    packageManager.getPackageInfo(packageName, 0).versionCode
}

版本名称的方法类似:

fun Activity.getVersionName(): String = try {
    packageManager?.getPackageInfo(packageName, 0)?.versionName ?: ""
} catch (e: PackageManager.NameNotFoundException) {
    ""
}