I'm writing a C program which I want to execute on my Desktop running Linux and also on an Android device.
I have to make some Desktop specific things and some Android specific things.
My question is, is there a way to get the OS version in C so I can handle if the program is executed on the Desktop or on the Android device?
-
1if you just want to check if you are using android you could always use c/c++ preprocessor macros to check, `#if defined(__unix__) && __ANDROID__ #define PLATFORM_ANDROID #endif` if you want to check the API version for android this way use do `#if defined(__unix__) && __ANDROID__ #include
#if defined(__ANDROID__) && __ANDROID_API__ == 0x00000001 #defined ANDROID_API_1 #endif #endif` – daniel Oct 24 '15 at 05:48
5 Answers
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
}

- 111,019
- 13
- 122
- 148
-
5I couldn't find `
` in my NDK, but using `__system_property_get` from ` – weiyin Mar 09 '15 at 19:56` worked. -
-
1property_get is from cutils, which is not part of the NDK: http://stackoverflow.com/questions/17744108/cutils-not-included-in-ndk I don't think cutils is meant for app development and the implementation in /system/lib/libcutils.so on your user's device could be incompatible to the
you used at compile time. – Simon Warta Jan 11 '17 at 21:48 -
-
-
1@RitobrotoGanguly: unfortunately, since this [commit](https://android.googlesource.com/platform/bionic/+/f8562c5%5E%21/) `ANDROID_PROPERTY_WORKSPACE` is not present in Android 8 (Oreo) and later. it means you have to use `__system_property_get()` method – mvp Jun 29 '21 at 01:36
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".

- 6,819
- 4
- 47
- 58
-
I think you don't need the +1 in the char array length because __system_property_get is "copying [the] value and a \0 terminator to the provided pointer. The total bytes copied will be no greater than PROP_VALUE_MAX." https://android.googlesource.com/platform/bionic/+/49f0a8f23bba188466c6ee3652858ef4da228c6f/libc/include/sys/system_properties.h – Simon Warta Jan 11 '17 at 21:39
NDK provide direct api to get app target sdk version or api level
android_get_device_api_level
android_get_application_target_sdk_version
See the ndk official document.

- 11,627
- 2
- 58
- 74
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;
}

- 431
- 3
- 12
-
This will give exact same result as `property_get("ro.build.version.sdk")`, but is much more complicated – mvp Jul 27 '15 at 20:11
-
4At least in my development environment (nVidia AndroidWorks, Visual Studio 2013), property_get is not readily available as it is not part of the stock android ndk. I assume I could find the source for property_get and add it to my project. However, after 10 minutes into that project, I realized JNI would do nicely. I post my answer here not to say that people can't or shouldn't use your answer, but to give people more options. – Matthew Grivich Jul 28 '15 at 20:00
-
Thanks for sharing. Remember to also call `env->DeleteLocalRef(versionClass)` – tmm1 Apr 26 '18 at 18:42
How about using AConfiguration_getSdkVersion() API?
#include <android/configuration.h>
...
auto apilevel = AConfiguration_getSdkVersion(app->config);
LOGI("Device API Level %d", apilevel);

- 56
- 3
-
3
-
@SimonWarta I think you need to build native apps to access this `android_app`. – Mygod Jan 24 '17 at 10:09
-
https://developer.android.com/ndk/reference/group/configuration#aconfiguration_getsdkversion – Arto Bendiken Jan 14 '20 at 14:42