你如何获取你的Android应用程序的构建/版本号?

1574
我需要弄清楚如何为我的Android应用程序获取或生成一个版本号。我需要在用户界面中显示版本号。
我需要在AndroidManifest.xml文件中做一些操作吗?

1
重复的问题:https://dev59.com/1m855IYBdhLWcg3wNhd1 - Idemax
37
获取版本号使用int versionCode = BuildConfig.VERSION_CODE;,获取版本名使用String versionName = BuildConfig.VERSION_NAME; - Lukas
39个回答

24
如果你正在使用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
    }
);

源自这里这里


11
问题不是关于PhoneGap的。你的回答可能会让人们感到困惑。 - likebobby
8
@BobbyJ 在这个问题、标题或标签中都没有明确说明这个问题是关于本地应用程序的。当我搜索答案时,这就是Google所显示的内容,如果当时可以看到这个信息,会让我节省数小时的时间。 - Sean Hall
谢谢Hall72215。如果真的没有其他方法可以获得自己的版本号,我会很高兴的...如果可能的话,我宁愿避免使用插件! - Magnus Smith
@MagnusSmith,除非PhoneGap/Cordova已将其添加到其内置功能中。 - Sean Hall
1
在这个例子中,你可以看到使用第三方解决方案创建应用程序是多么的愚蠢。当你自己从头开始编写时,只需要几行代码就可以了。 - Codebeat

20
这个问题有两种不同的情况,在任何答案中都没有得到适当的解决。
情况1:您没有使用模块
如果您没有使用模块,您可以访问BuildConfig文件,并立即获取您的版本代码:
val versionCode = BuildConfig.VERSION_CODE 

这是有效的,因为这是您的应用程序级别的BuildConfig文件,因此它将包含对应用程序版本代码的引用。
情景2:您的应用程序有许多模块,并且您希望从模块层次结构中的较低模块访问应用程序版本代码。
您拥有许多模块并具有给定的层次结构,例如app -> data -> domain -> ui等是很正常的。在这种情况下,如果您从"ui"模块访问BuildConfig文件,它将不会给您提供应用程序版本代码的引用,而是给您提供该模块的版本代码。
为了获取应用程序版本代码,您可以使用以下给定的代码:
首先是一个获取PackageInfo的扩展函数。
@Suppress("DEPRECATION")
fun Context.getPackageInfo(): PackageInfo {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
    } else {
        packageManager.getPackageInfo(packageName, 0)
    }
}

获取版本代码的扩展功能
fun Context.getVersionCode(): Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    getPackageInfo().longVersionCode.toInt()
} else {
    getPackageInfo().versionCode
}

版本名称的方法类似:
fun Context.getVersionName(): String = try {
    getPackageInfo().versionName
} catch (e: PackageManager.NameNotFoundException) {
    ""
}

1
不错,但它应该是上下文的扩展,而不是活动。 - htafoya
2
截至2023年,这是唯一正确的答案。 - undefined

20

不,你不需要对 AndroidManifest.xml 做任何操作

基本上,您应用程序的版本名称和版本代码会在 应用级别 Gradle 文件defaultConfig 标签下:

defaultConfig {
   versionCode 1
   versionName "1.0"
}

注意:当您希望将应用上传到应用商店时,可以任何名称作为版本名称,但如果此应用已在应用商店中,则版本代码必须与当前版本代码不同。

只需使用以下代码片段即可从应用程序的任何位置获取版本代码版本名称

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

2
versionCode 在 API 28 中已被废弃。根据文档所述,请使用 longVersionCode 替代;https://developer.android.com/reference/android/content/pm/PackageInfo.html#versionCode - Dan Abnormal

20

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

16
版本名称:BuildConfig.VERSION_NAME 版本代码:BuildConfig.VERSION_CODE

15

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

1
我在我的xml中遇到了错误:无法解析符号'@string/versionName'。 - RJB

14

对于Xamarin用户,可以使用以下代码获取版本名称和代码

  1. Version Name:

     public string getVersionName(){
         return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionName;
     }
    
  2. Version code:

     public string getVersionCode(){
         return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionCode;
     }
    

10

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

为什么它必须总是这样呢? - Peter Mortensen
你也可以声明要抛出异常,如果你不想在当前的方法中捕获它。 - The incredible Jan

9

有一些方法可以通过编程获取versionCodeversionName

  1. Get version from PackageManager. This is the best way for most cases.

     try {
         String versionName = packageManager.getPackageInfo(packageName, 0).versionName;
         int versionCode = packageManager.getPackageInfo(packageName, 0).versionCode;
     } catch (PackageManager.NameNotFoundException e) {
         e.printStackTrace();
     }
    
  2. Get it from generated BuildConfig.java. But notice, that if you'll access this values in library it will return library version, not apps one, that uses this library. So use only in non-library projects!

     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中的值,但是如果您没有在default配置中设置版本,则从PackageManager中将收到0null。因此,您的应用程序在设备上将具有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
    }
}

9

以下是获取版本代码的方法:

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

3
更好的方法 - BuildConfig.VERSION_CODE - Jaydev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接