8

I have a purely native Android NDK app, and need to retrieve values such as: android.os.Build.MODEL

Unfortunately I cannot find good examples of how to go about this?

3 Answers 3

22

These values are easy to obtain in native code via the interface defined in <sys/system_properties.h>, which has been around since the first NDK release. You just need to know the string identifier used on the Java side. Fortunately, with an open-source OS, we can find these easily. Here is a working example of retrieving the model name.

#include <sys/system_properties.h>

//
// Public codes are defined in http://developer.android.com/reference/java/lang/System.html#getProperty(java.lang.String).
// Codes below are defined in https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/Build.java.
// Items with * are intended for display to the end user.
//

#define ANDROID_OS_BUILD_VERSION_RELEASE     "ro.build.version.release"          // * The user-visible version string. E.g., "1.0" or "3.4b5".
#define ANDROID_OS_BUILD_VERSION_INCREMENTAL "ro.build.version.incremental"      // The internal value used by the underlying source control to represent this build.
#define ANDROID_OS_BUILD_VERSION_CODENAME    "ro.build.version.codename"         // The current development codename, or the string "REL" if this is a release build.
#define ANDROID_OS_BUILD_VERSION_SDK         "ro.build.version.sdk"              // The user-visible SDK version of the framework.

#define ANDROID_OS_BUILD_MODEL               "ro.product.model"                  // * The end-user-visible name for the end product..
#define ANDROID_OS_BUILD_MANUFACTURER        "ro.product.manufacturer"           // The manufacturer of the product/hardware.
#define ANDROID_OS_BUILD_BOARD               "ro.product.board"                  // The name of the underlying board, like "goldfish".
#define ANDROID_OS_BUILD_BRAND               "ro.product.brand"                  // The brand (e.g., carrier) the software is customized for, if any.
#define ANDROID_OS_BUILD_DEVICE              "ro.product.device"                 // The name of the industrial design.
#define ANDROID_OS_BUILD_PRODUCT             "ro.product.name"                   // The name of the overall product.
#define ANDROID_OS_BUILD_HARDWARE            "ro.hardware"                       // The name of the hardware (from the kernel command line or /proc).
#define ANDROID_OS_BUILD_CPU_ABI             "ro.product.cpu.abi"                // The name of the instruction set (CPU type + ABI convention) of native code.
#define ANDROID_OS_BUILD_CPU_ABI2            "ro.product.cpu.abi2"               // The name of the second instruction set (CPU type + ABI convention) of native code.

#define ANDROID_OS_BUILD_DISPLAY             "ro.build.display.id"               // * A build ID string meant for displaying to the user.
#define ANDROID_OS_BUILD_HOST                "ro.build.host"
#define ANDROID_OS_BUILD_USER                "ro.build.user"
#define ANDROID_OS_BUILD_ID                  "ro.build.id"                       // Either a changelist number, or a label like "M4-rc20".
#define ANDROID_OS_BUILD_TYPE                "ro.build.type"                     // The type of build, like "user" or "eng".
#define ANDROID_OS_BUILD_TAGS                "ro.build.tags"                     // Comma-separated tags describing the build, like "unsigned,debug".

#define ANDROID_OS_BUILD_FINGERPRINT         "ro.build.fingerprint"              // A string that uniquely identifies this build. 'BRAND/PRODUCT/DEVICE:RELEASE/ID/VERSION.INCREMENTAL:TYPE/TAGS'.


char model_id[PROP_VALUE_MAX]; // PROP_VALUE_MAX from <sys/system_properties.h>.
int len;
len = __system_property_get(ANDROID_OS_BUILD_MODEL, model_id); // On return, len will equal (int)strlen(model_id).
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. That's exactly the information which was missing and which is not obvious or visible anywhere in the public android ndk documentation. Here is a link to the sources if you're interested in the method signatures and contracts: android.googlesource.com/platform/bionic/+/android-1.6_r1/libc/…
1

The NDK isn't meant to replace the Java based API but to supplement it. To get Build you'll have to find its private implementation in C/C++ or provide the information from Java via JNI.

Pseudo Code:

android_main(struct *android_app){
    JNIEnv *env = android_app->activity->env;
    jclass build_class = FindClass(env, "android.os.Build");
    jfieldID brand_id = GetStaticFieldID(env, build_class, "BRAND", "Ljava/lang/String;");
    jstring brand_obj = (jstring)GetStaticObjectField(env, brand_id);
}

9 Comments

thank-you. I am unable to find its C/C++ implementation, however I can try and retrieve this info from Java via JNI. I see examples for this where 'JNIEnv*` is a function paramater, later used to call methods such as GetMethodID and CallVoidMethod, however I'm not sure where or how in my native method I could call this from? Where would I get this JNIEnv* parameter from?
(ie my purely native app has 'android_main` as my entry point into my purely native app, hence i'm not sure how to call a function that takes JNIEnv* as a parameter)
Ahh, this is going to be a problem, what kind of information are you looking for from Build?
Basically I need the device information, such as Build.MODEL, Build.BRAND, Build.DEVICE and Build.VERSION.RELEASE
Are you using "android_native_app_glue.h" or just "native_activity.h" to make your app? From there I can give you some pseudo code.
|
-1

I don't think you can do this unfortunately. You could always start in VM and jump down via JNI to native after retrieving the values you want to access.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.