如何以编程方式查找 Android 版本名称?

Posted

技术标签:

【中文标题】如何以编程方式查找 Android 版本名称?【英文标题】:How to find the Android version name programmatically? 【发布时间】:2012-05-19 20:11:20 【问题描述】:

我写这样的代码来查找android版本

String version=Build.VERSION.RELEASE;

通过使用此代码,我得到了版本号,但我想要版本名称。 如何获取版本名称?

【问题讨论】:

【参考方案1】:

如前所述,反思似乎是这个问题的关键。不需要 StringBuilder 和额外的格式,添加它只是为了说明用法。

import java.lang.reflect.Field;
...

StringBuilder builder = new StringBuilder();
builder.append("android : ").append(Build.VERSION.RELEASE);

Field[] fields = Build.VERSION_CODES.class.getFields();
for (Field field : fields) 
    String fieldName = field.getName();
    int fieldValue = -1;

    try 
        fieldValue = field.getInt(new Object());
     catch (IllegalArgumentException e) 
        e.printStackTrace();
     catch (IllegalAccessException e) 
        e.printStackTrace();
     catch (NullPointerException e) 
        e.printStackTrace();
    

    if (fieldValue == Build.VERSION.SDK_INT) 
        builder.append(" : ").append(fieldName).append(" : ");
        builder.append("sdk=").append(fieldValue);
    


Log.d(LOG_TAG, "OS: " + builder.toString());

在我的 4.1 模拟器上,我得到以下输出:

D/MainActivity( 1551): OS: android : 4.1.1 : JELLY_BEAN : sdk=16

享受吧!

【讨论】:

使用自己的静态名称数组并按索引查找会更简单、更安全。 对于可以为每个版本定期更新的应用来说,静态数组可能是理想的选择,但对于许多 Android 版本可能不会更新的项目,这可能仍然是首选解决方案。跨度> 它只返回 P,而不是 Pie。【参考方案2】:

优化的代码,这将工作:

import java.lang.reflect.Field;

Field[] fields = Build.VERSION_CODES.class.getFields();
String osName = fields[Build.VERSION.SDK_INT + 1].getName();
Log.d("Android OsName:",osName);

【讨论】:

仅供参考:对于 Android 8.1,这会产生:O_MR1 是的,Android 返回名称取决于定义的变量developer.android.com/reference/android/os/… 这让我最近遇到了麻烦,因为 '+ 1' 使它跑出了字段数组的末尾。我不明白这里的推理。我最后添加了一个检查,看看 SDK_INT + 1 是否太大。如果是,我使用“字段”中的最后一个条目,但我真的不知道这是否是最好的做法。在下面的 cmets 中有更多关于此的内容。 现在不安全。可能导致崩溃。我们可以使用构建一个字符串数组/映射并手动映射版本号/字符串名称。【参考方案3】:

API 28 (Android Pie) 之后,Build.VERSION_CODES更改 一些字段。

所以,如果你使用:

Field[] fields = Build.VERSION_CODES.class.getFields();
String osName = fields[Build.VERSION.SDK_INT + 1].getName();

会因为超出范围异常导致您的应用立即崩溃。

所有 API 级别的解决方案是:

Field[] fields = Build.VERSION_CODES.class.getFields();
String codeName = "UNKNOWN";
for (Field field : fields) 
    try 
        if (field.getInt(Build.VERSION_CODES.class) == Build.VERSION.SDK_INT) 
            codeName = field.getName();
        
     catch (IllegalAccessException e) 
        e.printStackTrace();
    

或者在 Kotlin 中使用 Java 8 的风格:

val fields = Build.VERSION_CODES::class.java.fields
var codeName = "UNKNOWN"
fields.filter  it.getInt(Build.VERSION_CODES::class) == Build.VERSION.SDK_INT 
      .forEach  codeName = it.name 

【讨论】:

您的解决方案简直是最好的,因为自 API 28 以来字段排列发生了变化。 您可以选择 firstOrNull,而不是在过滤列表上循环。 val fields = Build.VERSION_CODES::class.java.fields val codeName fields.firstOrNull it.getInt(Build.VERSION_CODES::class) == Build.VERSION.SDK_INT ?.name ?: "UNKNOWN" 好答案!此代码由 api 29 运行。:)【参考方案4】:

http://developer.android.com/reference/android/os/Build.VERSION_CODES.html 包含具有您要查找的名称的字段。 因此,您可以使用反射来查找与“版本”值对应的字段。

你为什么要这个名字?

【讨论】:

客户端要求获取自己手机的版本号和版本名称 那么最好的可能是将 Build.VERSION.SDK_INT 发送到您的服务器,然后将该 int 映射到您要提供给客户的名称。 我刚刚给了你一个,另一个答案也是如此:使用 android.os.Build.VERSION.SDK_INT 获取一个数字,然后找到 android.os.Build.VERSION_CODES 中的哪个字段具有该值反射。该字段的名称就是您要查找的内容【参考方案5】:

你会从这些获得信息

