Как обнаружить мобильный телефон или планшет в Android NDK

Я разрабатываю приложение cocos2d-x для устройств Android. У меня было бы две разные конфигурации экрана, предназначенные для форматов мобильных устройств и планшетов. В main.cpp я хотел бы добавить некоторую логику, которая определяет, является ли устройство планшетным или мобильным. Таким образом, я могу загрузить соответствующий интерфейс при запуске приложения.

Я видел решения для обнаружения планшета или устройства по коду Java, но есть ли способ сделать то же самое на C++ в NDK?


person don    schedule 17.09.2013    source источник
comment
Вы всегда можете использовать JNI для вызова функций Java из C   -  person krsteeve    schedule 17.09.2013
comment
Я думаю, это то, что я ищу. Можете ли вы немного расширить это и привести пример того, как это сделать? Или указать мне в правильном направлении со ссылкой?   -  person don    schedule 17.09.2013


Ответы (1)


Чтобы просто получить разрешение экрана, вы можете использовать ANativeWindow:

ANativeWindow nativeWindow = ANativeWindow_fromSurface(env, surface);
int width =  ANativeWindow_getWidth(renderEngine->nativeWindow);
int height = ANativeWindow_getHeight(renderEngine->nativeWindow);

Однако этого недостаточно, вам также понадобится плотность экрана, которая недоступна через NDK. Вы можете получить его с помощью JNI. То, что было бы несколькими строками в Java, заканчивается:

JNIEnv* jni;
app->activity->vm->AttachCurrentThread(&jni, NULL);

jclass activityClass = jni->FindClass("android/app/NativeActivity");
JNI_ASSERT(jni, activityClass);

jmethodID getWindowManager = jni->GetMethodID (activityClass, "getWindowManager" , "()Landroid/view/WindowManager;"); 
JNI_ASSERT(jni, getWindowManager);

jobject wm = jni->CallObjectMethod(app->activity->clazz, getWindowManager);
JNI_ASSERT(jni, wm);

jclass windowManagerClass = jni->FindClass("android/view/WindowManager");
JNI_ASSERT(jni, windowManagerClass);

jmethodID getDefaultDisplay = jni->GetMethodID(windowManagerClass, "getDefaultDisplay" , "()Landroid/view/Display;");
JNI_ASSERT(jni, getDefaultDisplay);

jobject display = jni->CallObjectMethod(wm, getDefaultDisplay);
JNI_ASSERT(jni, display);

jclass displayClass = jni->FindClass("android/view/Display");
JNI_ASSERT(jni, displayClass);

jclass displayMetricsClass = jni->FindClass("android/util/DisplayMetrics");
JNI_ASSERT(jni, displayMetricsClass);

jmethodID displayMetricsConstructor = jni->GetMethodID(displayMetricsClass, "<init>", "()V");
JNI_ASSERT(jni, displayMetricsConstructor);

jobject displayMetrics = jni->NewObject(displayMetricsClass, displayMetricsConstructor);
JNI_ASSERT(jni, displayMetrics);

jmethodID getMetrics = jni->GetMethodID(displayClass, "getMetrics", "(Landroid/util/DisplayMetrics;)V");
JNI_ASSERT(jni, getMetrics);

jni->CallVoidMethod(display, getMetrics, displayMetrics);
JNI_ASSERT(jni, true);

jfieldID xdpi_id = jni->GetFieldID(displayMetricsClass, "xdpi", "F");
JNI_ASSERT(jni, xdpi_id);

float xdpi = jni->GetFloatField( displayMetrics, xdpi_id);
JNI_ASSERT(jni, true);

Код взят из этого вопроса. JNI_ASSERT — небольшой макрос для проверки ошибок.

Когда у вас есть разрешение дисплея и число точек на дюйм, вы должны легко рассчитать размер экрана. Вам нужно будет решить, каково ваше отсечение для «телефона» и «планшета». (Но вы всегда можете посмотреть, где Android проводит черту!)

person krsteeve    schedule 17.09.2013
comment
Благодарю вас! Это подробный ответ на мой вопрос, а также хороший учебник по JNI. - person don; 18.09.2013