我正在编写一个 C 程序,我想在运行 Linux 的桌面和 Android 设备上执行它。
我必须制作一些特定于桌面的东西和一些特定于 Android 的东西。
我的问题是,有没有办法在 C 中获取操作系统版本,以便我可以处理程序是在桌面还是在 Android 设备上执行的?
5 回答
在您的本机代码中,您可以使用property_get()
,如下所示:
#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);
// ...
}
在桌面上,property_get()
应该返回空字符串。
请注意,从 Android 6 开始,<cutils/properties.h>
SDK 中不可用,使用__system_property_get
如下:
#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
// ...
}
// ...
}
您可以使用adb shell getprop
查看所有可能的 Android 属性。但是,请注意,并非所有设备都支持它们。
更新:如果您不需要操作系统版本,而只是想判断您的 C/C++ 代码是否在 Android 上运行,非常简单的判断方法是检查环境变量是否ANDROID_PROPERTY_WORKSPACE
存在(在 Android 7 或更早版本上),或者是否套接字/dev/socket/property_service
存在(Android 8 或更高版本),如下所示:
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
}
property_get()
对我不起作用,而是我使用了__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
是一个类似“6.0”的字符串。您还可以ro.build.version.sdk
获取 sdk 级别,这是一个类似“23”的字符串。
如果使用java原生接口,可以使用java函数获取sdk版本号,对android版本的依赖较少。
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;
}
使用 AConfiguration_getSdkVersion() API 怎么样?
#include <android/configuration.h>
...
auto apilevel = AConfiguration_getSdkVersion(app->config);
LOGI("Device API Level %d", apilevel);
NDK 提供直接 api 获取应用目标 sdk 版本或 api 级别
android_get_device_api_level
android_get_application_target_sdk_version
见ndk官方文档。