32

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

String version=Build.VERSION.RELEASE;

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

4

14 回答 14

63

如前所述,反思似乎是这个问题的关键。不需要 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

享受!

于 2012-11-06T20:17:13.563 回答
19

优化代码,这将起作用:

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);
于 2016-07-28T13:45:02.197 回答
16

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();
    }
}

或者在具有 Java 8 风格的 Kotlin 中:

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 }
于 2019-05-02T05:36:31.187 回答
5

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

你为什么要这个名字?

于 2012-05-11T08:19:59.147 回答
4

您将从这些信息中获取信息

android.os.Build.VERSION_CODES 

android.os.Build.VERSION.SDK_INT

可以从此链接获得更多信息:

以编程方式检索 Android API 版本

希望这会帮助你。

于 2012-05-11T08:19:07.190 回答
3

看一下这个:

// 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 版本更新列表(如果准确很重要)。

于 2013-05-03T14:11:44.920 回答
1

如 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 的精确度) .

于 2015-05-21T09:45:15.707 回答
1

我已经应用了上面的解决方案,但对“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;
}
于 2018-09-20T11:22:18.850 回答
1

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

 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
    }
于 2020-07-07T17:16:27.007 回答
0

当我尝试在 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";
}
于 2018-02-27T16:25:30.183 回答
0

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

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];
}

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

于 2018-07-06T16:21:45.790 回答
0

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

于 2019-03-28T06:27:30.800 回答
0

如果您正在寻找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,
 ...
于 2020-01-11T12:36:27.443 回答
-4

您可以尝试以下功能。

 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";
    }

}
于 2018-01-18T08:50:06.633 回答