Getting OS version with NDK in C

If you use the java native interface, you can use the java function to get the sdk version number, which is less dependent on android version.

int api_version( struct android_app *app ) {

    JNIEnv* env;
    app->activity->vm->AttachCurrentThread( &env, NULL );

    // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
   jclass versionClass = env->FindClass("android/os/Build$VERSION" );
   jfieldID sdkIntFieldID = env->GetStaticFieldID(versionClass, "SDK_INT", "I" );

   int sdkInt = env->GetStaticIntField(versionClass, sdkIntFieldID );
   app->activity->vm->DetachCurrentThread();
   return sdkInt;
}

property_get() did not work for me, instead I used __system_property_get().

#include <sys/system_properties.h>

void foo() {
    char osVersion[PROP_VALUE_MAX+1];
    int osVersionLength = __system_property_get("ro.build.version.release", osVersion);
}

ro.build.version.release is a string like "6.0". You can also get ro.build.version.sdk to get the sdk level, which is a string like "23".


In your native code, you could use property_get(), something like this:

#include <cutils/properties.h>

// ...

int myfunction() {
    char sdk_ver_str[PROPERTY_VALUE_MAX] = "0";
    property_get("ro.build.version.sdk", sdk_ver_str, "0");
    sdk_ver = atoi(sdk_ver_str);
    // ...   
}

On desktop, property_get() should return empty string.

Note that in starting from Android 6, <cutils/properties.h> is not available in SDK, use __system_property_get as follows:

#include <sys/system_properties.h>

// ...

int myfunction() {
    char sdk_ver_str[PROPERTY_VALUE_MAX];
    if (__system_property_get("ro.build.version.sdk", sdk_ver_str)) {
        sdk_ver = atoi(sdk_ver_str);
    } else {
        // Not running on Android or SDK version is not available
        // ...
    }
    // ...   
}

You can use adb shell getprop to see all possible Android properties. But, be aware that not all of them are supported by all devices.


UPDATE: If you don't need OS version, but simply want to tell if your C/C++ code is running on Android, very simple way to tell is to check if environment variable ANDROID_PROPERTY_WORKSPACE exists (on Android 7 or older), or if socket /dev/socket/property_service exists (Android 8 or newer), something like this:

include <stdlib.h>
include <unistd.h>
// ...

if (getenv("ANDROID_PROPERTY_WORKSPACE")) {
    // running under Android 7 or older
} else if (access("/dev/socket/property_service", F_OK) == 0) {
    // running under Android 8 or newer
} else {
    // running on desktop
}