在 C 中使用 NDK 获取操作系统版本

问题描述 投票:0回答:6

我正在编写一个 C 程序,我想在运行 Linux 的桌面上以及 Android 设备上执行该程序。
我必须制作一些桌面特定的东西和一些 Android 特定的东西。
我的问题是,有没有办法获取 C 语言的操作系统版本,以便我可以处理程序是在桌面上还是在 Android 设备上执行?

android c android-ndk
6个回答
11
投票

在您的本机代码中,您可以使用

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
}

10
投票

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”的字符串。


5
投票

NDK提供直接api来获取应用程序目标sdk版本或api级别

android_get_device_api_level
android_get_application_target_sdk_version

参见ndk官方文档


4
投票

如果使用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;
}

3
投票

使用 AConfiguration_getSdkVersion() API 怎么样?

#include <android/configuration.h>
...
auto apilevel = AConfiguration_getSdkVersion(app->config);
LOGI("Device API Level %d", apilevel);

0
投票
#if defined(__linux__)
// Linux-based OS

#if defined(__ANDROID__)
// Android OS
#else
// other Linux-based OS
#endif

#endif

请参阅this以供参考。需要注意的是,任何 Linux 系统都会设置

__linux__
,而 Android 会设置
__ANDROID__
。对于 Windows,大多数用例都是
_WIN32
。~

您还可以使用

/path/to/your/ndk/compiler -dM -E - < /dev/null
查看您可用的所有标志。

© www.soinside.com 2019 - 2024. All rights reserved.