android.os.Build.VERSION_CODES 

android.os.Build.VERSION.SDK_INT

更多信息可以通过这个链接获得:

Retrieving Android API version programmatically

希望这会对你有所帮助。

【讨论】:

【参考方案6】:

看看这个:

// Names taken from android.os.build.VERSION_CODES
String[] mapper = new String[] 
    "ANDROID BASE", "ANDROID BASE 1.1", "CUPCAKE", "DONUT",
    "ECLAIR", "ECLAIR_0_1", "ECLAIR_MR1", "FROYO", "GINGERBREAD",
    "GINGERBREAD_MR1", "HONEYCOMB", "HONEYCOMB_MR1", "HONEYCOMB_MR2",
    "ICE_CREAM_SANDWICH", "ICE_CREAM_SANDWICH_MR1", "JELLY_BEAN"
;
int index = Build.VERSION.SDK_INT - 1;
String versionName = index < mapper.length? mapper[index] : "UNKNOWN_VERSION"; // > JELLY_BEAN)

请注意,此解决方案仅适用于版本代码不断递增 1,并且您必须使用每个新的 android 版本更新列表(如果准确很重要)。

【讨论】:

那么,每一个新的 Android 版本你都必须更新这个数组,弱。【参考方案7】:

如 android 文档中所述,手机运行的 SDK 级别(整数)可用于:

android.os.Build.VERSION.SDK_INT;

这个int对应的枚举在android.os.Build.VERSION_CODES类中。

代码示例:

int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.FROYO)
    // Do something for froyo and above versions
 else
    // do something for phones running an SDK before froyo

编辑:此 SDK_INT 自 Donut (android 1.6 / API4) 起可用,因此请确保您的应用程序在使用时与 Cupcake (android 1.5 / API3) 不兼容,否则您的应用程序将崩溃(感谢程序员 Bruce精度)。

【讨论】:

【参考方案8】:

我已经应用了上面的解决方案,但对“O”和“N”作为版本名称不太满意,所以我做了一些更改。希望对其他人也有用

    /**
 * Gets the version name from version code. Note! Needs to be updated
 * when new versions arrive, or will return a single letter. Like Android 8.0 - Oreo
 * yields "O" as a version name.
 * @return version name of device's OS
 */
private static String getOsVersionName() 
    Field[] fields = Build.VERSION_CODES.class.getFields();
    String name =  fields[Build.VERSION.SDK_INT + 1].getName();

    if(name.equals("O")) name = "Oreo";
    if(name.equals("N")) name = "Nougat";
    if(name.equals("M")) name = "Marshmallow";

    if(name.startsWith("O_")) name = "Oreo++";
    if(name.startsWith("N_")) name = "Nougat++";

    return name;

【讨论】:

【参考方案9】:

适合初学者的解决方案。 我使用版本代码,因为它们比代号更好,更不容易混淆。例如。果冻豆、奥利奥、棒棒糖等在单一代号下具有不同的版本代码。 无论如何,您可以将版本代码替换为代号。

 var androidVersion = ""
    androidVersion = when (android.os.Build.VERSION.SDK_INT)
        16 -> "Android 4.1"
        17 -> "Android 4.2"
        18 -> "Android 4.3"
        19 -> "Android 4.4"
        21 -> "Android 5.0"
        22 -> "Android 5.1"
        23 -> "Android 6.0"
        24 -> "Android 7.0"
        25 -> "Android 7.1"
        26 -> "Android 8.0"
        27 -> "Android 8.1"
        28 -> "Android 9"
        29 -> "Android 10"
        else -> "API " + android.os.Build.VERSION.SDK_INT
    

【讨论】:

【参考方案10】:

当我尝试在 API 19 上运行的模拟器时,反射不起作用。

所以我想出了“Nacho Coloma”和“Kevin Grant”的混合答案

String osName="";
Field[] fields = Build.VERSION_CODES.class.getFields();
for (Field field : fields) 
    String fieldName = field.getName();
    int fieldValue = -1;

    try 
        fieldValue = field.getInt(new Object());
     catch (IllegalArgumentException e) 
        e.printStackTrace();
     catch (IllegalAccessException e) 
        e.printStackTrace();
     catch (NullPointerException e) 
        e.printStackTrace();
    

    if (fieldValue == Build.VERSION.SDK_INT) 
        osName=fieldName; break;
    

if(osName.isEmpty()) 
    String[] mapper = new String[]
            "ANDROID BASE", "ANDROID BASE 1.1", "CUPCAKE", "DONUT",
            "ECLAIR", "ECLAIR_0_1", "ECLAIR_MR1", "FROYO",
            "GINGERBREAD", "GINGERBREAD_MR1", "HONEYCOMB", "HONEYCOMB_MR1",
            "HONEYCOMB_MR2", "ICE_CREAM_SANDWICH", "ICE_CREAM_SANDWICH_MR1", "JELLY_BEAN",
            "JELLY_BEAN", "JELLY_BEAN", "KITKAT", "KITKAT",
            "LOLLIPOOP", "LOLLIPOOP_MR1", "MARSHMALLOW", "NOUGAT",
            "NOUGAT", "OREO", "OREO", "ANDROID P";
    int index = Build.VERSION.SDK_INT - 1;
    osName = index < mapper.length ? mapper[index] : "UNKNOWN_VERSION";

