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?
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
}
<cutils/properties.h>
in my NDK, but using __system_property_get
from <sys/system_properties.h>
worked. –
Adar ANDROID_PROPERTY_WORKSPACE
is not present in Android 8 (Oreo) and later. it means you have to use __system_property_get()
method –
Characteristically 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
}
<cutils/properties.h>
in my NDK, but using __system_property_get
from <sys/system_properties.h>
worked. –
Adar ANDROID_PROPERTY_WORKSPACE
is not present in Android 8 (Oreo) and later. it means you have to use __system_property_get()
method –
Characteristically 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.
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("ro.build.version.sdk")
, but is much more complicated –
Characteristically env->DeleteLocalRef(versionClass)
–
Mullock How about using AConfiguration_getSdkVersion() API?
#include <android/configuration.h>
...
auto apilevel = AConfiguration_getSdkVersion(app->config);
LOGI("Device API Level %d", apilevel);
app
variable from? –
Nikolaus android_app
. –
Nakada #if defined(__linux__)
// Linux-based OS
#if defined(__ANDROID__)
// Android OS
#else
// other Linux-based OS
#endif
#endif
See this for reference. The caveat is that any linux system sets __linux__
, and Android sets that and __ANDROID__
. For windows it's _WIN32
for most use cases.~
You can also use /path/to/your/ndk/compiler -dM -E - < /dev/null
to see all the flags available to you.
© 2022 - 2024 — McMap. All rights reserved.
#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 <android/api-level.h> #if defined(__ANDROID__) && __ANDROID_API__ == 0x00000001 #defined ANDROID_API_1 #endif #endif
– Alembic