Venkat
Venkat

Reputation: 3457

How to find the Android version name programmatically?

I write code for finding the Android version like this

String version=Build.VERSION.RELEASE;

by using this code I am get the version number but I want version name. how to get the version name?

Upvotes: 36

Views: 61905

Answers (14)

Trần Leo
Trần Leo

Reputation: 455

After API 28 (Android Pie), Build.VERSION_CODES were changed some fields.

So, if you using:

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

will cause your app CRASH immediately because of Out Of Range Exception.

The solution for all API level is:

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

Or in Kotlin with Java 8's style:

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 }

Or shorter version (thanks @datiKaa)

val fields = Build.VERSION_CODES::class.java.fields
val codeName fields.firstOrNull { it.getInt(Build.VERSION_CODES::class) == Build.VERSION.SDK_INT }?.name ?: "UNKNOWN"

Upvotes: 22

Zakir Shikhli
Zakir Shikhli

Reputation: 424

A beginner level friendly solution. I use version codes, because they are better and less confusing than code-names. For ex. jelly bean, oreo, lollipop etc. have different version codes under single codename. Anyway, You can replace version codes with codenames.

 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
    }

Upvotes: 1

Bruno Garcia
Bruno Garcia

Reputation: 6408

If you're looking for Xamarin.Android the solution is simply:

Build.VERSION.SdkInt.ToString();

Pretty simple.

The reason is SdkInt is mapped to Android's SDK_INT:

[Register("SDK_INT", ApiSince = 4)]
public static BuildVersionCodes SdkInt
{
  get
  {
    return (BuildVersionCodes) Build.VERSION._members.StaticFields.GetInt32Value("SDK_INT.I");
  }
}

Which maps to an enum, and in C# when an enum ToString is called, the name (as opposed to the value) of the enum is returned instead:

 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,
 ...

Upvotes: 0

shiv om Bhardwaj
shiv om Bhardwaj

Reputation: 31

Build.VERSION.SDK; is return correct result but SDK is deprecated as of API 16: Android 4.1 (Jelly Bean).so it will show like as w

Upvotes: 0

RexSplode
RexSplode

Reputation: 1505

I've applied the solution above, but wasn't quite happy with "O" and "N" as version names, so I made some changes. Hope it will be useful for others too

    /**
 * 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;
}

Upvotes: 1

Jon McClung
Jon McClung

Reputation: 1704

This answer provides better (full) names for Marshmallow on, while also remaining future-proof if you don't update your app when a new version comes out (the best of both worlds.) The list of version names comes from 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];
}

Obviously this is derivative of the answers of others. In my experience, people don't like it when you try to edit an existing answer to improve it, hence my creating a new one.

Upvotes: 0

Reflection is not working when I have tried in emulator running on API 19.

So I come up with an hybrid answer of "Nacho Coloma" and "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";
}

Upvotes: 0

Quantum4U
Quantum4U

Reputation: 35

You can try following function.

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

}

Upvotes: -4

Shyam Kumar
Shyam Kumar

Reputation: 919

Optimized code, this will work:

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

Upvotes: 19

hitesh141
hitesh141

Reputation: 943

As described in the android documentation, the SDK level (integer) the phone is running is available in:

android.os.Build.VERSION.SDK_INT;

The enum corresponding to this int is in the android.os.Build.VERSION_CODES class.

Code example:

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
}

Edit: This SDK_INT is available since Donut (android 1.6 / API4) so make sure your application is not retro-compatible with Cupcake (android 1.5 / API3) when you use it or your application will crash (thanks to Programmer Bruce for the precision).

Upvotes: 1

Nacho Coloma
Nacho Coloma

Reputation: 7338

Check this out:

// 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)

Be aware that this solution will only work as far as the version codes keep being incremented by one, and you will have to update the list with each new android version (if being accurate is important).

Upvotes: 3

Kevin Grant
Kevin Grant

Reputation: 2351

As suggested earlier, reflection seems to be the key to this question. The StringBuilder and extra formatting is not required, it was added only to illustrate usage.

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

On my 4.1 emulator, I get this output:

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

Enjoy!

Upvotes: 63

Philippe Girolami
Philippe Girolami

Reputation: 1876

http://developer.android.com/reference/android/os/Build.VERSION_CODES.html contains fields that have the name you're looking for. So you could use reflexion to find which field corresponds to the "version" value.

Why do you want the name ?

Upvotes: 5

UVM
UVM

Reputation: 9914

You will get the information from these

android.os.Build.VERSION_CODES 

android.os.Build.VERSION.SDK_INT

More information can be had from this link:

Retrieving Android API version programmatically

Hope this will help you.

Upvotes: 4

Related Questions