【讨论】:

【参考方案11】:

此答案为 Marshmallow on 提供了更好的(完整)名称,同时如果您在新版本发布时不更新您的应用程序(两全其美),也可以保持面向未来。版本名称列表来自here.

String versionName =
        Build.VERSION_CODES.class.getFields()[Build.VERSION.SDK_INT + 1].getName();
String[] versionNames = new String[]
        "ANDROID BASE", "ANDROID BASE 1.1", "CUPCAKE", "DONUT",
        "ECLAIR", "ECLAIR_0_1", "ECLAIR_MR1", "FROYO", "GINGERBREAD",
        "GINGERBREAD_MR1", "HONEYCOMB", "HONEYCOMB_MR1", "HONEYCOMB_MR2",
        "ICE_CREAM_SANDWICH", "ICE_CREAM_SANDWICH_MR1",
        "JELLY_BEAN", "JELLY_BEAN_MR1", "JELLY_BEAN_MR2", "KITKAT", "KITKAT_WATCH",
        "LOLLIPOP", "LOLLIPOP_MR1", "MARSHMALLOW", "NOUGAT", "OREO", "OREO_MR1"
;
int nameIndex = Build.VERSION.SDK_INT - 1;
if (nameIndex < versionNames.length) 
    versionName = versionNames[nameIndex];

显然这是从其他人的答案衍生而来的。根据我的经验,当您尝试编辑现有答案以改进它时,人们不喜欢它,因此我创建了一个新答案。

【讨论】:

【参考方案12】:

Build.VERSION.SDK;返回正确的结果,但从 API 16 开始不推荐使用 SDK:Android 4.1 (Jelly Bean)。所以它会显示为 w

【讨论】:

【参考方案13】:

如果您正在寻找Xamarin.Android,解决方案很简单:

Build.VERSION.SdkInt.ToString();

很简单。

原因是SdkInt映射到Android的SDK_INT

[Register("SDK_INT", ApiSince = 4)]
public static BuildVersionCodes SdkInt

  get
  
    return (BuildVersionCodes) Build.VERSION._members.StaticFields.GetInt32Value("SDK_INT.I");
  

映射到枚举,在 C# 中,当调用枚举 ToString 时,会返回枚举的名称(而不是值):

 public enum BuildVersionCodes
  
    [IntDefinition("Android.OS.Build.VERSION_CODES.Base", JniField = "android/os/Build$VERSION_CODES.BASE")] Base = 1,
    [IntDefinition("Android.OS.Build.VERSION_CODES.Base11", JniField = "android/os/Build$VERSION_CODES.BASE_1_1")] Base11 = 2,
    [IntDefinition("Android.OS.Build.VERSION_CODES.Cupcake", JniField = "android/os/Build$VERSION_CODES.CUPCAKE")] Cupcake = 3,
 ...

【讨论】:

【参考方案14】:

你可以试试下面的功能。

 public String AndroidOSName() 
    String os = Build.VERSION.SDK;
    System.out.println("here is my os" + " " + os);
    if (os.equals("23")) 
        return "Marshmallow";
     else if (os.equals("21")) 
        return "Lollipop";
     else if (os.equals("22")) 
        return "LOLLIPOP_MR1";
     else if (os.equals("20")) 
        return "KitKat";
     else if (os.equals("19")) 
        return "KitKat";
     else if (os.equals("18")) 
        return "Jelly Bean";
     else if (os.equals("17")) 

        return "Jelly Bean";
     else if (os.equals("16")) 
        return "Jelly Bean";
     else if (os.equals("15")) 
        return "Ice Cream Sandwich";
     else if (os.equals("14")) 
        return "Ice Cream Sandwich";
     else if (os.equals("13")) 
        return "Honeycomb";
     else if (os.equals("12")) 
        return "Honeycomb";
     else if (os.equals("11")) 
        return "Honeycomb";
     else if (os.equals("10")) 
        return "Gingerbread";
     else if (os.equals("9")) 
        return "Froyo";
     else if (os.equals("8")) 
        return "Froyo";
     else 
        return "Not Found";
    


【讨论】:

请注意,如果您想宣传自己的网站或博客,您必须在回答中披露您的隶属关系。否则,您的回答可能会被标记为垃圾邮件。请阅读How to not be a spammer。

以上是关于如何以编程方式查找 Android 版本名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中以编程方式查找TextView的文本区域(高度/宽度)

如何以编程方式查找已加载共享库的版本?

如何以编程方式重命名 Android 应用程序?

如何以编程方式从 Android 中删除 SQLite 数据库

如何以编程方式在 Android 设备中获取设备 (AOSP) 内部版本号?

以编程方式查找最新 Qt 版本号的最简单方法是啥?