7

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

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 与我的问题有关

4

6 回答 6

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 后备。

于 2012-08-26T22:18:49.370 回答
0

您不需要缓冲区,但如果您从 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);
}
于 2012-11-24T14:39:20.797 回答
0

您还可以在APP_CMD_INIT_WINDOW本机活动中像这样处理“应用程序命令”时获取窗口大小:

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,请查看示例 NDK 项目。native-activityengineengine_handle_cmd

于 2014-06-05T20:43:41.000 回答
0

对于像我这样正在寻找纯 C++ 方法的人来说,阅读/dev/graphics/fb0并不能可靠地工作。在许多设备上,它返回一个不正确的结果(在我的设备上它返回 640 X 400)。

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

什么对我有用:

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

su -c dumpsys display | grep mBaseDisplayInfo
于 2019-10-25T18:08:12.250 回答
-1

要获得屏幕分辨率,您必须使用 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);

这是文档

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

于 2012-08-27T21:19:18.040 回答
-3

这对我有用:

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
于 2018-06-19T18:45:46.113 回答