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

我必须使用AndroidManifest.xml吗?


当前回答

有一些方法可以通过编程方式获取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
    }
}

其他回答

对构建系统有用:有一个用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": {}
    }
]

这是一个干净的解决方案,基于scottyab(由哈维编辑)的解决方案。它显示了如果方法没有提供上下文,如何首先获取上下文。此外,它使用多行而不是每行调用多个方法。这使您在调试应用程序时更容易。

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

现在您在StringmyVersionName中收到了版本名,您可以将其设置为TextView或任何您喜欢的内容。。

// Set the version name to a TextView
TextView tvVersionName = (TextView) findViewById(R.id.tv_versionName);
tvVersionName.setText(myVersionName);

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())
    }
}
private String GetAppVersion() {
    try {
        PackageInfo _info = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
        return _info.versionName;
    }
    catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        return "";
    }
}

private int GetVersionCode() {
    try {
        PackageInfo _info = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
        return _info.versionCode;
    }
    catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        return -1;
    }
}

如果您使用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"
}