How to get the build/version number of your Android application?
我需要弄清楚如何为我的Android应用程序获取或生成一个内部版本号。我需要在用户界面中显示内部版本号。
我需要和
用途:
1 2 3 4 5 6 | try { PackageInfo pInfo = context.getPackageManager().getPackageInfo(getPackageName(), 0); String version = pInfo.versionName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } |
你可以通过这个得到版本代码
1 | int verCode = pInfo.versionCode; |
如果您使用的是Gradle插件/android studio,从0.7.0版开始,版本代码和版本名称在
1 2 3 4 | import com.yourpackage.BuildConfig; ... int versionCode = BuildConfig.VERSION_CODE; String versionName = BuildConfig.VERSION_NAME; |
不需要上下文对象!
还要确保在您的
1 2 3 4 | defaultConfig { versionCode 1 versionName"1.0" } |
稍微短一点的版本,如果您只需要版本名。
1 2 | String versionName = context.getPackageManager() .getPackageInfo(context.getPackageName(), 0).versionName; |
您需要两个部分:Android:版本代码安卓:版本名
versioncode是一个数字,你提交到市场上的应用程序的每个版本都需要一个比上一个更高的数字。
versionname是一个字符串,可以是任何您想要的字符串。在这里,您将应用程序定义为"1.0"或"2.5"或"2 alpha extreme!"或者什么。
例子:
Kotlin:
1 2 3 4 5 6 7 8 | val manager = this.packageManager val info = manager.getPackageInfo(this.packageName, PackageManager.GET_ACTIVITIES) toast("PackageName =" + info.packageName +" VersionCode =" + info.versionCode +" VersionName =" + info.versionName +" Permissions =" + info.permissions) |
爪哇:
1 2 3 4 5 6 7 8 9 | PackageManager manager = this.getPackageManager(); PackageInfo info = manager.getPackageInfo(this.getPackageName(), PackageManager.GET_ACTIVITIES); Toast.makeText(this, "PackageName =" + info.packageName +" VersionCode =" + info.versionCode +" VersionName =" + info.versionName +" Permissions =" + info.permissions, Toast.LENGTH_SHORT).show(); |
使用Gradle和BuildConfig从buildconfig获取版本名
1 | BuildConfig.VERSION_NAME |
是的,现在很容易。
它是否返回版本名称的空字符串?如果你得到的是一个空字符串,那么继续读下去。
我一直为
平地
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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}" } } |
注:这是杰克·沃顿的杰作。
从既然你已经在
1 2 | BuildConfig.VERSION_NAME //version name from your build file BuildConfig.VERSION_CODE //version code from your build file |
我不认为需要从包经理那里得到它
这里是一个干净的解决方案,基于Scottyab的解决方案(由Xavi编辑)。它演示了如何首先获取上下文(如果您的方法没有提供上下文的话)。此外,它使用多行而不是每行调用多个方法。这使您在调试应用程序时更加容易。
1 2 3 4 5 6 7 8 9 10 11 | 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(); } |
现在,您已经在字符串
1 2 3 | // set version name to a TextView TextView tvVersionName = (TextView) findViewById(R.id.tv_versionName); tvVersionName.setText(myVersionName); |
使用BuildConfig类
1 2 | String versionName = BuildConfig.VERSION_NAME; int versionCode = BuildConfig.VERSION_CODE; |
build.gradle(应用程序)
1 2 3 4 5 6 7 | defaultConfig { applicationId"com.myapp" minSdkVersion 19 targetSdkVersion 27 versionCode 17 versionName"1.0" } |
如果您正在使用PhoneGap,请创建自定义PhoneGap插件:
在应用程序包中创建新类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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中,添加以下行:
1 | <plugin name="PackageManagerPlugin" value="com.Demo.PackageManagerPlugin" /> |
在DeviceReady事件中,添加以下代码:
1 2 3 4 5 6 7 8 9 | 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属性:
1 2 3 4 5 6 7 8 | window.plugins.packageManager.getVersionName( function(versionName) { //do something with versionName }, function(errorMessage) { //do something with errorMessage } ); |
源于这里和这里。
一个非常简单的方法是:
1 | private String appVersion = BuildConfig.VERSION_NAME; |
下面是获取版本名称和版本代码的简单方法
1 2 | String version_name=BuildConfig.VERSION_NAME; int version_code=BuildConfig.VERSION_CODE; |
对于Xamarin用户,使用此代码获取版本名和代码
1)版本名称:
1 2 3 | public string getVersionName(){ return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionName; } |
2)版本代码:
1 2 3 | public string getVersionCode(){ return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionCode; } |
始终使用
1 2 3 4 5 6 7 8 9 | 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()); } |
以下是获取版本代码的方法:
1 2 3 4 5 6 7 8 9 10 | 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; } |
如果要在XML中使用它,请在渐变文件中添加以下行:
1 2 3 | applicationVariants.all { variant -> variant.resValue"string","versionName", variant.versionName } |
然后在XML上使用它,如下所示:
1 2 3 4 5 | <TextView android:gravity="center_horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/versionName" /> |
我已经通过使用偏好类解决了这个问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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); } } } |
有一些方法可以以编程方式获得
1 2 3 4 5 6 | try { String versionName = packageManager.getPackageInfo(packageName, 0).versionName; int versionCode = packageManager.getPackageInfo(packageName, 0).versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } |
1 2 | String versionName = BuildConfig.VERSION_NAME; int versionCode = BuildConfig.VERSION_CODE; |
除了在图书馆项目中使用第二种方法之外,还有一些细节。在新的Android Gradle插件(3.0.0+)中,一些功能被删除。所以,现在,也就是说,为不同的口味设置不同的版本是不正确的。
错误的方式:
1 2 3 4 5 6 7 8 9 | 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 } |
上面的代码将在
输出
1 2 3 4 5 6 7 8 9 10 11 | 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 } } |
上面提到的代码是分块的,但这里又包括了所有代码。您需要一个try/catch块,因为它可能会引发"nameNotFoundException"。
1 2 3 | try { String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; } catch (PackageManager.NameNotFoundException e) {e.printStackTrace();} |
我希望这样可以简化一些事情。:)
但是,一些不需要应用程序UI的buildconfig信息的人希望使用这些信息来设置CI作业配置,或者像我这样的其他人。
只要成功构建项目,在项目目录下就会有一个自动生成的文件buildconfig.java。
工作区/build/generated/source/buildconfig/调试发布/包/buildconfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 | /** * 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脚本或其他工具拆分您需要的信息。下面是一个例子:
1 2 3 4 5 6 | 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) |
请原谅我的英语能力有限,但希望这有帮助。
不,您不需要对androidmanifest.xml做任何事情。
基本上,您的应用程序的版本名称和版本代码位于应用程序级渐变文件中的defaultconfig标记下:
1 2 3 4 | defaultConfig { versionCode 1 versionName"1.0" } |
注意:当您希望在PlayStore中上载应用程序时,可以将任何名称作为版本名,但如果该应用程序已在PlayStore中,则版本代码必须与当前版本代码不同。
只需使用以下代码段从应用程序中的任何位置获取版本代码和版本名:
1 2 3 4 5 6 7 | try { PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); String version = pInfo.versionName; int verCode = pInfo.versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } |
试试这个:
1 2 3 4 5 6 7 8 | try { device_version = getPackageManager().getPackageInfo("com.google.android.gms", 0).versionName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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 { @Override public 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) { } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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; } } |
第一:
1 | import android.content.pm.PackageManager.NameNotFoundException; |
然后用这个:
1 2 3 4 5 6 7 | PackageInfo pInfo = null; try { pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); } catch (NameNotFoundException e) { e.printStackTrace(); } String versionName = pInfo.versionName; |
内部片段使用示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 usefull 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 USEFULL WITH THAT |
对于api 28,packageinfo.versioncode已弃用,请使用以下代码:
1 2 3 4 5 6 7 8 9 10 | 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 2 3 4 5 6 7 8 | PackageInfo pinfo = null; try { pinfo = getPackageManager().getPackageInfo(getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } int versionNumber = pinfo.versionCode; String versionName = pinfo.versionName; |
因为我只需要获取版本代码并检查应用程序是否更新,如果更新了,我必须启动PlayStore才能获得更新。我是这样做的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class CheckForUpdate { public static final String ACTION_APP_VERSION_CHECK="app-version-check"; public static void launchPlayStoreApp(Context context) { final String appPackageName = context.getPackageName(); // getPackageName() from Context or Activity object 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类,使用共享首选项保存了版本代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class PreferenceUtils { // this is for version code private 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 app versioncode sharedPreferencesAppVersionCode=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 default version code is 0 } } |
1 2 3 4 5 6 7 8 | 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(); } |