我需要弄清楚如何为我的 Android 应用程序获取或制作内部版本号。我需要在 UI 中显示内部版本号。
我必须对 AndroidManifest.xml
做些什么吗?
int versionCode = BuildConfig.VERSION_CODE;
并获取版本名称 String versionName = BuildConfig.VERSION_NAME;
如果您使用的是 Gradle 插件/Android Studio,as of version 0.7.0、版本代码和版本名称在 BuildConfig
中静态可用。 确保您导入您的应用程序包,而不是另一个 BuildConfig
:
import com.yourpackage.BuildConfig;
...
int versionCode = BuildConfig.VERSION_CODE;
String versionName = BuildConfig.VERSION_NAME;
不需要上下文对象!
还要确保在您的 build.gradle
文件而不是 AndroidManifest.xml
中指定它们。
defaultConfig {
versionCode 1
versionName "1.0"
}
利用:
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
String version = pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
您可以使用此获取版本代码
int verCode = pInfo.versionCode;
getPackageInfo()
时不要忘记try... catch..
BuildConfig.VERSION_**
。
如果您只想要版本名称,则版本略短。
try{
String versionName = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
您需要两个部分:
安卓:版本代码
安卓:版本名称
versionCode 是一个数字,您提交给市场的应用程序的每个版本都需要有一个比上一个更高的数字。
VersionName 是一个字符串,可以是任何你想要的。这是您将应用程序定义为“1.0”或“2.5”或“2 Alpha EXTREME!”的地方。管他呢。
例子:
科特林:
val manager = this.packageManager
val info = manager.getPackageInfo(this.packageName, PackageManager.GET_ACTIVITIES)
toast("PackageName = " + info.packageName + "\nVersionCode = "
+ info.versionCode + "\nVersionName = "
+ info.versionName + "\nPermissions = " + info.permissions)
爪哇:
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();
android:versionCode
和 android:versionName
的官方描述可以在这里找到:developer.android.com/tools/publishing/…
this.getPackageName()
代表什么,您刚刚吐出的 0
不知道含义
使用 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}"
}
}
注意:这是来自高手的Jake Wharton。
从 AndroidManifest.xml 中删除 versionName 和 versionCode
由于您现在已经在 build.gradle
文件中设置了 versionName
和 versionCode
,因此您还可以从 AndroidManifest.xml
文件中删除它们(如果它们存在的话)。
versionName "1.2"
和 BuildConfig.VERSION_NAME
返回 empty
。 API> 21
versionCode
和 versionName
分别使用静态整数和静态字符串。只是因为某些工具(如 Code Push)试图通过解析您的 build.gradle
文件来获取您的版本号,并且它们无法填充动态值。
import com.package.name.BuildConfig;
或直接在代码中引用它,即使在项目库中,它也可以工作;)
这是一个干净的解决方案,基于 the solution of scottyab(由 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();
}
现在您在字符串 myVersionName
中收到了版本名称,您可以将其设置为 TextView 或您喜欢的任何内容。
// Set the version name to a TextView
TextView tvVersionName = (TextView) findViewById(R.id.tv_versionName);
tvVersionName.setText(myVersionName);
Throws PackageManager.NameNotFoundException if a package with the given name can not be found on the system.
。但是,我无法想象这样的场景!
使用以下获取应用程序版本或构建代码,用于通过版本代码识别 APK 文件。版本代码用于检测更新、发布等时的实际构建配置。
int versionCode = BuildConfig.VERSION_CODE;
版本名称用于显示开发序列的用户或开发人员。您可以根据需要添加任何类型的版本名称。
String versionName = BuildConfig.VERSION_NAME;
Kotlin 单行
val versionCode = BuildConfig.VERSION_CODE
val versionName = BuildConfig.VERSION_NAME
Java 单行
String versionCode = String.valueOf(BuildConfig.VERSION_CODE);
String versionName = String.valueOf(BuildConfig.VERSION_NAME);
确保将 BuildConfig
导入您的班级。
使用 BuildConfig 类:
String versionName = BuildConfig.VERSION_NAME;
int versionCode = BuildConfig.VERSION_CODE;
文件 build.gradle(应用程序)
defaultConfig {
applicationId "com.myapp"
minSdkVersion 19
targetSdkVersion 27
versionCode 17
versionName "1.0"
}
如果您使用的是 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 event 中,添加以下代码:
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
}
);
与 2020 年一样:从 API 28 (Android 9 (Pie)) 开始,"versionCode" 已弃用,因此我们可以使用 "longVersionCode"。
Kotlin 中的示例代码
val manager = context?.packageManager
val info = manager?.getPackageInfo(
context?.packageName, 0
)
val versionName = info?.versionName
val versionNumber = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
info?.longVersionCode
} else {
info?.versionCode
}
对于 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";
}
版本名称:BuildConfig.VERSION_NAME 版本代码:BuildConfig.VERSION_CODE
如果您想在 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" />
对于 Xamarin 用户,使用此代码获取版本名称和代码
版本名称:public string getVersionName(){ return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionName; } 版本代码: public string getVersionCode(){ return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionCode; }
不,您不需要对 AndroidManifest.xml 做任何事情
基本上,您的应用程序的版本名称和版本代码位于应用程序级别的 Gradle 文件中,在 defaultConfig 标记下:
defaultConfig {
versionCode 1
versionName "1.0"
}
注意:当您希望将应用程序上传到 playstore 时,它可以给任何名称作为版本名称,但如果该应用程序已在 play store 中,则版本代码必须与当前版本代码不同。
只需使用以下代码片段从应用程序的任何位置获取版本代码和版本名称:
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
String version = pInfo.versionName;
int verCode = pInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
始终使用 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());
}
下面是获取版本代码的方法:
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;
}
我已经通过使用 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);
}
}
}
有一些以编程方式获取 versionCode
和 versionName
的方法。
从 PackageManager 获取版本。这是大多数情况下的最佳方式。尝试 { String versionName = packageManager.getPackageInfo(packageName, 0).versionName; int versionCode = packageManager.getPackageInfo(packageName, 0).versionCode; } 捕捉 (PackageManager.NameNotFoundException e) { e.printStackTrace();从生成的 BuildConfig.java 中获取它。但请注意,如果您在库中访问此值,它将返回使用此库的库版本,而不是应用程序版本。所以只在非库项目中使用!字符串版本名称 = BuildConfig.VERSION_NAME; int versionCode = BuildConfig.VERSION_CODE;
除了在库项目中使用第二种方式外,还有一些细节。在新的 Android Gradle 插件 (3.0.0+) 中有一些 functionalities removed。所以,就目前而言,即为不同的口味设置不同的版本不能正常工作。
错误的方式:
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
收到 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
}
}
上面提到了这段代码,但这里再次全部包含在内。您需要一个 try/catch 块,因为它可能会抛出“NameNotFoundException”。
try {
String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
}
catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
我希望这可以为未来的人简化事情。 :)
这个问题有两种不同的情况,在任何答案中都没有正确解决。
场景 1:您没有使用模块
如果您不使用模块,您可以访问您的 BuildConfig 文件并立即获取您的版本代码:
val versionCode = BuildConfig.VERSION_CODE
这是有效的,因为这是您的应用程序级别的 BuildConfig 文件,因此它将包含对您的应用程序版本代码的引用
场景 2:您的应用程序有许多模块,并且您假装从模块层次结构中的较低模块访问应用程序版本代码
您有许多具有给定层次结构的模块是正常的,例如 app -> data -> domain -> ui 等。在这种情况下,如果您从“ui”模块访问 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
}
版本名称的方法类似。
对于不需要应用程序 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)
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) {
}
}
}
试试这个:
try
{
device_version = getPackageManager().getPackageInfo("com.google.android.gms", 0).versionName;
}
catch (PackageManager.NameNotFoundException e)
{
e.printStackTrace();
}
科特林示例:
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())
}
}
第一的:
import android.content.pm.PackageManager.NameNotFoundException;
然后使用这个:
PackageInfo pInfo = null;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
}
catch (NameNotFoundException e) {
e.printStackTrace();
}
String versionName = pInfo.versionName;
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;
}
}
内部片段使用示例。
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
PackageInfo pinfo = null;
try {
pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
}
catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
int versionNumber = pinfo.versionCode;
String versionName = pinfo.versionName;
不定期副业成功案例分享
com.android.tools.build:gradle:1.3.0