我需要弄清楚如何获取或制作Android应用程序的版本号。我需要在UI中显示内部版本号。
我必须使用AndroidManifest.xml吗?
我需要弄清楚如何获取或制作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
}
}
其他回答
使用Gradle和BuildConfig
从BuildConfig获取VERSION_NAME
BuildConfig.VERSION_NAME
是的,现在就这么简单了。
它是否返回VERSION_NAME的空字符串?
如果您正在获取BuildConfig.VERSION_NAME的空字符串,请继续阅读。
我一直得到BuildConfig.VERSION_NAME的空字符串,因为我没有在Grade构建文件中设置versionName(我从Ant迁移到Gradle)。因此,以下是确保您通过Gradle设置VERSION_NAME的说明。
文件build.gradle
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}"
}
}
注:这是大师杰克·沃顿的作品。
从AndroidManifest.xml中删除versionName和versionCode
而且,既然您现在已经在build.gradle文件中设置了versionName和versionCode,那么您也可以将它们从AndroidManifest.xml文件中删除(如果有的话)。
我已经通过使用Preference类解决了这个问题。
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);
}
}
}
由于我只需要获取版本代码并检查应用程序是否更新,如果是,我必须启动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 object
final 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 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 the 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 the default version code is 0
}
}
对于不需要应用程序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)
Use:
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
String version = pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
您可以使用以下命令获取版本代码
int verCode = pInfo.versionCode;