如何获取 Android 应用程序的构建/版本号?
Posted
技术标签:
【中文标题】如何获取 Android 应用程序的构建/版本号?【英文标题】:How can you get the build/version number of your Android application? 【发布时间】:2011-09-29 10:22:07 【问题描述】:我需要弄清楚如何为我的 android 应用程序获取或制作内部版本号。我需要在 UI 中显示内部版本号。
我必须对AndroidManifest.xml
做点什么吗?
【问题讨论】:
不确定,但我认为您可以通过解析 AndroidManifest.xml 文件来获取它。 复制:***.com/questions/4471025/… 获取版本代码使用int versionCode = BuildConfig.VERSION_CODE;
并获取版本名称String versionName = BuildConfig.VERSION_NAME;
【参考方案1】:
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
导入您的班级。
【讨论】:
这种方法的缺点是,如果您在库模块中有此代码,它将显示库的版本,而不是应用程序本身。 在这种情况下,OP 请求了一个 Android 应用程序,但非常感谢关于库的注释,竖起大拇指【参考方案2】:如果您只需要版本名称,则版本略短。
try
String versionName = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionName;
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();
return false;
【讨论】:
优秀。这可能应该被 NameNotFoundException 的 try/catch 包围。 +1 我已经实施了您的解决方案,效果很好!但是,这个解决方案应该像 Igor 所说的那样被 try and catch 包围,并且将每个方法调用放在单独的行上而不是调用 context.methodName().subMethod().anotherSubMethod() 等是一种很好的做法(例如,用于调试) . 在一条线上。因此我提供了一个更清洁的解决方案below 这是正确的解决方案,谢谢 ;) 但是,正如 @IgorGanapolsky 所建议的,它需要用 try / catch 包围:) 对于那些使用 Gradle 的人 - 有一个更简单的解决方案。请参阅下面的答案。 @Erwinus 我完全不同意使用通用异常来捕获这样的东西的想法。更细粒度的异常表明开发人员对可能的错误的理解。【参考方案3】:版本名称:BuildConfig.VERSION_NAME 版本代码:BuildConfig.VERSION_CODE
【讨论】:
【参考方案4】:Kotlin 示例:
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())
【讨论】:
谢谢你,亚历山大!去年我在一个项目中使用了旧的 BuildConfig 代码,但它不再工作了,所以我改用了你的代码。像魅力一样工作。【参考方案5】:与 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
【讨论】:
【参考方案6】:对构建系统很有用:您的 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":
]
【讨论】:
【参考方案7】:使用以下内容获取应用版本或构建代码,用于通过版本代码识别 APK 文件。版本代码用于检测更新、发布等时的实际构建配置。
int versionCode = BuildConfig.VERSION_CODE;
版本名称用于显示开发序列的用户或开发人员。您可以根据需要添加任何类型的版本名称。
String versionName = BuildConfig.VERSION_NAME;
【讨论】:
在所有答案中,这是最简单的方法。当你可以用一行做同样的事情时,为什么要用 10 多行代码来做。我不明白。【参考方案8】:对于 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";
【讨论】:
【参考方案9】:不,你不需要对 AndroidManifest.xml 做任何事情
基本上,您的应用的版本名称和版本代码位于 应用级 Gradle 文件中,位于 defaultConfig 标签下:
defaultConfig
versionCode 1
versionName "1.0"
注意:当你想上传一个应用到playstore时,它可以给任何名字作为版本名称,但是如果这个应用已经在play中,版本代码必须与当前版本代码不同商店。
只需使用以下代码 sn-p 即可从应用中的任何位置获取版本代码和版本名称:
try
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
String version = pInfo.versionName;
int verCode = pInfo.versionCode;
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();
【讨论】:
versionCode 在 API 28 中已弃用。如文档中所述,请改用 longVersionCode; developer.android.com/reference/android/content/pm/…【参考方案10】:因为我只需要获取版本代码并检查应用程序是否已更新,如果是,我必须启动 playstore 以获取更新。我是这样做的。
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
【讨论】:
【参考方案11】: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();
【讨论】:
相对于之前的答案,您的答案是什么?请不要重复答案 解释一下。【参考方案12】:使用 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"
【讨论】:
【参考方案13】:PackageInfo pinfo = null;
try
pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();
int versionNumber = pinfo.versionCode;
String versionName = pinfo.versionName;
【讨论】:
【参考方案14】:有一些方法可以通过编程方式获取versionCode
和versionName
。
从PackageManager
获取版本。这是大多数情况下的最佳方式。
try
String versionName = packageManager.getPackageInfo(packageName, 0).versionName;
int versionCode = packageManager.getPackageInfo(packageName, 0).versionCode;
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();
从生成的BuildConfig.java
中获取它。但请注意,如果您在库中访问此值,它将返回使用此库的库版本,而不是应用程序版本。所以仅在非库项目中使用!
String versionName = 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
【讨论】:
【参考方案15】:内部 Fragment 使用示例。
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
【讨论】:
在发布答案之前,您应该查看其他答案。例如对于上下文你正在做 getActivity.getApplicationContext 如果你在片段中,那么我可以理解,但如果你在活动中,我认为你不需要调用 getActivity 在我的例子中,我是为 Fragment 制作的。代码在 onCreate 内部使用 如果你在 Fragment 中使用它为什么不直接使用 getContext()?【参考方案16】:上面提到了这段代码,但这里再次全部包含在内。您需要一个 try/catch 块,因为它可能会抛出“NameNotFoundException”。
try
String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();
我希望这可以为以后的人简化事情。 :)
【讨论】:
您也可以再次抛出异常,而不是 try/catch。【参考方案17】:试试这个:
try
device_version = getPackageManager().getPackageInfo("com.google.android.gms", 0).versionName;
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();
【讨论】:
【参考方案18】: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;
【讨论】:
解释一下。【参考方案19】: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;
【讨论】:
【参考方案20】:如果您想在 XML 内容上使用它,请在您的 Gradle 文件中添加以下行:
applicationVariants.all variant ->
variant.resValue "string", "versionName", variant.versionName
然后像这样在你的 XML 内容上使用它:
<TextView
android:gravity="center_horizontal"
android:layout_
android:layout_
android:text="@string/versionName" />
【讨论】:
我的 xml 中出现错误:无法解析符号 '@string/versionName'【参考方案21】:对于不需要应用程序 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)
【讨论】:
【参考方案22】: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)
【讨论】:
嗨,@donmj。如果您使用的是 Android 设备的非官方 root。我的事,你会需要的。这是我的方法。 感谢@Durul Dalkanat 的帮助 :)。 解释一下。【参考方案23】:我通过使用 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);
【讨论】:
这里问题的 Preference 的目的是什么? PackageManager 没有它也可以工作。【参考方案24】:第一:
import android.content.pm.PackageManager.NameNotFoundException;
然后使用这个:
PackageInfo pInfo = null;
try
pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
catch (NameNotFoundException e)
e.printStackTrace();
String versionName = pInfo.versionName;
【讨论】:
没有人有时间这样做。【参考方案25】:使用 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
文件中删除(如果它们存在)。
【讨论】:
只要您从应用程序项目访问 BuildConfig,而不是应用程序项目中使用的库,这将非常有效。否则,您将获得库项目的 BuildConfig,而不是应用程序。 @JohnCummings 有趣...没想到。 根本不工作,versionName "1.2"
和BuildConfig.VERSION_NAME
返回empty
。 API > 21
作为后续,我们实际上停止使用此方法,而只支持versionCode
和versionName
的静态整数和静态字符串。只是因为某些工具(例如 Code Push)试图通过解析您的 build.gradle
文件来获取您的版本号,并且它们无法填充动态值。
@JohnCummings 如果您 import com.package.name.BuildConfig;
或直接在代码中引用它,即使在项目库中也可以使用它;)【参考方案26】:
始终使用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 如果您不想在当前方法中捕获它,您也可以声明要抛出的异常。【参考方案27】:这是一个干净的解决方案,基于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);
【讨论】:
你觉得NNFE真的可以扔吗?在包管理器中找不到正在运行的应用程序会很奇怪:) 我同意这可能很奇怪,但这是此方法的默认例外 - 请参阅 API:它说Throws PackageManager.NameNotFoundException if a package with the given name can not be found on the system.
。但是,我无法想象这样的场景!【参考方案28】:
你需要两个部分:
android:versionCode android:versionNameversionCode 是一个数字,您提交给市场的应用的每个版本都需要有一个比上一个更高的数字。
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)
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();
【讨论】:
Android官方对android:versionCode
和android:versionName
的描述可以在这里找到:developer.android.com/tools/publishing/…
this 在这种情况下是 Context .ie Activity, Service .etc
粘贴一些示例代码有助于解释参数的含义....尽管每个人都可以理解this.getPackageName()
代表什么0
你只是吐了没有任何含义的线索
Android Studio 声称 versionCode 已弃用
@RomanGherta 从 API 28 开始。如果您使用更少的代码(或 8 年前编写此答案时)编写代码,您仍然应该很高兴。这里的另一个答案有更新的方法。【参考方案29】:
用途:
try
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
String version = pInfo.versionName;
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();
你可以通过这个来获取版本代码
int verCode = pInfo.versionCode;
【讨论】:
@Felix 您不能在上下文之外调用 getPackageManager(),因此可能需要 getApplicationContext()(或传递的上下文)。 如果您在无法传递上下文的静态方法中需要这个数字怎么办?我的设计不好? 别忘了try... catch..
getPackageInfo()
@Gubatron 我在下面的回答允许静态检索这些值。
如果您只想获取应用程序的版本,这是两个复杂的问题。您应该按照建议的here 使用BuildConfig.VERSION_**
。【参考方案30】:
如果您使用的是 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"
【讨论】:
请注意,对于多模块项目,在特定模块中查询时可能会得到意想不到的结果。可能最好将其绑定到主应用程序/活动类中的某个全局名称空间中。 如果您想在库模块中使用它来获取有关应用程序的信息,这不起作用。库模块中没有 BuildConfig 文件 @dumazy。库模块可以有一个 BuildConfig,但您不会获得应用程序的构建信息。您将获得图书馆的信息。 我想这个方法的空字符串结果是由于在编写这段代码时导入了错误的BuildConfig。当我将它粘贴到我的项目中时,我有很多选项可供我使用的所有库和模块选择。我刚刚导入了与我自己的包名关联的那个 这不适用于com.android.tools.build:gradle:1.3.0
以上是关于如何获取 Android 应用程序的构建/版本号?的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式在 Android 设备中获取设备 (AOSP) 内部版本号?