android通过C获取屏幕大小

时间:2012-08-26 15:37:56

标签: java android android-ndk

我希望通过c获得屏幕尺寸。我知道jni支持从c调用java。但有谁知道另一种方法?我的意思是从低级模块获取屏幕大小而不调用java。

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity
{

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    Log.v("getWidth", Integer.toString(getWindowManager().getDefaultDisplay().getWidth()));
    Log.v("getHeight", Integer.toString(getWindowManager().getDefaultDisplay().getHeight()));
    }
}

我认为/ dev / graphics与我的问题有关

6 个答案:

答案 0 :(得分:3)

是的,您可以从/ dev / graphics / fb0获得屏幕分辨率,但(至少在我的手机上),读取权限仅限于“图形”组中的root用户和用户。无论如何,你可以做这样的事情(为清楚起见,删除了错误检查):

// ... other standard includes ...
#include <sys/ioctl.h>
#include <linux/fb.h>

//...

struct fb_var_screeninfo fb_var;
int fd = open("/dev/graphics/fb0", O_RDONLY);
ioctl(fd, FBIOGET_VSCREENINFO, &fb_var);
close(fd);
// screen size will be in fb_var.xres and fb_var.yres

我不确定这些是否被视为“公共”NDK接口,因为我不知道Google是否认为“Android在Linux上运行并使用Linux Framebuffer接口”是公共API的一部分,但它确实有效。

如果你想确保它是可移植的,你可能应该有一个调用Java WindowManager API的JNI回退。

答案 1 :(得分:1)

如果你从java传入一个Surface,你不需要缓冲区,但你可以使用ANativeWindow类。

void Java_com_justinbuser_nativecore_NativeMethods_setSurface(JNIEnv * env, jobject this, jobject surface){
        ANativeWindow nativeWindow = ANativeWindow_fromSurface(env, surface);
    int width =  ANativeWindow_getWidth(renderEngine->nativeWindow);
    int height = ANativeWindow_getHeight(renderEngine->nativeWindow);
}

答案 2 :(得分:0)

要获得屏幕分辨率,您必须使用struct ANativeWindow_Buffer

typedef struct ANativeWindow_Buffer {
    // The number of pixels that are show horizontally.
    int32_t width;

    // The number of pixels that are shown vertically.
    int32_t height;

    // The number of *pixels* that a line in the buffer takes in
    // memory.  This may be >= width.
    int32_t stride;

    // The format of the buffer.  One of WINDOW_FORMAT_*
    int32_t format;

    // The actual bits.
    void* bits;

    // Do not touch.
    uint32_t reserved[6];
} ANativeWindow_Buffer;

要使用函数ANativeWindow_lock

/**
 * Lock the window's next drawing surface for writing.
 */
int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);

这是docs

如果您正在寻找此功能的使用,请查看名为native-plasma的android-ndk示例。

答案 3 :(得分:0)

您还可以在处理APP_CMD_INIT_WINDOW“app命令时获取窗口大小”就像在您的原生活动中一样:

static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
struct engine* engine = (struct engine*)app->userData;
switch (cmd) {
case APP_CMD_INIT_WINDOW:
    if (engine->app->window != NULL) {
        int width = ANativeWindow_getWidth(engine->app->window);
        int height = ANativeWindow_getHeight(engine->app->window);
    }

如果您想知道如何设置main.c结构和放大器,请查看native-activity示例NDK项目中的engineengine_handle_cmd回调。

答案 4 :(得分:0)

这对我有用:

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;

答案 5 :(得分:0)

对于像我这样寻求纯C ++方式实现此目标的任何人,阅读/dev/graphics/fb0都不可靠。在许多设备上,它返回错误的结果(在我的设备上,它返回640 X 400)。

例如在本机二进制可执行文件中无法使用ANativeWindowANativeWindow_Buffer的情况下,这是一个问题。

对我有用的东西:

假设您拥有一部已打过电话的手机,则可以处理以下命令的输出以可靠地读取分辨率。

su -c dumpsys display | grep mBaseDisplayInfo