Как да откриете мобилен телефон или таблет в 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 е малък макрос за проверка на грешки.

След като имате разделителната способност на дисплея и dpi, трябва да е лесно да изчислите размера на екрана. Ще трябва да решите каква е вашата граница за "телефон" и "таблет". (Но винаги можете да надникнете къде Android тегли чертата!)

person krsteeve    schedule 17.09.2013
comment
Благодаря ти! Това е подробен отговор на моя въпрос, както и хубав урок за JNI. - person don; 18.09.2013