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

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

我必须用AndroidManifest.xml做些什么吗?

822297 次浏览

你需要两个部分:

  • 系统版本
  • 安卓版本

versionCode是一个数字,您提交给市场的应用程序的每个版本都需要有一个高于上一个版本的数字。

VersionName是一个字符串,可以是您想要的任何内容。这是您将应用定义为“1.0”或“2.5”或“2 Alpha EXTREME!”或其他什么的地方。

示例:

静态编程语言:

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

Java:

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

稍短的版本,如果你只是想要版本名称。

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

用途:

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

你可以用这个来获取版本代码

int verCode = pInfo.versionCode;

如果您使用的是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";
@Overridepublic 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" />

设备就绪事件中,添加以下代码:

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

来自这里这里

这是一个基于的解决方案清洁溶液(由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();}

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

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

如果您使用的是Gradle插件/Android Studio,版本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 1versionName "1.0"}

始终使用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 blockLog.e(TAG, "Exception Version Name: " + e.getLocalizedMessage());}

使用Gradle和BuildConfig

从BuildConfig获取VERSION_NAME

BuildConfig.VERSION_NAME

是的,现在就这么简单。

是否为VERSION_NAME返回空字符串?

如果您为BuildConfig.VERSION_NAME获得一个空字符串,请继续阅读。

我一直得到BuildConfig.VERSION_NAME的空字符串,因为我没有在我的等级构建文件中设置versionName(我从蚂蚁迁移到Gradle)。所以,这里是确保你通过Gradle设置VERSION_NAME的说明。

文件build.gradle

def versionMajor = 3def versionMinor = 0def versionPatch = 0def versionBuild = 0 // Bump for dogfood builds, public betas, etc.
android {
defaultConfig {versionCode versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
versionName "${versionMajor}.${versionMinor}.${versionPatch}"}
}

注意:这是来自精湛的Jake Wharton

AndroidManifest.xml中删除versionNameversionCode

由于您现在已经在build.gradle文件中设置了versionNameversionCode,如果它们存在,您也可以从AndroidManifest.xml文件中删除它们。

第一:

import android.content.pm.PackageManager.NameNotFoundException;

然后使用这个:

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

我有解决这个通过使用首选项类。

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);}}}
package com.sqisland.android.versionview;
import android.app.Activity;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.os.Bundle;import android.widget.TextView;
public class MainActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
TextView textViewversionName = (TextView) findViewById(R.id.text);
try {PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);textViewversionName.setText(packageInfo.versionName);
}catch (PackageManager.NameNotFoundException e) {
}}}

对于不需要应用程序UI的BuildConfig信息的人,但是想要使用此信息来设置CI作业配置或其他人,比如我:

只要您成功构建项目,项目目录下就会有一个自动生成的文件BuildConfig.java

//配置包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)

如果您想在XML内容上使用它,请在Gradle文件中添加以下行:

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

然后在您的XML内容上使用它,如下所示:

<TextViewandroid:gravity="center_horizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/versionName" />

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

public String getAppVersion() {String versionCode = "1.0";try {versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;} catch (PackageManager.NameNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return versionCode;}

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

试试这个:

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

上面提到了这段代码,但在这里它再次全部包括在内。你需要一个try/cat块,因为它可能会抛出“NameNotFoundException”。

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

我希望这能简化路上的人的事情。:)

内部片段用法示例。

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

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

  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 = versionCodevariant.mergedFlavor.versionName = versionName}

上面的代码将正确设置BuildConfig中的值,但从PackageManager开始,如果您没有在default配置中设置版本,您将收到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 = versionCodeoutput.versionNameOverride = versionName}}
PackageInfo pinfo = null;try {pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);}catch (PackageManager.NameNotFoundException e) {e.printStackTrace();}int versionNumber = pinfo.versionCode;String versionName = pinfo.versionName;

使用BuildConfig类:

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

文件build.gradle(应用程序)

defaultConfig {applicationId "com.myapp"minSdkVersion 19targetSdkVersion 27versionCode 17versionName "1.0"}
try {PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);String versionName = packageInfo.versionName;int versionCode = packageInfo.versionCode;//binding.tvVersionCode.setText("v" + packageInfo.versionName);}catch (PackageManager.NameNotFoundException e) {e.printStackTrace();}

由于我只需要获取版本代码并检查应用程序是否更新,如果是,我必须启动Play商店以获得更新。我是这样做的。

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 objectfinal 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 codeprivate  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 versioncodesharedPreferencesAppVersionCode = 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}}

不你不需要对AndroidManifest.xml做任何事

基本上,您的应用程序的版本名称和版本代码位于应用级Gradle文件中的默认配置标签下:

defaultConfig {versionCode 1versionName "1.0"}

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

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

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

对于API 28(android9(Pie)),不建议使用PackageInfo.version代码,因此请使用以下代码:

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

使用以下命令获取用于通过版本代码识别APK文件的应用版本或构建代码。版本代码用于在更新、发布等时检测实际的构建配置。

int versionCode = BuildConfig.VERSION_CODE;

版本名称用于显示开发序列的用户或开发人员。您可以根据需要添加任何类型的版本名称。

String versionName = BuildConfig.VERSION_NAME;

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

与2020年一样:从API 28(android9(Pie))开始,"versionCode"不建议使用因此我们可以使用"long版本编码"

静态编程语言的示例代码

val manager = context?.packageManagerval info = manager?.getPackageInfo(context?.packageName, 0)
val versionName = info?.versionNameval versionNumber = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {info?.longVersionCode} else {info?.versionCode}

静态编程语言示例:

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

静态编程语言单行程序

val versionCode = BuildConfig.VERSION_CODEval versionName = BuildConfig.VERSION_NAME

Java一句话

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

确保将BuildConfig导入到您的类中。

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

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

场景1:您没有使用模块

如果您不使用模块,您可以访问您的BuildConfig文件并立即获得您的版本代码:

val versionCode = BuildConfig.VERSION_CODE

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

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

您通常会有许多具有给定层次结构的模块,例如应用程序->数据->域->用户界面等,在这种情况下,如果您从“用户界面”模块访问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) {""}

就写这个。

xml代码

<TextViewandroid:id="@+id/appversion"android:layout_width="wrap_content"android:layout_height="wrap_content"/>

初始化文本视图的变量

TextView appversion;

将文本视图ID设置为变量

appversion = findViewById(R.id.appversion);

这是显示应用程序版本BuildConfig.VERSION_NAME的主要代码,只需将其用作字符串值

textview.setText("v"+BuildConfig.VERSION_NAME);

非常简单:

   val manufacturer = Build.MANUFACTURERval model = Build.MODELval version = Build.VERSION.SDK_INTval versionRelease = Build.VERSION.RELEASE
    Log.e("TAG","VERSION.RELEASE {" + Build.VERSION.RELEASE + "}");Log.e("TAG","\nVERSION.INCREMENTAL {" + Build.VERSION.INCREMENTAL + "}");Log.e("TAG","\nVERSION.SDK {" + Build.VERSION.SDK + "}");Log.e("TAG","\nBOARD {" + Build.BOARD + "}");Log.e("TAG","\nBRAND {" + Build.BRAND + "}");Log.e("TAG","\nDEVICE {" + Build.DEVICE + "}");Log.e("TAG","\nFINGERPRINT {" + Build.FINGERPRINT + "}");Log.e("TAG","\nHOST {" + Build.HOST + "}");Log.e("TAG","\nID {" + Build.ID + "}");

感谢https://stackoverflow.com/a/40421709/2828651